Apache Teaclave SGX SDK

repository·main·Indexed 22 days ago

https://github.com/apache/teaclave-sgx-sdk

A Rust SDK for developing secure Intel SGX applications. It provides a high-performance development environment that integrates with the Rust ecosystem, featuring support for Tokio and Tonic within enclaves, a refactored lightweight architecture, and a robust testing framework with the sgx_tstd standard library. The SDK supports multiple build modes (cargo, no_std, and xargo) and includes sample applications for cryptography, RPC, and data sealing.

Tokens
20.4K
Snippets
31
Records
133
Agent score
76%

What's inside Apache Teaclave SGX SDK

  1. Overview of Apache Teaclave™ SGX SDK

    main

    Apache Teaclave™ SGX SDK is a Rust-based development environment for building Intel SGX (Software Guard Extensions) applications. It allows developers to create secure, privacy-preserving enclaves using Rust's safety and performance features.

    Key features include:

    • Support for modern Rust ecosystems like Tokio and Tonic directly within enclaves.
    • A lightweight architecture that refactors Intel's SGX SDK using Rust.
    • A robust testing framework and a well-tested sgx_tstd standard library.
    • High compatibility with most Rust crates without requiring modifications.
  2. Use libbacktrace for symbolic backtraces

    main

    libbacktrace is a C library used to produce symbolic backtraces in C/C++ programs. It is commonly used to print detailed backtraces during error handling or to collect profiling information.

    To use the library:

    1. Include the backtrace.h header in your project.
    2. Link the libbacktrace library into your program or library.

    Supported executable formats (as of January 2018) include ELF, PE/COFF, and XCOFF with DWARF debugging information. The library relies on the C++ unwind API provided by GCC.

  3. Understand hashbrown performance and security trade-offs

    main

    Performance

    hashbrown is significantly faster than the previous Rust standard library implementation (pre-1.36). It uses SIMD lookups to scan multiple hash entries in parallel and has lower memory overhead (approximately 1 byte per entry instead of 8).

    Security (HashDoS)

    By default, hashbrown uses AHash, which is much faster than the standard library's SipHash. However, AHash does not provide the same level of HashDoS resistance as SipHash. If your application requires protection against HashDoS attacks, you should consider using a different hasher.

  4. Understand Sealing, Attestation, and Secret Management Assumptions

    main

    When using the SDK for security-critical operations, adhere to these fundamental assumptions and constraints:

    • Sealing (sgx_tseal): Provides confidentiality and integrity, but does not provide freshness or availability. A sealed blob can be deleted, withheld, or rolled back to an earlier version by the untrusted host. To prevent rollback attacks, you must implement an external mechanism like a monotonic counter or a freshness service.
    • Sealing Scope: Choosing between MRENCLAVE and MRSIGNER is a security decision. MRENCLAVE binds data to the exact enclave, while MRSIGNER allows any enclave from the same signer to unseal it, which increases the exposure surface.
    • Attestation: Attestation (local via sgx_tdh or remote via sgx_key_exchange/sgx_dcap) is not automatic. Reports and quotes are untrusted input until they are verified by trusted code (e.g., sgx_dcap_tvl).
    • OCALL Security: Never treat OCALL results (time, file existence, configuration, etc.) as a security oracle. Any value crossing from the host to the enclave can be forged by an adversary.
    • Secrets: Do not pass secrets to the host in cleartext unless your threat model explicitly allows it.
    • Randomness: Entropy inside the enclave must be sourced from SGX (RDRAND or sgx_read_rand). Never use randomness provided via a host OCALL.
  5. Understand the SGX Trust Model and Domains

    main

    The SGX system is partitioned into two domains enforced by hardware. Understanding this asymmetry is critical for security: the enclave can read host memory, but the host cannot read enclave memory. Therefore, the primary security hazard is untrusted input coming from the host into the enclave.

    DomainRunsTrust PostureSDK Crates
    Untrusted Host (REE)Host app, OS, hypervisor, BIOSUntrustedsgx_u* (e.g., sgx_urts, sgx_oc)
    Enclave (TEE)Your trusted code + SDK runtimeTrustedsgx_t* (e.g., sgx_trts, sgx_tstd)

    Note: The SDK provides a trusted std and ergonomic Rust bindings, but it does not protect against microarchitectural side-channel attacks (e.g., cache timing, L1TF) or physical attacks beyond memory encryption. These are platform-level responsibilities.

  6. How EDL pointer annotations work at the trust boundary

    main

    The Enclave Definition Language (EDL) defines the boundary between the untrusted host and the trusted enclave via ECALLs (host $\to$ enclave) and OCALLs (enclave $\to$ host). Pointer annotations in EDL files determine how data is marshalled across this edge:

    • [in]: The marshaller copies the buffer into enclave memory before the call. This mitigates TOCTOU (Time-of-Check-to-Time-of-Use) attacks, but the contents must still be validated.
    • [out]: A buffer is allocated in enclave memory and copied back to the host on return. Do not write secrets here.
    • [in, out]: Data is copied in and then copied back out on return.
    • [string], [size=...], or [count=...]: Defines the length of the data to be copied. Incorrect size definitions are common sources of edge bugs.
    • [user_check]: Highest risk. No copy is performed. The enclave receives a raw untrusted pointer and must manually validate it and assume it can change concurrently due to host access.
  7. How SGX code coverage works

    main

    The sgx_cov mechanism automates the collection of coverage data through the following lifecycle:

    1. Data Injection: An on exit function is injected using the global_dtor macro, which invokes sgx_cov::cov_writeout().
    2. Compile Time: .gcno files are generated at the RustEnclave_Out_Path.
    3. Runtime: .gcna files are generated at the RustEnclave_Out_Path.
    4. Reporting: Running make gen_cov_report processes the .gcno and .gcna files to produce an HTML report.
  8. Configure Tokio runtime and TCS number

    main

    When using Tokio in an enclave, you must ensure the number of Thread Control Structures (TCS) is correctly configured.

    Using #[tokio::main]

    By default, #[tokio::main] creates a worker pool with a number of threads equal to the logical core count. Because 1 TCS is always reserved for the initializer thread, your total TCSnum must be logical core count + 1.

    Example: On a server with 128 logical cores, you must set TCSnum to 129 to run the server enclave natively.

    Using tokio::runtime::Builder

    For more granular control, use tokio::runtime::Builder. This allows you to explicitly set the number of worker threads. The required TCSnum will be worker_threads + 1.

    Example: Setting .worker_threads(32) requires a TCSnum of 33.

  9. Use Tonic and Tokio in an enclave

    main

    Tonic (gRPC) and Tokio (async runtime) are supported within the enclave. To use them, add the following dependencies to your Cargo.toml:

    [dependencies]
    prost = "0.9"
    tokio = { version = "1.0", features = ["rt-multi-thread", "time", "fs", "macros", "net"] }
    tonic = { version = "0.6.2", features = ["tls", "compression"]  }
    
    [build-dependencies]
    tonic-build = { version = "0.6.2", features = ["prost", "compression"] }
  10. Generate SGX code coverage reports

    main

    You can generate coverage reports using the make system. The process involves running the application with the COV=1 flag and then generating the report.

    Standard Build

    $ COV=1 make run
    $ make gen_cov_report

    Using cargo-std

    If your build uses cargo-std, set the BUILD_STD environment variable:

    $ BUILD_STD=cargo COV=1 make run
    $ BUILD_STD=cargo make gen_cov_report

    Using xargo

    If your build uses xargo, set the BUILD_STD environment variable:

    $ BUILD_STD=xargo COV=1 make run
    $ BUILD_STD=xargo make gen_cov_report

    After running these commands, open html/index.html to view the coverage results.

    $ COV=1 make run
    $ make gen_cov_report