A Rust library providing a unified interface for TEE (Trusted Execution Environment) attestation evidence generation and verification.
| Platform | Attest | Verify | WASM Verify |
|---|---|---|---|
| AMD SEV-SNP (bare-metal) | Yes | Yes | Yes |
| Intel TDX (bare-metal) | Yes | Yes | Yes |
| Azure SEV-SNP (vTPM) | Yes | Yes | Yes |
| Azure TDX (vTPM) | Yes | Yes | Yes |
| GCP SEV-SNP (non-vTPM) | Yes | Yes | Yes |
| GCP TDX (non-vTPM) | Yes | Yes | Yes |
| Dstack TDX | Yes | Yes | Yes |
[dependencies]
attestation = { path = ".", features = ["snp", "tdx"] }| Feature | Description |
|---|---|
snp |
AMD SEV-SNP support (verify always, attest when attest also enabled) |
tdx |
Intel TDX support |
az-snp |
Azure SEV-SNP vTPM support (implies snp) |
az-tdx |
Azure TDX vTPM support (implies tdx) |
gcp-snp |
GCP SEV-SNP non-vTPM support (implies snp) |
gcp-tdx |
GCP TDX non-vTPM support (implies tdx) |
dstack |
Dstack TDX support via Unix socket (implies tdx) |
attest |
Enable guest-side evidence generation (Linux-only, requires TEE hardware) |
cli |
Build the attestation-cli binary |
All six platform features are enabled by default. Verification is always compiled when a platform feature is enabled. The attest feature gates all guest-side code that requires hardware access.
use attestation::{VerifyParams, VerificationResult};
#[tokio::main]
async fn main() {
// evidence_json is a self-describing AttestationEvidence envelope
let evidence_json: &[u8] = b"...";
let params = VerifyParams {
expected_report_data: Some(vec![0xAA; 64]),
..Default::default()
};
let result = attestation::verify(evidence_json, ¶ms).await.unwrap();
println!("Signature valid: {}", result.signature_valid);
println!("Platform: {}", result.platform);
println!("Launch digest: {}", result.claims.launch_digest);
println!("Report data match: {:?}", result.report_data_match);
}use attestation::{Verifier, VerifyParams};
#[tokio::main]
async fn main() {
let verifier = Verifier::new();
// Or with custom cert/collateral providers:
// let verifier = Verifier::new()
// .with_cert_provider(my_cert_provider)
// .with_tdx_provider(my_tdx_provider);
let result = verifier
.verify(evidence_json, &VerifyParams::default())
.await
.unwrap();
}#[tokio::main]
async fn main() {
// Auto-detect the TEE platform
let platform = attestation::detect().expect("no TEE platform detected");
println!("Detected platform: {}", platform);
// Generate evidence with a challenge nonce
let nonce = b"server-provided-challenge-nonce";
let evidence_json = attestation::attest(platform, nonce, &attestation::AttestOptions::default()).await.unwrap();
// Send evidence_json to the verifier — it's a self-describing envelope
println!("Evidence: {} bytes", evidence_json.len());
}Each platform has a dedicated example. Run on the appropriate hardware:
cargo run --example snp --features "snp,attest"
cargo run --example tdx --features "tdx,attest"
cargo run --example az_snp --features "az-snp,attest"
cargo run --example az_tdx --features "az-tdx,attest"
cargo run --example gcp_snp --features "gcp-snp,attest"
cargo run --example gcp_tdx --features "gcp-tdx,attest"Azure examples accept an optional nonce argument:
cargo run --example az_snp --features "az-snp,attest" -- "my-custom-nonce"GCP examples accept an optional nonce argument:
cargo run --example gcp_snp --features "gcp-snp,attest" -- "my-custom-nonce"
cargo run --example gcp_tdx --features "gcp-tdx,attest" -- "my-custom-nonce"A CLI binary is available for attestation and verification from the command line:
# Build the CLI
cargo build --release --features cli
# Generate evidence (on TEE hardware, Linux only)
cargo build --release --features "cli,attest"
./target/release/attestation-cli attest --report-data "my-nonce"
# Verify evidence (works anywhere)
echo "$EVIDENCE" | ./target/release/attestation-cli verify{
"attestation_report": "<base64-encoded 1184-byte SNP report>",
"cert_chain": {
"vcek": "<base64-encoded DER certificate>",
"ask": "<base64-encoded DER certificate, optional>",
"ark": "<base64-encoded DER certificate, optional>"
}
}{
"quote": "<base64-encoded TDX quote bytes>",
"cc_eventlog": "<base64-encoded CCEL eventlog, optional>"
}{
"version": 1,
"tpm_quote": {
"signature": "<hex-encoded RSA signature>",
"message": "<hex-encoded TPMS_ATTEST>",
"pcrs": ["<hex-encoded 32-byte PCR value>", "...(24 entries)"]
},
"hcl_report": "<url-safe-base64-encoded HCL report (2600 bytes)>",
"vcek": "<url-safe-base64-encoded DER certificate>"
}{
"version": 1,
"tpm_quote": {
"signature": "<hex-encoded RSA signature>",
"message": "<hex-encoded TPMS_ATTEST>",
"pcrs": ["<hex-encoded 32-byte PCR value>", "...(24 entries)"]
},
"hcl_report": "<url-safe-base64-encoded HCL report (2600 bytes)>",
"td_quote": "<url-safe-base64-encoded TD quote>"
}GCP SEV-SNP uses the same wire format as bare-metal SNP. The platform field in the evidence envelope is set to gcp-snp to distinguish it from bare-metal SNP evidence.
{
"attestation_report": "<base64-encoded 1184-byte SNP report>",
"cert_chain": {
"vcek": "<base64-encoded DER certificate>",
"ask": "<base64-encoded DER certificate, optional>",
"ark": "<base64-encoded DER certificate, optional>"
}
}GCP TDX uses the same wire format as bare-metal TDX. The platform field in the evidence envelope is set to gcp-tdx to distinguish it from bare-metal TDX evidence.
{
"quote": "<base64-encoded TDX quote bytes>",
"cc_eventlog": "<base64-encoded CCEL eventlog, optional>"
}{
"quote": "<base64-encoded TDX quote bytes>",
"event_log": "<JSON-encoded dstack event log, optional>",
"vm_config": "<VM configuration string, optional>"
}{
"signature_valid": true,
"platform": "snp",
"claims": {
"launch_digest": "<96-char hex string (48 bytes)>",
"report_data": "<128-char hex string (64 bytes)>",
"signed_data": "<hex-encoded bytes>",
"init_data": "<hex-encoded bytes>",
"tcb": {
"type": "Snp",
"bootloader": 3,
"tee": 0,
"snp": 8,
"microcode": 115
},
"platform_data": {
"policy": { "abi_major": 0, "debug_allowed": false, "..." : "..." },
"vmpl": 0,
"chip_id": "<128-char hex>"
}
},
"report_data_match": true,
"init_data_match": null
}# Unit tests (no hardware needed)
cargo test --features snp
cargo test --features tdx
cargo test --features az-snp
cargo test --features az-tdx
cargo test --features gcp-snp
cargo test --features gcp-tdx
cargo test --features dstack
# Integration tests on Azure SNP CVM
cargo test --test az_snp_live --features "az-snp,attest" -- --ignored
# Integration tests on Azure TDX CVM
cargo test --test az_tdx_live --features "az-tdx,attest" -- --ignored
# Benchmarks
cargo bench --features snp
cargo bench --features tdx
cargo bench --features az-snp
cargo bench --features az-tdx
cargo bench --features gcp-snp
cargo bench --features gcp-tdxThe library compiles to wasm32-unknown-unknown for verifier-only use:
cargo check --target wasm32-unknown-unknown --no-default-features --features snp,tdx,az-snp,az-tdx,gcp-snp,gcp-tdx,dstackThe attest feature is automatically excluded on WASM. All verification uses pure-Rust crypto (no OpenSSL dependency).
AMD root certificates (ARK + ASK) for Milan, Genoa, and Turin processors are embedded at compile time. Per-chip VCEK certificates are fetched on demand from AMD KDS or Azure IMDS.
Apache-2.0