CCSI

Lesson 3.2 · 15 min read

Appraisal, freshness and binding

What a verifier must check, why nonces matter, and how to bind a key to evidence.

What a verifier must check

Appraising evidence is more than checking a signature. A sound verifier performs every one of the following, and an auditor should be able to see each step in code or configuration:

  1. Signature and chain. The evidence is signed by a key that chains to the hardware vendor's root (for example AMD ARK, Intel's SGX/TDX root CA, or the AWS Nitro root). Certificates are valid and not revoked.
  2. Platform TCB. Firmware and microcode security versions meet the current minimum. After a vendor TCB recovery, older versions should be rejected after a grace period you define.
  3. Debug and policy flags. Debug mode is off. A debuggable TEE offers no confidentiality.
  4. Measurements. Launch and runtime measurements match approved reference values.
  5. Freshness. The evidence contains the verifier's nonce, or is otherwise provably recent, so an old report cannot be replayed.
  6. Binding. The caller-bound data (REPORTDATA, REPORT_DATA, user_data or public_key) commits to the key or TLS channel that will be used next.

Freshness

RFC 9334 describes three ways to establish freshness: a nonce supplied by the verifier and included in the evidence; timestamps with sufficiently synchronised clocks; and epoch IDs distributed by an epoch bell. Nonces are the most common in confidential computing.

python
import hashlib, os

# Verifier side: issue a fresh nonce for each attestation
nonce = os.urandom(32)

# Attester side (inside the TEE): generate an ephemeral key pair, then
# request evidence whose 64-byte caller data commits to key and nonce
report_data = hashlib.sha512(public_key_bytes + nonce).digest()   # 64 bytes
evidence = get_attestation_report(report_data)                    # platform API

# Verifier side: after checking signature, TCB, debug, measurements...
assert evidence.report_data == hashlib.sha512(public_key_bytes + nonce).digest()
# ...only now encrypt secrets to public_key_bytes
Illustrative pseudocode for binding a key and nonce into evidence

Key takeaways

  • Signature, TCB, debug, measurements, freshness and binding: all six, every time.
  • A nonce in the evidence prevents replay; a bound public key prevents relay.
  • Treat a debug-enabled TEE as untrusted regardless of its measurements.