• No results found

4.5 Implementation of LaSt GT

4.5.5 How the TCC primitives are extended

We have to extend the primitives in Section2.3.1in order to support LaStGT’s virtual mem- ory management. Since the management is performed by suitably handling interruptions of the

secured service application while it is executing, support for LaStGT can be fully implemented within the execute primitive. In addition, small changes are required to the verify primitive. This clarifies how we provide such a support “below” the primitives (Section2.3.1).

An enhanced execute primitive. Algorithm 23and Algorithm 24 (dark background, bottom- side) highlight how the execute primitive changes. We point out that, in XMHF-TrustVisor, in- memory data management is performed at the level of the hypervisor (and thus not shown) which provides memory and data to the trusted execution. In SGX instead, data management is deputed to the untrusted application-level (AEX code block, lines14-24).

The AEX block is executed when the enclave is interrupted, for instance due to a page fault. In the case of a map miss (i.e., the needed data is not in memory), the SMM is called to load the data in memory (line16); we display such direct call for clarity, however, the SMM can be implemented outside the primitive and then used as we describe in a note below. Once the data is in memory, the AEX code block leverages the OS driver to run privileged instructions to supply memory to the enclave (line18, though the instructions are not detailed for brevity). For security reasons however, the enclave code must accept any supplied memory before using it, and also has to retrieve and validate data from untrusted memory. These operations are performed by letting the enclave code start at a different entry point (line20). If validation is successful, then the original execution flow can be resumed (line21). If the interruption is unexpected, or the untrusted application-level is unable to resolve the page fault, then the execution is simply terminated (line23), so no results or attestations are produced.

The reader can easily check that the implementation is compatible with the primitives intro- duced in Section4.5.1. For example, by considering the SGX implementation, it is easy to spot where the createEnvironment and runAt primitives are implemented, while mapIn, MapOut, loadState and storeState are implemented inside the SMM.

A note on customizable data structures and algorithms. In Algorithm24(line16), we abused notation for brevity by inserting a call to the SMM to resolve a map miss. As the SMM appears to be inside the primitive, this may raise questions about how the user can customize data structures and algorithms in LaStGT.

We provide a straightforward alternative to customize them. The alternative is to extend the parameters of the execute primitive with a callback function for the SMM. If a callback is provided, the execute primitive uses it (at line16) to call the user function. Otherwise the primitive can use a default implementation.

Input: description of code’s text, data, stack

sections, and input data (including nonce)

Output: output data

1: trigger registration hyper-call to isolate code and I/O memory pages

2: encode I/O parameters for I/O marshaling 3: call isolated code

4: decode output data

5: trigger unregistration hyper-call to return isolated memory pages

6: return output data

1: trigger registration hyper-call to isolate code and memory pages for input and output 2: trigger hyper-call to register input data root

maps and SMM entry point 3: call isolated code

4: output data ← output data map

5: trigger unregistration hyper-call to return isolated memory pages

6: return output data

Algorithm 23: execute primitive on XMHF- TrustVisor. Above, the original implemen- tation from Algorithm1. Below, dark areas highlight the differences of the implemen- tation that support LaStGT.

Input: description of code’s text, data, stack

sections, and input data (including nonce)

Output: output data

1: init SGX Enclave Control Structure (SECS) 2: initialize TCS(s)

3: trigger system call toECREATEenclave 4: for each code page to be isolated do 5: trigger system call toEADDenclave page 6: trigger system call toEEXTENDthe page

content to the enclave 7: end for

8: trigger system call toEENITthe enclave 9: runEENTERon the enclave’s TCS

10: forward local attestation to Quoting Enclave for remote attestation

11: trigger system call toEREMOVEthe enclave 12: return output data

1: init SGX Enclave Control Structure (SECS) 2: initialize TCS(s)

3: trigger system call toECREATEenclave 4: for each code page to be isolated do 5: trigger system call toEADDenclave page 6: trigger system call toEEXTENDthe page

content to the enclave 7: end for

8: trigger system call toEENITthe enclave 9: runEENTERon enclave’s state handler’s TCS

to register input data root maps 10: runEENTERon the enclave’s TCS

