id: b6f9dc86c1624d62bd2e9713dd9a2de3
parent_id: f0a971209ab84374a8fb753db8f1c927
item_type: 1
item_id: fa9e72ee12554f978a86ab3f7888cc63
item_updated_time: 1782804076518
title_diff: "[]"
body_diff: "[{\"diffs\":[[1,\"# Keyfob Station — SCP03 / KLMS Flow Reference\\\nID: fa9e72ee12554f978a86ab3f7888cc63\\\nNotebook ID: 283dd54f183a4ce69366648f091336d1\\\nCreated: 1782487881636\\\nUpdated: 1782802444698\\\nIs Todo: No\\\nTags: rust, scp03, nfc, ford, active-project\\\n\\\n---\\\n\\\n\"],[0,\"# Keyfob\"]],\"start1\":0,\"start2\":0,\"length1\":8,\"length2\":247},{\"diffs\":[[0,\"tion\"],[-1,\" (KLMS session-key offload)\"],[0,\"** e\"]],\"start1\":323,\"start2\":323,\"length1\":35,\"length2\":8},{\"diffs\":[[0,\"ent/data\"],[-1,\"\\\n>\"],[0,\" flow an\"]],\"start1\":332,\"start2\":332,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"security\"],[1,\"\\\n>\"],[0,\" rationa\"]],\"start1\":354,\"start2\":354,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"cts, and\"],[-1,\"\\\n>\"],[0,\" current\"]],\"start1\":412,\"start2\":412,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"atus see\"],[1,\"\\\n>\"],[0,\" **\\\"Ford\"]],\"start1\":431,\"start2\":431,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"CP03)\\\"**\"],[1,\"; for the full 5-actor\\\n> message tables + bundle/cache plane see **\\\"Keyfob Station — KLMS Data Contract\\\n> & E2E Sequence\\\"**\"],[0,\".\\\n\\\n## Mo\"]],\"start1\":484,\"start2\":484,\"length1\":16,\"length2\":139},{\"diffs\":[[0,\"on: KLMS\"],[1,\"-orchestrated,\"],[0,\" session\"]],\"start1\":638,\"start2\":638,\"length1\":16,\"length2\":30},{\"diffs\":[[0,\"Goal:** the \"],[1,\"**\"],[0,\"master key a\"]],\"start1\":684,\"start2\":684,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\"key \"],[-1,\"and per-fob static keys **never leave the KLMS HSM**.\\\nThe factory station is untrusted; it receive\"],[1,\"never comes near the factory floor.** It lives only in\\\nthe generation HSM (Ford/Clypeum). The factory side get\"],[0,\"s on\"]],\"start1\":705,\"start2\":705,\"length1\":106,\"length2\":118},{\"diffs\":[[0,\"sion\"],[-1,\" \"],[1,\"\\\n\"],[0,\"keys \"],[-1,\"plus\\\nthe already-encrypted personalization payload.\\\n\\\n**Why feasible:** every SCP03 step (KDF3 static derivation, Phase-2 session-key\\\nderivation, host/card cryptograms) is an AES-CMAC over data the station can\\\nsupply. An HSM holding the master key can compute the entire handshake and emit\\\nonly session keys.\\\n\\\n### Event & data flow\"],[1,\"+ pre-encrypted content.\\\n\\\n**Topology (revised):**\\\n- **Master key + KDF3 (Phase 1)** run at the **generation side**. Per-fob static\\\n  keys are packaged into **encrypted bundles**.\\\n- The **station-side HSM** (YubiHSM 2 / Nitrokey / Utimaco) does **AES primitives\\\n  only** (AES-CMAC/AES-CBC) and holds the **bundle-decryption private key\\\n  (generated inside it)**. It does NOT understand SCP03/KDF3.\\\n- The **KLMS orchestrates** Phase-2 (static→session) by calling the HSM per AES\\\n  op, and maintains a **cache of decrypted packages** (watchdog ≥2 weeks stock).\\\n\\\n### Async plane — bundle/cache (keeps stock warm, decoupled from the line)\\\n\\\n```\\\nGEN SIDE              STATION-SIDE HSM            KLMS (cache + watchdog)\\\n─────────────────────────────────────────────────────────────────────────\\\n (A0) export bundle-encryption pubkey  ◄───────── generated keypair; privkey never leaves\\\n encrypt bundle of N packages ─────────────────►  fetch / push\\\n                       decrypt bundle ────────►\\\n                                                  decrypt → key objects (HSM) + content → cache\\\n                                                  watchdog: stock < 2-wk? → request more\\\n```\\\n\\\n### Real-time plane — per fob\"],[0,\"\\\n\\\n``\"]],\"start1\":839,\"start2\":839,\"length1\":344,\"length2\":1221},{\"diffs\":[[0,\"MS (\"],[-1,\"+ HSM)\\\n\"],[1,\"orch)      Station-HSM (AES)\\\n─────────────────\"],[0,\"────\"]],\"start1\":2125,\"start2\":2125,\"length1\":15,\"length2\":54},{\"diffs\":[[0,\"────────────\"],[-1,\"─\"],[0,\"►\\\n    { uid,\"]],\"start1\":2529,\"start2\":2529,\"length1\":25,\"length2\":24},{\"diffs\":[[0,\"ptogram,\"],[-1,\"\\\n     \"],[0,\" fob_ide\"]],\"start1\":2631,\"start2\":2631,\"length1\":22,\"length2\":16},{\"diffs\":[[0,\"FESN\"],[-1,\" → fetch payload\"],[0,\") }\\\n\"]],\"start1\":2659,\"start2\":2659,\"length1\":24,\"length2\":8},{\"diffs\":[[0,\" 4. \"],[-1,\"HSM internal (master key sealed):\"],[1,\"cache lookup(uid) → static-key handles + content\"],[0,\"\\\n   \"]],\"start1\":2700,\"start2\":2700,\"length1\":41,\"length2\":56},{\"diffs\":[[0,\"    \"],[-1,\"   • KDF3(uid) → S-ENC,\"],[1,\"5. AE\"],[0,\"S-\"],[1,\"C\"],[0,\"MAC\"],[-1,\",S-DEK          (Phase 1)\"],[1,\"(s_mac, …)  ───────────────────────────►\\\n                                  6. ◄──────────────────────── expected card-cryptogram\"],[0,\"\\\n   \"]],\"start1\":2783,\"start2\":2783,\"length1\":61,\"length2\":147},{\"diffs\":[[0,\"        \"],[-1,\" •\"],[0,\" VERIFY \"]],\"start1\":2955,\"start2\":2955,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"    \"],[-1,\"   • session KDF(ctx=SeqCnt‖host_chal‖card_chal)\\\n                                         → SES-ENC, SES-MAC, SES-RMAC          (Phase 2)\\\n                                     •\"],[1,\"7. AES-CMAC(s_enc/s_mac, …) ×3  ───────────────► (session KDF, Phase 2)\\\n                                  8. ◄──────────────────────── SES-ENC/MAC/RMAC\\\n                                  9. AES-CMAC(s_mac, …)  ───────────────────────►\"],[0,\" host\"],[-1,\"_\"],[1,\" \"],[0,\"cryp\"]],\"start1\":3043,\"start2\":3043,\"length1\":190,\"length2\":247},{\"diffs\":[[0,\"gram\"],[-1,\" = cmac(SES-MAC, …)\"],[0,\"\\\n   \"]],\"start1\":3292,\"start2\":3292,\"length1\":27,\"length2\":8},{\"diffs\":[[0,\"    \"],[-1,\"    • A003_ciphertext   = AES-CBC(S-DEK, priv_key)\"],[1,\"10. AES-CBC(s_dek, A003_scalar)  ───────────────► pre-encrypt\"],[0,\"\\\n   \"]],\"start1\":3326,\"start2\":3326,\"length1\":58,\"length2\":69},{\"diffs\":[[0,\"─────── \"],[-1,\"5\"],[1,\"11\"],[0,\". respon\"]],\"start1\":3446,\"start2\":3446,\"length1\":17,\"length2\":18},{\"diffs\":[[0,\"es_rmac,\"],[-1,\"\\\n     \"],[0,\" host_cr\"]],\"start1\":3492,\"start2\":3492,\"length1\":22,\"length2\":16},{\"diffs\":[[0,\"n_id\"],[1,\", expires_at\"],[0,\" }\\\n\\\n\"],[-1,\" 6\"],[1,\"12\"],[0,\". EX\"]],\"start1\":3615,\"start2\":3615,\"length1\":14,\"length2\":26},{\"diffs\":[[0,\" open)\\\n\\\n\"],[-1,\" 7\"],[1,\"13\"],[0,\". STORE \"]],\"start1\":3786,\"start2\":3786,\"length1\":18,\"length2\":18},{\"diffs\":[[0,\"ES-MAC)\\\n\"],[-1,\" 8\"],[1,\"14\"],[0,\". Lifecy\"]],\"start1\":3860,\"start2\":3860,\"length1\":18,\"length2\":18},{\"diffs\":[[0,\"FACTORY\\\n\"],[-1,\" 9\"],[1,\"15\"],[0,\". Post-p\"]],\"start1\":3924,\"start2\":3924,\"length1\":18,\"length2\":18},{\"diffs\":[[0,\"─────►\\\n1\"],[-1,\"0\"],[1,\"6. result → KLMS ──► audit + retire cached package (consume)\\\n17\"],[0,\". DROP s\"]],\"start1\":3977,\"start2\":3977,\"length1\":17,\"length2\":79},{\"diffs\":[[0,\"ver \"],[-1,\"leav\"],[1,\"reach\"],[0,\"es the \"],[-1,\"HSM\"],[1,\"factory floor\"],[0,\"\\\n- \"],[1,\"**\"],[0,\"Mast\"]],\"start1\":4095,\"start2\":4095,\"length1\":25,\"length2\":38},{\"diffs\":[[0,\" key\"],[-1,\", S-ENC / S-MAC / S-DEK (static, long-lived), and the **p\"],[1,\"** — generation-side gen-HSM only (not in the station HSM, KLMS, or station).\\\n- **Per-fob static keys (S-ENC/MAC/DEK)** — held as HSM key objects on the\\\n  factory side; ideally never as plaintext in the KLMS.\\\n- **P\"],[0,\"lain\"]],\"start1\":4135,\"start2\":4135,\"length1\":65,\"length2\":222},{\"diffs\":[[0,\"text fob\"],[-1,\"\\\n \"],[0,\" private\"]],\"start1\":4357,\"start2\":4357,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\" key\"],[-1,\"**\"],[0,\" (A003\"],[-1,\" is\"],[1,\")** —\"],[0,\" pre\"]],\"start1\":4373,\"start2\":4373,\"length1\":19,\"length2\":19},{\"diffs\":[[0,\"ted \"],[-1,\"by the HSM)\"],[1,\"(AES-CBC under S-DEK) by\\\n  the HSM; the station only ever sees the ciphertext\"],[0,\".\\\n\\\n#\"]],\"start1\":4399,\"start2\":4399,\"length1\":19,\"length2\":85},{\"diffs\":[[0,\"ties\"],[-1,\" (vs. \\\"KLMS returns static keys\\\")\"],[0,\"\\\n- A\"]],\"start1\":4764,\"start2\":4764,\"length1\":41,\"length2\":8},{\"diffs\":[[0,\"ster key\"],[1,\", no\\\n  static keys\"],[0,\").\\\n- A l\"]],\"start1\":4837,\"start2\":4837,\"length1\":16,\"length2\":34},{\"diffs\":[[0,\" issued.\"],[1,\"\\\n- The **master key is never on the factory floor** — even a full factory\\\n  compromise (station + HSM + KLMS) exposes only the bundle-decryption key +\\\n  cached static keys, not the master key.\"],[0,\"\\\n\\\n### Im\"]],\"start1\":5118,\"start2\":5118,\"length1\":16,\"length2\":208},{\"diffs\":[[0,\"ented as\"],[1,\" (our boundary)\"],[0,\"\\\n- `Scp0\"]],\"start1\":5330,\"start2\":5330,\"length1\":16,\"length2\":31},{\"diffs\":[[0,\"mulates \"],[-1,\"the \"],[1,\"KLMS+\"],[0,\"HSM, ver\"]],\"start1\":5637,\"start2\":5637,\"length1\":20,\"length2\":21},{\"diffs\":[[0,\"togram).\"],[1,\"\\\n- The KLMS internals (cache, watchdog, HSM primitives, bundle decrypt) are\\\n  Clypeum's; our boundary is the Station↔KLMS contract.\"],[0,\"\\\n\\\n### Op\"]],\"start1\":5679,\"start2\":5679,\"length1\":16,\"length2\":147},{\"diffs\":[[0,\"S link.\\\n\"],[1,\"- [ ] **HSM product** (YubiHSM 2 / Nitrokey / Utimaco) for station-side primitives + bundle decrypt.\\\n- [ ] **Static-key placement**: HSM key objects (preferred) vs KLMS RAM.\\\n- [ ] **Bundle encryption scheme** (RSA-OAEP / ECIES / AES-KW) + push vs pull delivery.\\\n- [ ] **Does A003 plaintext reach the KLMS**, or is it encrypted inside the HSM during unwrap?\\\n- [ ] **2-week stock sizing** (line rate × hours × margin).\\\n\"],[0,\"- [ ] **\"]],\"start1\":5977,\"start2\":5977,\"length1\":16,\"length2\":433}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-30T07:27:45.654Z
created_time: 2026-06-30T07:27:45.654Z
type_: 13