This document describes the security model of the Apache Teaclave™ dependency crates repository (teaclave-crates). It has two audiences:
teaclave-* crates when building SGX enclaves or TrustZone Trusted Applications, and maintainers who port and adapt crates here.This repository is not an application and does not itself contain a trust boundary (there is no ECALL/OCALL edge or Normal/Secure-world split here). Instead it hosts the dependencies that are linked into the trusted side of TEE applications built with the Teaclave SGX SDK and the Teaclave TrustZone SDK. Its security model is therefore about what gets pulled into someone else's Trusted Computing Base, and about provenance — the integrity of the port relative to its upstream.
Every crate published from this repository is intended to be linked into the trusted side of a TEE application — inside an SGX enclave or a TrustZone TA.
The consequence is blunt:
There is no privilege separation between these crates and the secrets of the enclave/TA that links them. A bug or backdoor in any crate here executes inside the TEE, with access to keys, sealing/attestation material, and plaintext data. A single weakness propagates to every downstream application that depends on the affected
teaclave-*crate.
So the unit of trust is the whole repository. Unlike the SDK repositories — where the security story is “validate untrusted input at the boundary” — here the story is “do not let the port weaken, or drift away from, the security properties the upstream crate provides, and do not let anything untrusted enter the TCB through the supply chain.”
The adversary is inherited from the downstream SDK and is the same untrusted world those SDKs assume:
In addition, this repository faces a supply-chain adversary: anyone able to influence the ported source, a patch, a pinned upstream snapshot, a build script, or a prebuilt binary artifact can compromise every consumer.
teaclave-* artifact on crates.io matches this repository, and that upstream security fixes are tracked and re-ported.The platform-level threats are out of scope here exactly as in the SDKs: microarchitectural / speculative side channels, availability/DoS, and rollback of data persisted outside the TEE. A finding that depends only on those is not a bug in this repository.
Per the README, crates are hosted in one of two ways, and this determines what an auditor must actually look at:
libc-0.2.182-e879ee9/optee-0001-libc-adaptation.patch (Base-Commit: e879ee90…)rust-1.93.1-01f6ddf/optee-0001-std-adaptation.patch (Base-Commit: 01f6ddf7…) — this patches the Rust standard library itself for the OP-TEE target.ring-0.17.14/, getrandom-0.2.16/. By convention the commit history makes the adaptation diffable: a Download <crate> <version> from crates.io commit imports the pristine upstream source (including .cargo_vcs_info.json, which records the upstream revision for provenance), and the following commit(s) apply the TEE port.Crates are published to crates.io under the teaclave-* namespace (e.g. an adaptation of ring is published as teaclave-ring) so downstream code can depend on them with ordinary Cargo syntax. The repository keeps only the latest ported version of each crate.
The review unit is the diff from upstream, not the whole crate. The README states it directly: “Each crate undergoes a security review focused on diffs from the upstream.” The overwhelming majority of bytes in ring-0.17.14/ or the std snapshot are unmodified upstream code that has already been reviewed by the upstream community. The security-relevant change is:
.patch file (and confirming the Base-Commit snapshot is authentic);Download ... from crates.io commit — i.e. git diff <download-commit> HEAD -- <crate-dir>/ (cross-check .cargo_vcs_info.json against the upstream release for provenance).Every path here is TCB. The table instead points to what each port adapts and the security-critical seam an auditor should focus on.
| Path | Upstream | What it adapts for TEE | Security-critical seam |
|---|---|---|---|
getrandom-0.2.16/ | getrandom | The randomness source. Adds TEE backends — src/optee.rs (OP-TEE) alongside src/rdrand.rs (used under SGX). | Entropy must come from a hardware/TEE RNG (RDRAND/sgx_read_rand, OP-TEE TRNG) — never from an untrusted-host or predictable source. This is the single most security-sensitive primitive in the repo: a weak getrandom silently undermines every key and nonce generated in the TEE. |
libc-0.2.182-e879ee9/ | libc | Adds the optee target (target_os = "optee") and a new src/optee/mod.rs syscall surface. | libc calls route to the TEE OS / untrusted world. Results crossing back (return values, errno, buffers) are untrusted and must not be trusted by callers for security decisions. Review the added syscall declarations for correctness and for anything that leaks or trusts host data. |
rust-1.93.1-01f6ddf/ | Rust std / compiler | Adds OP-TEE target specs and adapts std (library/std) for the target. | std is in the TCB. Scrutinize adapted fs, time, env, net, thread, panic/abort, and allocation paths — anything that reaches an untrusted service or changes a security-relevant default. A std weakness affects all TrustZone std TAs. |
ring-0.17.14/ | ring | Full import of the crypto crate adapted to build for the TEE target. | Crypto primitives are TCB. Note the prebuilt binary artifacts under pregenerated/ (.S, .asm, and even a checked-in .o object) and the ~1000-line build.rs — these are TCB code that is not easily source-reviewable and run/link at build time. Confirm they correspond to the asm sources and the named upstream. |
When new crates are added, classify each the same way: what upstream security primitive does this port touch, and does the adaptation preserve or weaken it?
The README frames the repository's purpose as “Adapting With Target-Dependent Security Primitives.” These are precisely the seams where a port can go wrong, because the upstream implementation assumed a normal OS and the TEE port must substitute a different mechanism:
/dev/urandom via an untrusted FS, a fixed seed, or a non-CSPRNG is a critical vulnerability. (getrandom backends.)For each of these, the auditor's question is the same: does the TEE adaptation preserve the security property the upstream crate guarantees on a normal OS, or does it weaken it?
Because the whole repository is TCB and is consumed as binary teaclave-* packages by other projects, provenance is a first-class security property here — arguably the security property.
Base-Commit snapshot being authentic and the patch being exactly what was reviewed. Verify the upstream commit hash; do not review the patch against an unverified tree.ring, libc, or getrandom, or a Rust std soundness fix), the port must be re-based and re-published. Stale ports silently retain fixed vulnerabilities — check the ported version against the latest upstream advisories.ring-0.17.14/pregenerated/*.o / *.S / *.asm) and build scripts execute or link into the enclave/TA and cannot be fully source-reviewed. Treat them as high-trust artifacts: confirm they match their asm sources and the upstream release, and flag any that cannot be reproduced from source.build.rs and proc-macros run on the build/CI host and determine the binary that is measured (MRENCLAVE) or signed (TA). The build host and CI are part of the trust chain.teaclave-* artifact a downstream project pulls from crates.io must correspond to the reviewed source in this repository. A mismatch between the published crate and this repo is a supply-chain break.Base-Commit for every crate, and keep the adaptation diff minimal and reviewable.cargo audit / cargo deny in CI.teaclave-* crate is built from this repository with a verifiable trail.Note to the reviewing agent: Treat everything in this repository as Trusted Computing Base — it is linked into downstream enclaves/TAs. But review the diff from upstream, not the entire vendored crate. The bulk of a full import (e.g.
ring-0.17.14/) or the std snapshot is unmodified, already-reviewed upstream code; auditing it line-by-line as if it were first-party is wasted effort and produces false positives. Identify the change set first:
- For a patch bundle, read the
.patchfile and theBase-Commitit targets; the patch is the review.- For a full import, diff the TEE port against the pristine upstream the repo preserves in its own history — the
Download <crate> <version> from crates.iocommit:git diff <download-commit> HEAD -- <crate-dir>/. Review only that delta plus the build-time and binary artifacts, and cross-check.cargo_vcs_info.jsonagainst the upstream release. If you cannot obtain the upstream baseline to diff against, say so explicitly and treat the port as unreviewed rather than assuming it matches upstream.
To keep findings high-signal:
Where real findings concentrate
getrandom backends): is entropy sourced from a TEE/hardware RNG, never from an untrusted or predictable source?std path that reaches an untrusted service (fs, time, env, net): does the port trust untrusted return values it shouldn't?cfg-gated branch that behaves differently on the TEE target.build.rs, proc-macros, and prebuilt objects/assembly that enter the TCB and can't be source-reviewed.Expected non-findings (avoid these false positives)
unsafe/FFI as a new finding.Before reporting, state whether the code is part of the adaptation diff or unmodified upstream, and which target-dependent security primitive (§4) or supply-chain property (§5) the issue affects. If a finding is in unmodified upstream code, it is almost certainly out of scope here.
Security issues should be reported privately first, per SECURITY.md, before any public disclosure. Vulnerabilities that originate in unmodified upstream code should additionally be reported to the upstream project.