Lab 02 — Secure/Measured Boot + Attestation

Phase: 09 — Networking & Tenancy | Difficulty: ⭐⭐⭐⭐☆ | Time: 4–6 hours Language: Python 3 (stdlib) | Hardware: none (swtpm/tpm2-tools for the real extension)

Concept primer: ../WARMUP.md Ch. 5–7, ../HITCHHIKERS-GUIDE.md §4–§6.

Run

python3 solution.py     # trusted boot+attest OK; tampered boot stopped / detected

Run it for REAL with swtpm + tpm2-tools (the extension — verified)

attestation_flow.sh reproduces the same measured-boot + attestation flow with a real software TPM (swtpm) and real tpm2-tools. TPM tooling is Linux-only, so run-in-docker.sh runs it in a Linux container (needs Docker) — works on macOS/Windows hosts too:

./run-in-docker.sh        # or, on Linux: apt install swtpm tpm2-tools && ./attestation_flow.sh

It: starts swtpm → tpm2_pcrextends shim/grub/kernel into a PCR (measured boot) → creates an AK and tpm2_quote/tpm2_checkquote (real signed attestation) → extends a tampered kernel into another PCR and shows the value differs (attestation would reject). Verified output:

golden PCR23 = 0x48078734A5098E041B9FE97CF18C6158D3E41166C52BD316569997182B5BD213
checkquote: PASS  (genuine TPM signed the PCRs, nonce matched) -> ATTESTED
tampered PCR16 = 0x7837FDDA35A019DAD51C1E6CF6923D982C07578D915CFAAEDDE2CD8EF524ED5B
PCR mismatch (golden != tampered) -> attestation REJECTS the tampered node ✅

This is the simulator's logic (solution.py) on real TPM hardware-emulation — the same PCR-extend chain, AK quote, and known-good comparison. (Two real-TPM gotchas you'll hit and that the script handles: swtpm's small transient-object pool needs tpm2_flushcontext -t before the quote, and PCRs 22/23 have locality restrictions so the tamper demo uses the locality-0 debug PCR 16.)

0. The mission

Build the chain of trust that lets you know and prove a node booted approved software: secure boot (enforce signatures), measured boot (extend hashes into a TPM PCR), and remote attestation (a signed PCR quote a verifier checks against known-good before trusting the node).

1. The three behaviors

  1. Trusted node: signatures verify, PCR matches the golden value, attestation → trust.
  2. Tampered kernel, Secure Boot ON: the signature check stops the boot (enforce).
  3. Tampered kernel, Secure Boot OFF: it boots anyway, but the PCR mismatches and attestation refuses — measured boot + attestation catch what enforcement missed. This is the key insight: enforce and prove, because you can't always enforce everywhere.

Plus: replay protection (unknown nonce rejected) and forged-quote rejection (wrong AK).

2. Why attestation gates trust

A node only earns tenant workloads/keys by proving a known-good boot state. In multi-tenant or sovereign/air-gapped deployments (Phase 06 RKE2), you can't assume trust — compromised firmware could exfiltrate tenant data. Attestation makes trust provable and gateable, a natural addition to the Phase 05 provisioning gate and Phase 06 node-join.

3. Extensions (real TPM)

  1. Use swtpm (software TPM) + tpm2-tools: tpm2_pcrextend, tpm2_quote, tpm2_checkquote — reproduce the flow on a real TPM stack.
  2. Seal a secret to a PCR state (tpm2_create/tpm2_unseal) so a disk-encryption key only releases on a known-good boot.
  3. Integrate attestation as a Phase 05 provisioning gate / Phase 06 node-join check.
  4. Model dbx revocation: revoke a now-vulnerable bootloader and show it's refused.

4. What this lab proves

You understand the full trust chain — secure boot (enforce), measured boot (record), attestation (prove) — and can explain the crucial secure-vs-measured distinction and why attestation gates trust. "Ensure secure boot for multi-tenant environments" (the JD) becomes a working chain you can defend in a security review. Feeds system-design/04 and the sovereign-deployment story.