DEV Community

Cover image for Read an Intel TDX Quote, Field by Field
VoltageGPU
VoltageGPU

Posted on Originally published at voltagegpu.com

Read an Intel TDX Quote, Field by Field

Originally published on voltagegpu.com, where the bundle and every raw file are linked.

Key takeaways

  • Every value below comes from one public quote, checked with voltage-verify 0.2.2.
  • Six things matter to a tenant: MRTD, RTMR0 to RTMR3, REPORTDATA, the TD attributes, the TCB status and the certificate chain.
  • Each proves something narrow. None shows that the VM runs software you trust.

voltage-verify reduces a TDX quote to one line: RESULT: VERIFIED. Here we open one: a quote captured on 17 September 2026 in a VoltageGPU Confidential VM with one NVIDIA RTX PRO 6000 Blackwell Server Edition. We check it, then read each field for what it proves and what it does not. The bundle is public; all outputs date from 22 October 2026.

What a TDX quote is, and who signs it

Intel TDX runs a VM as a trust domain (TD). A CPU-attested software module, the TDX module, sits between the host and the guest. It gives the guest a TD report: the TD's measurements, the platform's security versions and 64 bytes chosen by the guest, called REPORTDATA. A MAC protects the report, and only the local platform can check it.

So a Quoting Enclave, an Intel SGX enclave on the same host, checks the report and turns it into a quote anyone can verify. A version 4 quote has three parts:

  • a 48-byte header: version 4, key type 2 (ECDSA P-256), TEE type 0x81 (TDX);
  • the 584-byte TD report;
  • the signature data: quote signature, attestation key, the Quoting Enclave's report and the platform's certificate chain.

The attestation key signs the header and the TD report. The Quoting Enclave's report vouches for that key: its data starts with a SHA-256 of the key and the enclave's authentication data. The platform's PCK key signs that report. Intel issues the PCK certificate, whose chain ends at the Intel SGX Root CA. VoltageGPU appears nowhere in this chain.

Step 1: verify the bundle

The bundle holds the quote, a manifest, NVIDIA's GPU tokens and Intel's documents from the day of capture (README). The commands are written for Linux and macOS. We ran them on Windows 11 in Git Bash, where the interpreter is python.

pip install "voltage-verify>=0.2.2"
curl -fsSLO https://voltagegpu.com/blog/two-proofs/evidence/rtx6000b-2026-09-17/bundle.json
voltage-verify verify bundle.json --challenge d807768657e40ee62d430d9dc5eb924d520ba1d07e351bc44ee59dbe611085a7 --hwmodel GB20X --gpus 1
Enter fullscreen mode Exit fullscreen mode

What it printed on 22 October 2026:

