Skip to content
This repository has been archived by the owner on May 9, 2022. It is now read-only.

Latest commit

 

History

History
117 lines (80 loc) · 5.57 KB

HACKING.md

File metadata and controls

117 lines (80 loc) · 5.57 KB

Working on this project

Pinning SGX dependencies

We currently depend on a post-v1.1.3 revision of sgx_types for this PR, which was merged in b9d1bda:

Because of how Cargo resolves Git repository references, all dependency references to the incubator-teaclave-sgx-sdk repository should be qualified with this same revision, to prevent Cargo from resolving conflicting versions of the SGX SDK packages:

sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" }

Note that most of the SGX packages still refer to the old teaclave-sgx-sdk repo, so these references must be patched like this:

[patch."https://github.com/apache/teaclave-sgx-sdk.git"]
sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", rev = "b9d1bda" }

Cargo patch limitation workaround

Ideally, we want to explicitly specify the tag or revision of the SGX-forked packages we use, like this:

serde = { git = "https://github.com/mesalock-linux/serde-sgx", tag = "sgx_1.1.3" }

However, this fails for packages that are also listed as dependencies of other SGX-forked packages without the explicit tag: Cargo will resolve these as different crates, which causes problems (such as different crates referring to different versions of serde's traits).

We cannot use [patch] to override these dependencies to use the same specifiers, because of this Cargo limitation:

To work around this problem, our specifiers must exactly match the specifiers used by our dependencies' dependency declarations. (That is, the rev / tag / branch values (or lack of them) must match.)

Currently, at least these transitively-used dependencies must be specified exactly:

once_cell = { git = "https://github.com/mesalock-linux/once_cell-sgx" }
serde = { git = "https://github.com/mesalock-linux/serde-sgx" }
serde-big-array = { git = "https://github.com/mesalock-linux/serde-big-array-sgx" }
serde_derive = { git = "https://github.com/mesalock-linux/serde-sgx" }
serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" }

Aligned memory allocation for secret values

In enclave code, all memory allocations for sensitive secret values (such as cryptographic keys) must be padded and aligned to protect against certain cache timing side-channel attacks, as detailed in the Intel's INTEL-SA-00219 Developer Guidance.

The Rust SGX SDK provides primitives (AlignBox and sgx_align_*) to help implement this guidance, but other enclave secrets must also be allocated similarly.

In particular, care must be taken to allocate aligned memory before initialising secrets in it, rather than initialising secrets in unaligned memory and then moving them to aligned memory.

In this codebase, also see the AlignedKey type in the rtc_tenclave::dh::types module.

Background:

Rust SGX SDK:

ECALL enclave name prefixing and --use-prefix

See "Avoiding Name Collisions" in the Intel SGX Developer Reference.

When linking more than one enclave library into an application, all ECALL and OCALL function names must be unique to avoid linking collisions. The sgx_edger8r tool automatically prevents OCALL name collisions by prepending the enclave name to all bridge functions, but does not do the same for ECALL names by default.

This means that when more than one enclave library uses a shared library with its own ECALLs, like we do with rtc_tenclave, the ECALL function names of the different instances of shared library will collide, by default.

To avoid this, we pass the --use-prefix option to sgx_edger8r to prepend the enclave name to all untrusted proxy function names, so that the shared library ECALLs will have a unique interface for each enclave library they're exposed from.

This means that the shared library's trusted code and EDL will refer to a function like session_request, but the untrusted code will refer to different per-enclave instances of it, like rtc_auth_session_request, rtc_data_session_request, and so on.

However, this means that all other references to the enclave's non-library ECALLs will also become prefixed in the same way: the function names in the EDL will use the unprefixed form, while the references in the untrusted code must use the prefixed from.