Question Lists:

What it means

Task, Procedure and Critical Procedure. A task $T$ is a set of procedures where a procedure takes inputs and / or returns an output. We define $p(S) \in T$ as a critical procedure, where $p$ takes input a secret set $S$ and returns a value $r_p$.

Proof of Being Forgotten (PoBF) refers to a kind of regulation enforcing that code dealing with secrets is verified so that:

  1. No leftovers: Secrets are completely consumed, and
  2. No leakage: No secret is leaked to any unauthorized party

Formally, given a critical procedure $p(S)$, Being Forgotten $\mathsf{BF}(p(S))$ is a conjunction of not Leaked and not residual; that is:

$$ \mathsf{BF}(p(S)) \overset{\Delta}{=} \neg \mathsf{Leaked}(p, S^) \wedge \neg \mathsf{Residual}(p, S^). $$

An interesting fact is, the term leakage also considers the values tainted by the initial secret. In the core functionalities of POBF, we just designate a simple private computation function called private_vec_compute as the workflow.

Constraints of PoBF

  1. Restriction for Leakage ⇒ the aforementioned zone should be restricted while the program is running and should be read exclusive. Formally,

    $$ \mathsf{Restricted}(p(S), \mathcal{Z}) \overset{\Delta}{=}\mathsf{WriteBounded} \wedge \mathsf{ReadExclusive} $$

    where

    $$ \mathsf{WriteBounded}(p(S), \mathcal{Z}) \Leftrightarrow \forall \mathsf{op}(\mathrm{arg}*) \in p, \mathsf{op} = \mathsf{Write} \Rightarrow \mathrm{arg} \in \cal Z. $$

    $$ \mathsf{ReadExclusive}(p(S), \mathcal{Z}) \Leftrightarrow \forall\mathsf{op}(\mathrm{arg}*) \in \mathcal{T} \setminus \{p\}, \mathsf{op} = \mathsf{Read} \Rightarrow \mathrm{arg} \notin \mathcal{Z} $$

    The thing is, for a single-threaded task, read exclusion can be without doubt guaranteed, but this does not necessarily hold true for multi-threaded tasks. Using Coq, the following theorem holds true.

    Theorem. Restricted means no leakage.

  2. CleanMoved for residual. Residue should be safely cleaned after the execution of critical procedures. Also the return value $r_p$ must be passed to the next procedure intactly and cannot be accessed by any other entities. Formally,

    $$ \mathsf{CleanMoved}(p(S), \mathcal{Z}) \overset{\Delta}{=} \mathsf{Zeroized(p(S), \mathcal{Z})} \wedge \mathsf{SafeTransferred}(p(S), p_{next}(S_{next})). $$

    where

    $$ \mathsf{Zerorized}(p(S), \mathcal{Z}) \Leftrightarrow \forall l \in \mathcal{Z} \setminus loc(r_p), read(l) = 0. $$

    $$ \mathsf{SafeTransferred}(p(S), p_{next}(S_{next})) \Leftrightarrow r_p \in S_{next} \wedge (\forall \mathsf{op} \in \mathcal{T}, \mathrm{arg} \in loc(r_p) \wedge \mathsf{op} = read(\mathrm{arg}*) \Rightarrow \mathsf{op} \in p_{next}(S_{next})) $$

    Using Coq, the following theorem holds true.

    Theorem. CleanMoved means no residue.

    Theorem. For a single-thread program, if $p_{next}$ is executed right after $p(S)$ and the zone remains unchanged, then the transfer is safe. ⇒ creusot: Only need to prove zeroized.

    Exception: the last critical procedure does not have any next procedure, so we assume it always satisfies safe transfer, but to the extent that it is an encryption algorithm that completely consumes the input secret. We call it EndWithEncryption.

  3. PoBF for the Task.

    $$ \mathsf{BF}(\mathcal{T}) \Leftrightarrow \bigwedge_{p_i \in \mathcal{T}}\mathsf{Restricted}(p_i(S), \mathcal{Z}) \wedge \bigwedge_{p_i \in \mathcal{T}}\mathsf{CleanMoved}(p_i(S), \mathcal{Z}) \wedge \mathsf{EndWithEncryption} $$

    By 1, 2, 3, to prove the single-threaded task is BF, we only need to prove that each critical procedure is write bounded, safe transferred and zeorized, and the last critical procedure is an encryption algorithm. These can be done using Coq (see Software Foundations).

Implementation Details

Rust (Ownership, Memory and Thread Safety)+ Teaclave (Code Integrity and Confidentiality) + MIRAI (Abstract Interpretation for verification and static analysis).

  1. Leakage prevention is achieved by exclusive resource usage (holds for single-threaded programs), Rust ownership rules (critical procedures are only allowed to modify owned variables either transferred from the outside world or initialized by their own), safe Rust (prevents raw pointer dereferencing) and taint analysis in bridge functions (OCALLS and exception handlers, done by MIRAI tag analysis).