Skip to content

Verifying a Trusted Execution Domain ​

Every TED runs inside an Intel TDX trust domain. The platform publishes enough evidence for an independent party to check, without trusting Betteredge, that a given domain booted the expected firmware in the expected configuration on genuine, up-to-date Intel hardware.

This page describes how to reproduce that check offline. It needs no TDX hardware and no TPM - an ordinary Linux workstation is enough.

What the evidence proves ​

EvidenceEstablishes
TDX quoteSigned by Intel-rooted keys: the platform is genuine TDX, its TCB level, and the values of MRTD and RTMR0–3 at quote time
System firmware (OVMF)The exact firmware image the domain boots from; MRTD and the CFV digest are recomputed from it
CC event log (CCEL)The individual boot measurements whose replay produces RTMR0–2; secure boot state and key databases

What it does not prove: anything about the domain after the measured boot completed, the behaviour of workloads running inside it, or the physical security of the site.

Collecting the evidence ​

  • System firmware - TED > Trust > System Firmware > OVMF firmware.

  • Quote - either download the quote attached to a key request under System Boot > Download quote, or generate a fresh one inside the domain. A self-generated quote carries a self-chosen nonce, which rules out replay:

sh
head -c 64 /dev/urandom > nonce.bin
mkdir /sys/kernel/config/tsm/report/r0
dd if=nonce.bin of=/sys/kernel/config/tsm/report/r0/inblob bs=64
cat /sys/kernel/config/tsm/report/r0/outblob > quote.dat
rmdir /sys/kernel/config/tsm/report/r0
xxd -p -c 64 nonce.bin           # keep for the reportData check
  • Event log - copied out of the domain:
sh
cat /sys/firmware/acpi/tables/data/CCEL > ccel.bin

If a downloaded quote arrives base64-encoded, decode it before use:

sh
base64 -d quote.b64 > quote.dat

Tools ​

We provide the td-verify CLI to automate these checks. The TED could also be independently verified with the following tools.

PurposeToolInstall
Quote signature, PCK chain, QE identity, TCBgo-tdx-guest checkgo install github.com/google/go-tdx-guest/tools/check@latest
Same as above, reference implementationIntel DCAP libsgx-dcap-quote-verify + QuoteVerificationSampleIntel apt repository, C++ build
MRTD / RTMR precomputationvirtee/tdx-measure (Rust), cmc/mrtool (Go)cargo install --git … / go install …/tools/mrtool@latest
In-guest inspection: Event log replay, MRTD, CFV, secure boottdeventlog (Canonical tdx-tools-guest), cc-api/cc-measuredistro package / source setupenv.sh

Verification cli ​

Every check below is performed by td-verify, a single static binary built from go-trust. The tool is MIT-licensed library and the platform itself uses for attestation verification:

sh
go install gitlab.com/real-cis/cc/go-trust/cmd/td-verify@latest

Only the quote is required - it is the hardware-signed root that everything else is compared against:

sh
td-verify --quote quote.dat

Each further artefact enables further checks. Anything not supplied is reported as skipped, never as passed:

FlagAdds
--firmware OVMF.fdMRTD recomputation, CFV digest, secure boot variable digests
--ccel ccel.binRTMR0–2 replay, secure boot state, CFV cross-check
--nonce <hex>reportData equals a caller-chosen challenge

Other flags: --qemu-compat (default true, see below), --skip-signature for a fully offline run, --verbose to list every replayed event.

A full run:

sh
td-verify --quote quote.dat \
          --firmware OVMF.fd \
          --ccel ccel.bin \
          --nonce "$(xxd -p -c 64 nonce.bin)"

1. Verify the quote ​

The first check validates the ECDSA signature, the PCK certificate chain up to the Intel SGX Root CA, certificate revocation, the QE identity, and the platform TCB level, using collateral fetched from Intel's provisioning service.

Until this passes, nothing else in the quote means anything - MRTD and the RTMRs are only trustworthy because Intel's key attests to them.

Independent cross-check with a third-party implementation:

sh
go install github.com/google/go-tdx-guest/tools/check@latest
check -in quote.dat -inform bin -get_collateral -check_crl

Intel's DCAP libsgx-dcap-quote-verify with the bundled QuoteVerificationSample is the reference implementation

2. Compare firmware measurements with the quote ​

MRTD is the build-time measurement the TDX module computes over the pages the VMM adds before the domain starts. For TDVF those pages are named in the firmware image's own metadata table, so MRTD can be recomputed offline from the image alone.

The Configuration Firmware Volume (CFV) holds the secure boot variables. It is page-added but not extended into MRTD; TDVF hashes it during boot and extends RTMR0 instead. Betteredge uses MRTD and the CFV digest as the seed for key derivation, which is why both appear on the Trust tab.

With --firmware, td-verify recomputes MRTD, the CFV digest and the PK, KEK, db and dbx measurements, then compares them against the quote and the event log.