[PASS] manifest.format       manifest is well formed
[PASS] manifest.commitments  bundle commitments match the manifest
[PASS] manifest.challenge    challenge is the one this verifier issued
[PASS] tdx.structure         TDX quote v4, TEE 0x81, 4940 bytes
[PASS] tdx.debug             TD attributes 0000001000000000 (0x10000000), DEBUG (bit 0) off: not a debug TD
[PASS] tdx.report_data       quote report_data equals SHA-512 of the manifest
[PASS] tdx.signatures        attestation key, QE binding, QE report and PCK chain verify up to the pinned Intel SGX Root CA
[PASS] tdx.collateral        TCB info and QE identity signed by Intel (Intel PCS, fetched now)
[PASS] tdx.tcb               platform TCB UpToDate, QE UpToDate, TDX_03 UpToDate
[PASS] tdx.revocation        PCK certificate not revoked (57 entries in CRL)
[PASS] tdx.revocation        PCK CA certificate not revoked (0 entries in CRL)
[PASS] nvidia.signatures     2 NVIDIA-signed tokens verify, keys from the bundle chained to the pinned NRAS intermediate (NVIDIA's live JWKS fetched for its intermediates)
[PASS] nvidia.nonce          NRAS eat_nonce equals SHA-256 of the manifest
[PASS] nvidia.policy         overall result true, every GPU: measurements ok, secure boot on, debug off, nonce matched, report signature and chain validated
[PASS] nvidia.freshness      token issued 0s from bundle creation

TDX: MRTD eea8b6a814569a52bd1e12f6b869bb2d...  TCB UpToDate  QE UpToDate
GPU: GPU-0 GB20X driver 595.71.05 vbios 98.02.9E.00.01 measurements success

RESULT: VERIFIED
Enter fullscreen mode Exit fullscreen mode

Fifteen checks pass. This article reads the tdx.* lines. The nvidia.* lines are covered in the bundle tutorial.

Step 2: print every field

With --json, voltage-verify lists the main fields under facts.tdx, not the whole TD report or the certificates. This script prints everything, using the standard library and cryptography, which voltage-verify installs.

"""Print every field of the Intel TDX quote carried by a voltage-verify bundle.

Usage: python3 -I read_quote.py bundle.json
Layout of a TDX quote v4: a 48-byte header, the 584-byte TD report, then the
signature data. Standard library only, plus `cryptography` (installed with
voltage-verify) to read the certificates.
"""
import base64
import hashlib
import json
import struct
import sys

from cryptography import x509
from cryptography.hazmat.primitives import hashes

bundle = json.load(open(sys.argv[1], encoding="utf-8"))
b64 = bundle["tdx"]["quote_b64"]
quote = base64.b64decode(b64 + "=" * (-len(b64) % 4))

version, key_type, tee_type = struct.unpack_from("<HHI", quote, 0)
print(f"header: version {version}, key type {key_type}, TEE type 0x{tee_type:x}, {len(quote)} bytes")

# TD report fields: (name, offset in the quote, size in bytes)
FIELDS = [
    ("TEE_TCB_SVN", 48, 16), ("MRSEAM", 64, 48), ("MRSIGNERSEAM", 112, 48),
    ("SEAMATTRIBUTES", 160, 8), ("TDATTRIBUTES", 168, 8), ("XFAM", 176, 8),
    ("MRTD", 184, 48), ("MRCONFIGID", 232, 48), ("MROWNER", 280, 48),
    ("MROWNERCONFIG", 328, 48), ("RTMR0", 376, 48), ("RTMR1", 424, 48),
    ("RTMR2", 472, 48), ("RTMR3", 520, 48), ("REPORTDATA", 568, 64),
]
for name, off, size in FIELDS:
    print(f"{name:<14} {quote[off:off + size].hex()}")

attrs = int.from_bytes(quote[168:176], "little")
print(f"TD attributes 0x{attrs:x}: DEBUG (bit 0) = {attrs & 1}, SEPT_VE_DISABLE (bit 28) = {attrs >> 28 & 1}")

canonical = json.dumps(bundle["manifest"], sort_keys=True, separators=(",", ":"), ensure_ascii=False)
print("REPORTDATA == SHA-512(manifest):", hashlib.sha512(canonical.encode()).digest() == quote[568:632])

sig_len = struct.unpack_from("<I", quote, 632)[0]
sig = quote[636:636 + sig_len]  # quote signature (64), attestation key (64), certification data
cert_type, cert_len = struct.unpack_from("<HI", sig, 128)
qe = sig[134:134 + cert_len]  # QE report (384), its signature (64), auth data, PCK chain
prod_id, isv_svn = struct.unpack_from("<HH", qe, 256)
print(f"signature data: {sig_len} bytes, certification data type {cert_type}")
print(f"QE report: MRSIGNER {qe[128:160].hex()}, ISVPRODID {prod_id}, ISVSVN {isv_svn}")
auth_len = struct.unpack_from("<H", qe, 448)[0]
inner_type, inner_len = struct.unpack_from("<HI", qe, 450 + auth_len)
pem = qe[456 + auth_len:456 + auth_len + inner_len].rstrip(b"\0")
print(f"certification data type {inner_type}:")
for cert in x509.load_pem_x509_certificates(pem):
    print(f"  {cert.subject.rfc4514_string()}  (valid until {cert.not_valid_after_utc:%Y-%m-%d})")
print("root SHA-256:", cert.fingerprint(hashes.SHA256()).hex())
Enter fullscreen mode Exit fullscreen mode

python3 -I read_quote.py bundle.json printed:

header: version 4, key type 2, TEE type 0x81, 4940 bytes
TEE_TCB_SVN    05030400000000000000000000000000
MRSEAM         476a2997c62bccc78370913d0a80b956e3721b24272bc66c4d6307ced4be2865c40e26afac75f12df3425b03eb59ea7c
MRSIGNERSEAM   000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
SEAMATTRIBUTES 0000000000000000
TDATTRIBUTES   0000001000000000
XFAM           e702060000000000
MRTD           eea8b6a814569a52bd1e12f6b869bb2d9c0c8a7a43e658ffc3b42c199f116157ea7f04d359c7fdfd8ac483152cc13542
MRCONFIGID     000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MROWNER        000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MROWNERCONFIG  000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
RTMR0          f9ac3522e05572c2ede103eb9f243bebddee62d8e8db65a526736ea2bd5eb6dbe69a5ff8082c8050865b5ddadae4fa8a
RTMR1          965b54adf526d37237906189a31d9b058c39fac8909d9689e3340505aac4176deed2c2f3374b226304b23137d4832ae9
RTMR2          c2f56e0459db5660608f8f3a312f67decc0d210d55e93d3d106fe7f939941c524b0b370d53c4a6d6290e2df3b9511397
RTMR3          000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
REPORTDATA     832791479ad739ef2c1d51e1fb1da7a7a1422b6c88afaf2ca1c292f1ae9ee7dbe5e571b9926390cfdd7f62672c696ccda0c004a0c779a30c16ff80ce461790b8
TD attributes 0x10000000: DEBUG (bit 0) = 0, SEPT_VE_DISABLE (bit 28) = 1
REPORTDATA == SHA-512(manifest): True
signature data: 4304 bytes, certification data type 6
QE report: MRSIGNER dc9e2a7c6f948f17474e34a7fc43ed030f7c1563f1babddf6340c82e0e54a8c5, ISVPRODID 2, ISVSVN 7
certification data type 5:
  C=US,ST=CA,L=Santa Clara,O=Intel Corporation,CN=Intel SGX PCK Certificate  (valid until 2033-03-13)
  C=US,ST=CA,L=Santa Clara,O=Intel Corporation,CN=Intel SGX PCK Platform CA  (valid until 2033-05-21)
  C=US,ST=CA,L=Santa Clara,O=Intel Corporation,CN=Intel SGX Root CA  (valid until 2049-12-31)
root SHA-256: 44a0196b2b99f889b8e149e95b807a350e7424964399e885a7cbb8ccfab674d3
Enter fullscreen mode Exit fullscreen mode

The offsets match voltage-verify's parser (TD attributes at byte 168, REPORTDATA at 568), and the sizes add up: 48 + 584 + 4 (a length field) + 4,304 = 4,940 bytes. MRCONFIGID, MROWNER and MROWNERCONFIG, immutable software-defined IDs in Linux's description, are zero: they carry nothing here. We do not interpret XFAM or SEAMATTRIBUTES.

Anatomy of an Intel TDX quote v4 of 4,940 bytes: a 48-byte header and the 584-byte TD report, both covered by the quote signature, then a 4-byte length and 4,304 bytes of signature data. TDATTRIBUTES, MRTD, RTMR0 to RTMR3 and REPORTDATA are the fields a tenant checks; the signature chain runs from the attestation key through the QE report and the PCK certificate to the pinned Intel SGX Root CA.
The quote of the 17 Sep 2026 bundle, byte by byte. Offsets as read by read_quote.py above. The cloud provider is not in the signature chain.

The fields, one by one

MRTD: what the TD started from

Value: eea8b6a8…2cc13542.

The TDX module computes MRTD while the host builds the TD, before the TD runs. Linux documents it as the measurement of the TD's initial contents: its initial configuration and firmware image.

What it proves. The TD started from contents with this hash, measured by the TDX module, not reported by the host.

What it does not prove. That this firmware is one you trust: that needs a reference value, ideally rebuilt from source, and we publish none for this image. Our data only shows stability: the same MRTD appears in all four RTX PRO 6000 bundles we have published.

RTMR0 to RTMR3: the boot chain

Values: RTMR0 f9ac3522…dae4fa8a, RTMR1 965b54ad…d4832ae9, RTMR2 c2f56e04…b9511397, RTMR3 all zeros.

RTMRs are run-time registers that software in the TD can extend, mixing new data into the current value. The UEFI specification (2.10, section 38.4.1), as implemented in the EDK2 firmware, maps PCR 1 and 7 to RTMR0, PCR 2 to 6 to RTMR1 and PCR 8 to 15 to RTMR2. Nothing maps to RTMR3. Typically, RTMR0 holds the firmware configuration, RTMR1 the boot loader and kernel, RTMR2 the kernel command line and initrd.

What they prove. The boot events recorded by firmware and the boot loader hash to these values.

What they do not prove. Which events those were. A hash chain cannot be read backwards: you replay the firmware's event log and compare, and the bundle does not include that log.

The published bundles show the limit. RTMR0 and RTMR1 are identical in all four, RTMR3 is zero in all four, and RTMR2 differs every time:

Bundle RTMR2, first 16 hex digits
17 Sep, 00:00 UTC (this one) c2f56e0459db5660
17 Sep, 12:28 UTC (deployed by API) c67f740f73f8d900
9 Oct d9d5a5c17828c2b8
17 Oct (weekly run) 49b10f1d50c9b0fe

We have not published the event log that would explain the change. Pinning RTMR2 would have accepted at most one of these VMs. Pinning MRTD, RTMR0 and RTMR1 would have accepted all four; expect them to change with image updates.

REPORTDATA: your challenge

Value: 83279147…461790b8 (64 bytes).

The guest software chooses these 64 bytes. voltage-verify writes there the SHA-512 of the manifest, serialized canonically (keys sorted, no spaces, UTF-8). The manifest holds a 32-byte challenge, here d8077686…611085a7, and the script confirms the hash. The SHA-256 of the same manifest is the nonce in NVIDIA's GPU tokens: that manifest is the only link between the two proofs.

A challenge the bundle was not made for fails (output trimmed):

$ voltage-verify verify bundle.json --offline --challenge 0000000000000000000000000000000000000000000000000000000000000000
[FAIL] manifest.challenge    challenge differs from the one this verifier issued (replay or foreign bundle)
RESULT: NOT VERIFIED (manifest.challenge)
Enter fullscreen mode Exit fullscreen mode

What it proves. The quote was requested for this exact manifest. If you generated the challenge, the quote was produced after you asked, not replayed.

What it does not prove. Freshness to you, unless the challenge is yours: here it was drawn inside the VM. Generate yours on your machine; the published script two-proofs-in-the-vm.sh accepts it as CHALLENGE. The field also means only what the guest software decided: our inference run of 16 October puts a SHA-256 of a nonce and the instance's public key in its first 32 bytes.

TD attributes: the debug bit

Value: 0000001000000000, read as a little-endian 64-bit integer: 0x10000000.

Only bit 28 is set. Linux calls it SEPT_VE_DISABLE; in Linux 6.8, a guest not in debug mode panics at boot without it (this guest runs 6.8.0-110-generic). Bit 0, DEBUG, is 0.

A debug TD gives no confidentiality: the host can read and modify its memory and CPU state, and Intel's Quoting Enclave still signs its quote. voltage-verify 0.2.1 and earlier printed this field without checking it. Version 0.2.2, released on 21 October 2026, fails a quote with bit 0 set unless you pass --allow-debug. Here is a copy of the quote with bit 0 flipped:

$ python3 -I -c "import json,base64;s=json.load(open('bundle.json'))['tdx']['quote_b64'];open('quote.bin','wb').write(base64.b64decode(s+'='*(-len(s)%4)))"
$ python3 -I -c "q=bytearray(open('quote.bin','rb').read()); q[168]|=1; open('quote-debug.bin','wb').write(q)"
$ voltage-verify quote quote-debug.bin --offline
[PASS] tdx.structure   TDX quote v4, TEE 0x81, 4940 bytes
[FAIL] tdx.debug       TD attributes 0100001000000000 (0x10000001), DEBUG (bit 0) ON: a debug TD gives no confidentiality, the host can read and modify its memory
[FAIL] tdx.signatures  quote signature does not verify with the attestation key: 

TDX: MRTD eea8b6a814569a52bd1e12f6b869bb2d...  TCB ?  QE ?

RESULT: NOT VERIFIED (tdx.debug, tdx.signatures)
Enter fullscreen mode Exit fullscreen mode

tdx.debug fails because the bit is set; tdx.signatures fails because the attestation key signed the original bytes. A genuine debug TD has a validly signed quote, so only tdx.debug would catch it.

What it proves. The TD was not created in debug mode.

What it does not prove. Anything about the software inside it.

TCB status: is the platform current?

TEE_TCB_SVN, 05030400000000000000000000000000, records the TDX module's security version at TD launch. voltage-verify reads the module's major version from its second byte (03, hence TDX_03) and its security version from the first (05). The PCK certificate adds the CPU's SGX security versions and the FMSPC, 20a06d080000, which identifies the platform family.

Intel publishes signed TCB info per FMSPC: a list of levels, newest first, where the first level the platform meets gives its status. In the copy stored in the bundle (issued 16 September 2026), the UpToDate level, dated 13 August 2025, requires TDX components of at least 05 00 04. This quote has 05 03 04.

Online on 22 October, Intel's current documents give platform TCB UpToDate, QE UpToDate, TDX_03 UpToDate, with no advisory IDs. Offline, the stored documents give the same verdict plus a warning, as they passed their nextUpdate date on 16 October 2026:

[WARN] tdx.collateral_fresh  Intel collateral is past its nextUpdate; refetch online
Enter fullscreen mode Exit fullscreen mode

What it proves. On the date of Intel's documents, Intel rated the platform, the TDX module and the Quoting Enclave UpToDate.

What it does not prove. That this lasts. In the same TCB info, the level dated 14 May 2025 is rated OutOfDate. An offline check is only as current as the documents it reads.

The certificate chain: who vouches

The script output ends with the chain: PCK Certificate, PCK Platform CA, Intel SGX Root CA. voltage-verify checks each signature and validity date, and compares the root with the copy of Intel's root it ships, pinned by its SHA-256 (44a0196b…fab674d3). The Quoting Enclave's MRSIGNER (dc9e2a7c…0e54a8c5) and product ID (2) match Intel's signed identity for it, and its security version (7) meets the UpToDate level (4 in the stored identity). Last, the PCK certificate is not among the 57 entries of Intel's revocation list, and the root's list is empty. voltage-verify selftest also alters one byte of the quote body:

[PASS] quote-tamper       one byte of the TDX quote body altered  ->  rejected on tdx.signatures
Enter fullscreen mode Exit fullscreen mode

What it proves. A genuine Intel platform, with an identity Intel issued, signed this quote, and the quote has not changed since.

What it does not prove. Who operates the machine, or where. The certificates name Intel, not a cloud provider.

What this proves, and what it does not

Together, the fields prove that on 17 September 2026 a trust domain, not in debug mode, ran on an Intel platform that Intel rated UpToDate, with the measurements above, and produced this quote for this manifest.

They do not prove:

  • that the firmware and kernel are ones you trust: no reference values are published for this image, and RTMR2 changes from one VM to the next;
  • anything about the GPU: the NVIDIA tokens are a separate proof, tied to the quote only by the manifest, so the two are not shown to share a machine;
  • which code ran after boot: RTMR3 is zero and the manifest names no image;
  • freshness to you, since this challenge was drawn inside the VM;
  • the state of the TD today: a quote describes the TD when it was produced.

Reproduce it

Tested on 22 October 2026 on Windows 11 (Git Bash, Python 3.12.4), with python for python3 and . vv/Scripts/activate for the venv.

python3 -m venv vv && . vv/bin/activate
pip install "voltage-verify>=0.2.2"
B=https://voltagegpu.com/blog/two-proofs/evidence/rtx6000b-2026-09-17
curl -fsSLO "$B/bundle.json"
curl -fsSLO "$B/SHA256SUMS"
grep ' bundle.json$' SHA256SUMS | sha256sum -c -
C=d807768657e40ee62d430d9dc5eb924d520ba1d07e351bc44ee59dbe611085a7
voltage-verify verify bundle.json --challenge $C --hwmodel GB20X --gpus 1
voltage-verify verify bundle.json --challenge $C --offline --json
voltage-verify selftest bundle.json --offline --challenge $C
python3 -I read_quote.py bundle.json   # the script from Step 2
Enter fullscreen mode Exit fullscreen mode

Expected: bundle.json: OK, RESULT: VERIFIED, "ok": true with the tdx.collateral_fresh warning, SELFTEST: PASS, then the fields of Step 2. To compare RTMR2, run the script on the bundles in rtx6000b-api-2026-09-17/ and rtx6000b-2026-10-09/, next to this one, and on the weekly run listed on /proofs.

Further reading

  • /proofs: every proof we publish, with the command that rechecks it.
  • voltage-verify: what the tool checks, its changelog and its source (MIT).
  • Inference proofs, 16 October 2026: the same Intel checks on every instance serving three TEE models, with another REPORTDATA convention.

Top comments (0)