Low-Level API
Raw quote generation, REPORTDATA extraction, and local field inspection — no network or hardware required for verification.
The low-level API gives you direct access to quote generation and field extraction. Use it when you need full control over the REPORTDATA layout, want to verify quotes received from other systems, or are building a custom verification pipeline.
All extraction functions work without TDX hardware and without a network connection.
Quote generation
generate_evidence produces a DCAP quote from a 64-byte REPORTDATA payload.
use livy_tee::{generate_evidence, report::{ReportData, REPORT_DATA_VERSION}};
// Build your ReportData however you like — the low-level API is agnostic
// about what payload_hash means.
let rd = ReportData::new(
payload_hash, // [u8; 32] — your commitment hash
build_id, // [u8; 8] — SHA-256(binary)[0..8]
REPORT_DATA_VERSION,
build_number, // u32 — CI counter, 0 in development
nonce, // u64 — monotonic counter
);
let rd_bytes: [u8; 64] = rd.to_bytes();
// On real TDX hardware: returns an ~8000-byte DCAP quote via TSM configfs.
// With mock-tee feature: returns a correctly-shaped 632-byte stub.
let evidence = generate_evidence(&rd_bytes)?;
println!("quote length: {} bytes", evidence.raw().len());The Evidence type is a thin wrapper around the raw quote bytes:
use livy_tee::Evidence;
// Access raw bytes.
let raw: &[u8] = evidence.raw();
// Construct from received bytes (e.g. from an API response).
let evidence = Evidence::from_bytes(received_bytes)?;Extracting REPORTDATA
Extract the 64-byte REPORTDATA from a quote. No signature verification is performed — this is a pure byte extraction.
use livy_tee::{extract_report_data, report::ReportData};
// Extract raw 64-byte REPORTDATA from the quote.
// In the ITA flow, this field is SHA-512(nonce_val ‖ nonce_iat ‖ runtime_data),
// not the ReportData struct itself.
let report_data_bytes: [u8; 64] = extract_report_data(&evidence)?;
// Parse the ReportData struct from the raw runtime_data bytes
// (the 64-byte payload passed to generate_evidence, not the quote field above).
let rd = ReportData::from_bytes(&runtime_data_bytes);
println!("payload_hash: {}", hex::encode(rd.payload_hash));
println!("nonce: {}", rd.nonce);
println!("version_code: {}", rd.version_code);Extracting the MRTD
The MRTD (Measurement of Trust Domain) is the 48-byte hardware measurement of the binary that was launched in the TD. In real TDX quotes this is a SHA-384 of the TD image; in mock quotes it is all zeros.
use livy_tee::extract_mrtd;
let mrtd: [u8; 48] = extract_mrtd(&evidence)?;
println!("mrtd: {}", hex::encode(mrtd));Anyone who can reproduce the build can independently compute the MRTD and compare it against this value.
Combined generation and ITA verification
generate_and_attest is the mid-level function used internally by the high-level API. It generates a quote and sends it to Intel Trust Authority in one call.
use livy_tee::{generate_and_attest, ItaConfig};
let config = ItaConfig {
api_key: "your-key".to_string(),
..ItaConfig::default()
};
let attested = generate_and_attest(&rd.to_bytes(), &config).await?;
// Fields on AttestedEvidence:
println!("ita_token: {}", attested.ita_token);
println!("mrtd: {}", attested.mrtd);
println!("tcb_status: {}", attested.tcb_status);
// Raw quote bytes.
let quote_bytes: &[u8] = attested.evidence.raw();
// Original 64-byte ReportData struct (what was passed to generate_evidence).
let runtime_data: &[u8] = &attested.runtime_data;
// ITA verifier nonce components (for verify_quote).
let nonce_val: &[u8] = &attested.nonce_val;
let nonce_iat: &[u8] = &attested.nonce_iat;Extracting REPORTDATA from an ITA JWT
Parse the structured ReportData from an ITA JWT without making any network calls:
use livy_tee::report_data_from_token;
if let Some(rd) = report_data_from_token(&ita_token)? {
println!("payload_hash: {}", hex::encode(rd.payload_hash));
println!("build_id: {}", hex::encode(rd.build_id));
println!("nonce: {}", rd.nonce);
}Binary hash
Get the SHA-256 hex hash of the currently running executable — used to derive build_id:
use livy_tee::binary_hash;
// Returns hex(SHA-256(running_binary_bytes)).
let hash_hex: String = binary_hash()?;
println!("binary_hash: {}", hash_hex);DCAP quote byte layout
For low-level parsing, the DCAP v4 quote structure is:
[0..2] version u16 LE — must be 4
[2..4] att_key_type u16 LE
[4..8] tee_type u32 LE — 0x81 = TDX
[8..48] header rest
── TD Report Body (520 bytes @ 48) ──
[48..184] various TD fields (TEETCBSVN, MRSEAM, …)
[184..232] MRTD 48 bytes — binary measurement
[232..568] more TD fields (RTMR0..3, etc.)
[568..632] REPORTDATA 64 bytes — SHA-512(nonce_val ‖ nonce_iat ‖ runtime_data)
[632..] attestation key + certification chainError types
use livy_tee::{ExtractError, GenerateError, EvidenceError};
// ExtractError — returned by extract_report_data and extract_mrtd
match extract_report_data(&evidence) {
Err(ExtractError::TooShort(len)) => eprintln!("quote too short: {len} bytes"),
Err(ExtractError::UnsupportedVersion(v)) => eprintln!("expected v4, got v{v}"),
Err(ExtractError::UnsupportedTeeType(t)) => eprintln!("expected TDX (0x81), got 0x{t:08x}"),
Ok(bytes) => { /* ... */ }
}