diff --git a/docs/TODO.md b/docs/TODO.md index c6c01ba..b5291c9 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1006,7 +1006,7 @@ reasonable for a controlled fleet; the highest-assurance path is attended/firmwa or manufacturer pre-provisioning. Default recommendation: **separate provisioning UKI + isolated VLAN + read-back verify.** -## [ ] 11. (DESIGN) TPM 802.1X identity enrolment (TOFU + OOB fingerprint) +## [~] 11. (DESIGN) TPM 802.1X identity enrolment (TOFU + OOB fingerprint) **Authoritative design consolidated 2026-06-28: [tpm-enrolment-design.md](tpm-enrolment-design.md)** — unifies this item with the @@ -1031,7 +1031,9 @@ approve → cert). **BENCH-VERIFY:** run against real step-ca (`bootstrap.sh` ro `enrol` provisioner password readable by the broker) and confirm an issued cert authenticates EAP-TLS. -**HOST SIDE BUILT 2026-07-02 — Go binary (`fleet-enrol`), awaiting bench.** +**HOST SIDE BUILT 2026-07-02 — Go binary (`fleet-enrol`); TEST-PATH ENROLMENT +BENCH-VERIFIED ON REAL HARDWARE (Dell 820, `rd.dot1x=0`, 2026-07-03).** Secure-path +(802.1X/MACsec) enrolment still to verify — see the NV-index bench finding below. Pivoted from a shell hook to a static **Go + go-tpm** binary (`files/enrol/`): it talks to `/dev/tpmrm0` DIRECTLY (via `transport.FromReadWriter` on an `os.File` — no `linuxtpm`, so go-tpm is the only vendored dep), so the enrolment @@ -1126,7 +1128,7 @@ have their EK there), so enrolment could never create our key. (+ `tpm2_evictcontrol -C o -c 0x81000100` for a stale *app* key — never the EK), or BIOS "Clear TPM". Document in the bench README. -**BENCH FINDING 2026-07-03 (FIXED) — NV index `0x01800001` collided with OEM +**BENCH FINDING 2026-07-03 (FIXED + BENCH-VERIFIED) — NV index `0x01800001` collided with OEM platform NV; moved to `0x01800100`.** The Dell 820 kept "finding a cert" and bypassing enrolment even after repeated BIOS TPM clears. `tpm2_nvreadpublic` showed the truth: `0x01800001` on that hardware is a **firmware/platform** index @@ -1142,9 +1144,18 @@ through the cmdline (`extract-artifacts.sh`), `fleet-enrol -nvindex`, the dracut hooks, bench scripts, invariant #1, and docs. Also **hardened `WriteNVCert`** to refuse a `platformcreate` index with a clear "pick a free owner index" error instead of a confusing undefine failure (regression `simtest/ -TestWriteNVCertRefusesPlatformIndex`). **BENCH-VERIFY:** 820 now enrols at -`0x01800100`; and check `tpm2_nvreadpublic` on any OTHER hardware model in the -fleet — if a vendor also squats `0x018001xx`, pick a value free on all of them. +TestWriteNVCertRefusesPlatformIndex`). **BENCH-VERIFIED 2026-07-03 — the Dell 820 +enrols end-to-end at `0x01800100`.** First success on REAL TPM hardware (past the +un-clearable OEM platform-NV at `0x01800001`): validates BOTH the NV-index move +AND the `0x81000100` key-handle move on a physical TPM, not just the Proxmox +swtpm — the full host ceremony (ensure ECDSA key → CSR → broker fingerprint → +approve → leaf cert → NV write) runs on the metal. This was the hard case (the +820 previously "found a cert" and silently bypassed enrolment every boot). **STILL +BENCH-VERIFY:** (a) `tpm2_nvreadpublic` on any OTHER hardware model in the fleet — +if a vendor also squats `0x018001xx`, pick a value free on all of them; (b) the +enrolled cert actually **authenticates EAP-TLS on the secure path** (this run was +test-mode `rd.dot1x=0`; 802.1X/MACsec enrolment still unverified — see the +test-mode note above). **BENCH-VERIFY (host side, before trusting):** (a) go-tpm against a REAL TPM + swtpm on the target (the simulator proves the ceremony, not the device) — **the