QEMU 8.x and --qemu-compat ​

QEMU changed how TDVF sections are processed for the initial page add, which changes the resulting MRTD for an unchanged firmware image (qemu-tdx#1, td-shim#683). The current platform runs QEMU 8.x, so --qemu-compat defaults to true and no flag is needed. Hosts on QEMU 10.x or later need --qemu-compat=false; a MRTD mismatch says which value to try.

WARNING

Third-party MRTD tools (virtee/tdx-measure, cmc/mrtool, dstack-mr, td-shim-tee-info-hash) implement the post-8.x behaviour only and will report a different MRTD for the same image on the current fleet. A mismatch from one of those tools indicates the QEMU version difference, not a tampered firmware image. They remain a valid cross-check for RTMR values, and for MRTD once hosts are on QEMU 10.x.

3. Check secure boot state ​

Secure boot state lives in the event log, not the quote. The relevant record is an EV_EFI_VARIABLE_DRIVER_CONFIG event in RTMR0 carrying the SecureBoot variable, which must hold 0x01.

Secure boot being enabled is necessary but not sufficient: PK, KEK, db and dbx decide which images were allowed to load. With both --firmware and --ccel, td-verify also checks that the variables measured at boot are the ones baked into the image, which ties the key databases back to a downloadable artefact rather than to digests displayed in a dashboard. Those digests must still match a known-good set, and dbx must be current.

4. Replay the event log against the RTMRs ​

Each measurement extends a register with RTMR[i] = SHA384(RTMR[i] || digest), starting from zero. Replaying the log in order must reproduce the register values inside the signed quote. The CC event log records the measurement register index rather than a PCR number:

CC MR indexTDX registerContents
0MRTDfirmware code (build time, not in the log)
1RTMR0TD HOB, CFV, secure boot variables, VMM configuration
2RTMR1kernel / initrd / boot parameters
3RTMR2OS-level components

A match binds the whole log to hardware-signed values: the log cannot be forged without breaking SHA-384, so every individual event in it becomes evidence. --verbose lists each replayed event, which localises a mismatch to a specific boot component.

RTMR3 is reserved for runtime extensions and is not covered by the boot log. A non-zero RTMR3 is legitimate; it must be checked against the signed quote directly, never against the log.

In-guest alternatives for inspecting the log interactively: tdeventlog from Canonical's tdx/guest-tools, or cc-api/cc-measure (tdx_eventlogs, tdx_rtmr, tdx_verify_rtmr).

5. Remaining checks in the quote body ​

Enforced automatically:

  • TD_ATTRIBUTES.DEBUG clear - a debuggable TD offers no confidentiality.
  • MRSIGNERSEAM all zero - the TDX module is Intel-signed.
  • MRCONFIGID, MROWNER, MROWNERCONFIG - expected to be zero unless the platform sets them deliberately.

reportData and freshness ​

reportData is 64 bytes chosen by whoever requested the quote.

For a quote generated inside the domain, it is exactly the nonce written to inblob, and --nonce checks it. This is the only way to prove a quote describes the domain now.

For a quote downloaded from the dashboard, reportData binds a random challenge issued by the key derivation service during the key request. That challenge proves freshness to the service at the time of the request, but it is not predictable from outside, so there is no reference value to compare against - the check is skipped. A downloaded quote is evidence about a past boot, dated by its journal entry; generating a fresh quote is what establishes the current state.

Worth reviewing by hand ​

  • TEE_TCB_SVN and MRSEAM - the TDX module version. These are checked against Intel's TCB info in step 1, which fails outright on a TCB level Intel no longer considers current, so the values are printed for the record rather than for a manual decision.
  • XFAM - the extended features the domain may use.

Interpreting failures ​

SymptomLikely cause
Quote signature or TCB check failsSignature, certificate chain or TCB rejected - not a genuine or not an up-to-date platform
MRTD differsDifferent firmware image, or the wrong --qemu-compat setting for the host
MRTD differs only under a third-party toolQEMU 8.x page-add behaviour; see --qemu-compat above
RTMR0 differs, CFV digest matchesDifferent VMM configuration, boot variables or TD HOB
RTMR1 or RTMR2 differDifferent kernel, initrd or command line
CFV digest differsDifferent secure boot variable set baked into the firmware
Secure boot variables differ from the imageThe domain booted with key databases other than the published ones
Event log parses but replay failsLog truncated or tampered; the LogAreaMinimumLength field of /sys/firmware/acpi/tables/CCEL gives its recorded length

References ​

  • Intel TDX Module Base Architecture Specification - MRTD and RTMR semantics
  • Intel TDX Virtual Firmware Design Guide - TDVF metadata, BFV/CFV, measurement flow
  • UEFI Specification - CC event log format and register mapping
  • TCG PC Client Platform Firmware Profile - event types and structures