11: forward local attestation to Quoting Enclave for remote attestation

12: trigger system call toEREMOVEthe enclave 13: return output data

14: On AEX:

15: if map miss then

16: call SMM 17: end if

18: do memory management (reclaim/pro- vide pages)

19: if map hit then

20: runEENTERon state handler’s TCS (and wait for termination)

21: runERESUMEon enclave’s TCS 22: else

23: segmentation fault ⇒ shutdown 24: end if

Algorithm 24: execute primitive on Intel SGX. Above, the original implementation from Algorithm2. Below, dark areas high- light the differences of the implementation that support LaStGT.

Input: nonce, output hash, input hash, code

identity, hypervisor identity, hypervisor public attestation key, TPM attestation, certified TPM public attestation key, hypervisor attestation

Output: true or false

1: if TPM attestation can be validated using certified TPM public attestation key ∧ attested hypervisor identity is expected ∧ attested hypervisor public attestation key is expected ∧ hypervisor attestation can be validated using hypervisor public attestation key ∧ nonce, code identity, hash(input hash||output hash) are expected

then

2: return true 3: else

4: return false 5: end if

Input: nonce, output hash,

request hash and state (root) hash , code identity, hypervisor identity, hypervisor public attestation key, TPM attestation, certified TPM public attestation key, hypervisor attestation

Output: true or false

1: if TPM attestation can be validated using certified TPM public attestation key ∧ attested hypervisor identity is expected ∧ attested hypervisor public attestation key is expected ∧ hypervisor attestation can be validated using hypervisor

public attestation key ∧ nonce, code identity, hash(request hash||state hash||output hash) are expected then

2: return true 3: else

4: return false 5: end if

Algorithm 25: verify primitive for XMHF- TrustVisor. Above, the original implemen- tation from Algorithm5. Below, dark areas highlight the differences of the implemen- tation that support LaStGT.

Input: nonce, output hash, input hash, code

identity, remote attestation (from Quoting Enclave), public report key

Output: true or false

1: if code identity (i.e.,MRENCLAVEregister value inside the remote attestation) not expected ∨ hash(nonce||input hash||output hash) (i.e.,REPORTDATAstructure inside the remote attestation) not expected then 2: return false

3: end if

4: contact IAS [220] through APIs [221] 5: validate attestation report from IAS with

public report key

6: if IAS returns attestation not valid then 7: return false

8: end if 9: return true

Input: nonce, output hash,

request hash and state (root) hash , code identity, remote attestation (from Quoting Enclave), public report key

Output: true or false

1: if code identity (i.e.,MRENCLAVEregister value inside the remote attestation) not expected ∨

hash(nonce||request hash||state hash|| output hash) (i.e.,REPORTDATAstructure inside the remote attestation) not expected

then

2: return false 3: end if

4: contact IAS [220] through APIs [221] 5: validate attestation report from IAS with

public report key

6: if IAS returns attestation not valid then 7: return false

8: end if 9: return true

Algorithm 26: verify primitive for Intel SGX. Above, the original implementation from Algorithm6. Below, dark areas high- light the differences of the implementation that support LaStGT.

Note. Inside an enclave the verification is slightly different as follows: the signed Attestation Verifica- tion Report (returned by the IAS) is forwarded to the enclave, who performs the same checks as above and additionally verifies the signature, so it requires one additional input i.e., the public Report Key. For addi- tional details, see the implementation of the get cert

VC3 Haven LaSt GT∗

hypervisor library SQLite SLoC × 103 9.2 [39] 23.1+ O(103)# [38] 15.1 [94] 7.7 92.6 +1.9‡ | {z } 24.7 | {z } 100.3

* based on XMHF-TrustVisor ‡ LaStGTcore code and headers #

LibOS contains millions of lines of code

Table 4.2: TCB size breakdown (in thousand source lines of code) and comparison. SQLite is included as an example real-world application ported to LaStGT.

bottom-side) highlight how the verify primitive changes. As it can be noticed, the main differ- ence is providing the client with the state root hash, that allows to verify that the remote service processed the intended large data set. Therefore, the complexity of the primitive—and so the verification effort for the client—does not change with respect to the previous version (top-side of the algorithms).