Skip to content

Add Intel TDX support to story-kernel #65

Description

@0xHansLee

Description and context

story-kernel currently runs exclusively on Intel SGX via Gramine. The TEE-specific surface is small and isolated (~150 LOC) inside the enclave/ package, with five public entry points (GetRemoteQuote, GetSelfCodeCommitment, ValidateCodeCommitment, SealToFile/UnsealFromFile, NewSealedLevelDB).

We want to add Intel TDX as a second supported TEE backend so the kernel can run on TDX-capable hosts in addition to SGX. The on-chain identity stored on the Story chain must remain in its native form per TEE type (32B MRENCLAVE for SGX, MRTD + RTMRs for TDX); the Automata DCAP attestation contract handles both quote formats.

Two main TEE-specific concerns differ between SGX and TDX:

  1. Quote interface — SGX uses Gramine's /dev/attestation/{user_report_data,quote}. TDX uses the Linux configfs-tsm interface (/sys/kernel/config/tsm/report/) or the /dev/tdx_guest ioctl.
  2. Sealing — SGX provides hardware sealing via EGETKEY (MRENCLAVE + CPU bound, stateless, reboot-survivable). TDX has no equivalent CPU instruction. The closest equivalent operational model is TPM2 PCR-binding sealing, where TDX measurements (MRTD/RTMR) are extended into vTPM PCRs and data is sealed against a PCR policy. This preserves the SGX guarantee of "same machine + same code → always unseal, no external dependencies, reboot-survivable".

Options considered

Option Approach Verdict
A. Native Go (recommended) Use google/go-tdx-guest for TDX quote generation/parsing; use Go TPM2 libraries (go-tpm) for sealing. No new toolchain. ✅ Lowest complexity
B. Rust TDX crate via cgo FFI Use a Rust TDX library compiled as staticlib, called via Go cgo. ❌ Adds Rust toolchain on top of existing Go + C++ (cb-mpc) — high build/CI/debug cost for no functional gain
C. Rust sidecar process Separate Rust binary for TDX primitives, Go calls via Unix socket. ❌ No security benefit (same TCB), only operational complexity

google/go-tdx-guest is production-quality (used by Google Confidential Space) and covers TDX quote generation, parsing, and DCAP verification. Sealing primitives are TEE-agnostic standard Linux APIs (TPM2, configfs-tsm).

Suggested solution

  1. Introduce a TEE interface in enclave/ covering Quote, Seal, Unseal, GetIdentity, ValidateIdentity. Identity is a variable-length byte slice tagged with TEE type — no compression of MRTD/RTMR.
  2. Move existing Gramine SGX implementation behind //go:build sgx.
  3. Add TDX implementation behind //go:build tdx using google/go-tdx-guest for attestation and TPM2 PCR-binding for sealing.
  4. The NonceBindingSealer wrapper in store/nonce_sealer.go is TEE-agnostic and stays unchanged on top of either backend.
  5. Add Makefile targets (build-sgx, build-tdx) and CI matrix for both backends.
  6. The existing light_client sealed DB and DKG share sealing semantics are preserved on TDX via the TPM2 PCR sealing path.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions