id: c00ce466ea8844049235cbd77149f042
parent_id: 0bc9657eef7048b2ab2723a1b3e0239f
item_type: 1
item_id: 445891dba8674cae8b865a6fd2a3faf1
item_updated_time: 1782804033468
title_diff: "[]"
body_diff: "[{\"diffs\":[[1,\"# Ford EoL Key Fob Provisioning System (SCP03)\\\nID: 445891dba8674cae8b865a6fd2a3faf1\\\nNotebook ID: 283dd54f183a4ce69366648f091336d1\\\nCreated: 1780901497561\\\nUpdated: 1782802416305\\\nIs Todo: No\\\nTags: rust, scp03, nfc, ford, active-project\\\n\\\n---\\\n\\\n\"],[0,\"# Ford EoL K\"]],\"start1\":0,\"start2\":0,\"length1\":12,\"length2\":251},{\"diffs\":[[0,\"diagram)\"],[1,\", **\\\"Keyfob Station — KLMS Data Contract & E2E Sequence\\\"** (full\\\n> 5-actor contract + message tables for Enterprise Architect),\"],[0,\" and **\\\"\"]],\"start1\":912,\"start2\":912,\"length1\":16,\"length2\":143},{\"diffs\":[[0,\"), and **\\\"Keyfob\"],[1,\"\\\n>\"],[0,\" Station — Real \"]],\"start1\":1045,\"start2\":1045,\"length1\":32,\"length2\":34},{\"diffs\":[[0,\" Repo\\\"**\"],[-1,\"\\\n>\"],[0,\" (securi\"]],\"start1\":1103,\"start2\":1103,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"the KLMS\"],[-1,\" \"],[1,\"/\"],[0,\"HSM — th\"]],\"start1\":2123,\"start2\":2123,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"tes the \"],[1,\"KLMS+\"],[0,\"HSM with\"]],\"start1\":2442,\"start2\":2442,\"length1\":16,\"length2\":21},{\"diffs\":[[0,\" the\"],[1,\"\\\n \"],[0,\" dev\"],[-1,\"\\\n \"],[0,\" key\"]],\"start1\":2463,\"start2\":2463,\"length1\":14,\"length2\":14},{\"diffs\":[[0,\"m` (\"],[-1,\"Nitrokey local\"],[1,\"dev SW\"],[0,\" KDF\"]],\"start1\":2512,\"start2\":2512,\"length1\":22,\"length2\":14},{\"diffs\":[[0,\"**. \"],[-1,\"Remains available for a future local-HSM option; the\\\n  production master key belongs on the KLMS server HSM\"],[1,\"Models the **dev** SW-KDF path (master→static via on-device\\\n  AES-CMAC). The **production** station-side HSM primitive/bundle-decrypt\\\n  backend is KLMS-side (Clypeum), not in our binaries.\\\n\\\n---\\\n\\\n## Production Topology (5 actors)\\\n\\\nThe production design separates **key generation** from **key use** so the master\\\nkey never comes near the factory floor.\\\n\\\n| Actor | Holds long-term | Does |\\\n|---|---|---|\\\n| **Ford / Clypeum gen side** | **master key** (in gen-HSM) | KDF3 per-fob → static keys; packages + encrypts key **bundles** to the station-HSM pubkey; audit DB |\\\n| **KLMS** (Clypeum) | decrypted-package cache (2-wk stock) | **orchestrates** SCP03 Phase-2 via HSM primitives; bundle cache + watchdog; returns session keys + content |\\\n| **Station-side HSM** (YubiHSM 2 / Nitrokey / Utimaco) | **bundle-decryption private key (generated inside it)** | **AES primitives only** (AES-CMAC/AES-CBC) + bundle decrypt; does NOT understand SCP03/KDF3 |\\\n| **Station** | nothing | PC/SC to fob; forwards handshake to KLMS; consumes session keys |\\\n| **Key Fob** | per-fob static keys (factory-loaded) | NCJ37x being provisioned |\\\n\\\n**Two operational planes:**\\\n- **(A) Async bundle/cache** — gen side ships encrypted key bundles → station-side\\\n  HSM decrypts → KLMS caches decrypted packages. A watchdog keeps ≥ **2 weeks of\\\n  production** in stock, decoupling the line from gen-side latency.\\\n- **(B) Real-time per fob** — KLMS pulls the fob's package from cache, orchestrates\\\n  Phase-2 (static→session) calling the HSM for every AES op, returns session keys +\\\n  pre-encrypted content to the station.\\\n\\\nSee **\\\"KLMS Data Contract & E2E Sequence\\\"** for the full message tables + EA diagram.\\\n\\\n### Key Design Decision: master key stays at the generation side\\\n\\\nThe architecture evolved from a local Nitrokey KDF, to KLMS-HSM session-key\\\noffload, to the current split:\\\n\\\n- **Master key is never on the factory side.** It lives only in the generation\\\n  HSM (Ford/Clypeum). KDF3 (Phase 1, master+UID → S-ENC/MAC/DEK) runs there; the\\\n  resulting per-fob static keys are **packaged into encrypted bundles**.\\\n- **The station-side HSM does AES primitives only** — it cannot run SCP03. It\\\n  holds the **bundle-decryption private key (generated inside it)** and performs\\\n  `AES-CMAC` / `AES-CBC` on demand. The **KLMS orchestrates** the Phase-2\\\n  derivation, building each derivation-data block and calling the HSM.\\\n- **The KLMS is the orchestration + cache tier.** It fetches bundles, has the\\\n  HSM decrypt them, caches decrypted packages (watchdog-maintained), and at\\\n  provisioning time runs Phase-2 + card-cryptogram verification + A003 encryption\\\n  — all via HSM primitives — emitting only ephemeral session keys.\\\n\\\n> Net: master key → gen side only; per-fob static keys → HSM key objects on the\\\n> factory side; session keys → station (RAM-only, zeroized). The station\\\n> boundary (`KlmsClient` request/response) is unchanged by this revision\"],[0,\".\\\n\\\n-\"]],\"start1\":2617,\"start2\":2617,\"length1\":115,\"length2\":2926},{\"diffs\":[[0,\"30, rev \"],[-1,\"5\"],[1,\"6\"],[0,\")\\\n\\\nAn 11\"]],\"start1\":5581,\"start2\":5581,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"ent`** (\"],[1,\"KLMS+\"],[0,\"HSM emul\"]],\"start1\":6742,\"start2\":6742,\"length1\":16,\"length2\":21},{\"diffs\":[[0,\" runtime\"],[1,\" (dev model)\"],[0,\".** | ✅ \"]],\"start1\":7081,\"start2\":7081,\"length1\":16,\"length2\":28},{\"diffs\":[[0,\"etails.\\\n\"],[1,\"- **KLMS internals (bundle cache, watchdog, station-side HSM primitives, bundle\\\n  decrypt)** — Clypeum's responsibility; our boundary is the\\\n  Station↔KLMS contract only.\\\n\"],[0,\"- **Real\"]],\"start1\":8095,\"start2\":8095,\"length1\":16,\"length2\":187},{\"diffs\":[[0,\"ples.\\\n4.\"],[1,\" **HSM product + bundle/cache design** — confirm YubiHSM 2 / Nitrokey / Utimaco;\\\n      bundle crypto + push/pull; 2-week stock sizing (see Data Contract note §7).\\\n5.\"],[0,\" **Key V\"]],\"start1\":8880,\"start2\":8880,\"length1\":16,\"length2\":181},{\"diffs\":[[0,\"re d\"],[-1,\"er\"],[0,\"ive\"],[-1,\"d inside the KLMS HSM\\\n>\"],[1,\"rsified at the generation\\\n> side\"],[0,\" and\"]],\"start1\":10351,\"start2\":10351,\"length1\":36,\"length2\":43},{\"diffs\":[[0,\"ach the \"],[-1,\"application\"],[1,\"factory floor\"],[0,\".\\\n\\\n### D\"]],\"start1\":10403,\"start2\":10403,\"length1\":27,\"length2\":29},{\"diffs\":[[0,\"LMS \"],[-1,\"derives session keys + host cryptogram **and**\"],[1,\"looks up the cached package, orchestrates Phase-2 via station-side HSM\\\n   AES primitives,\"],[0,\" pre\"]],\"start1\":13956,\"start2\":13956,\"length1\":54,\"length2\":97},{\"diffs\":[[0,\"on: \"],[-1,\"KLMS Performs the Full Handshake (session-key offload)\"],[1,\"master key at the generation side\"],[0,\"\\\n\\\nTh\"]],\"start1\":14441,\"start2\":14441,\"length1\":62,\"length2\":41},{\"diffs\":[[0,\"ion \"],[-1,\"to having\\\nthe **Clypeum KLMS server perform the entire SCP03 handshake**. The EoL station\\\nis an untrusted factory-floor environment; the **master key and static keys\"],[1,\"→ KLMS-HSM\\\nsession-key offload → the current **generation-side / factory-side split**:\\\n\\\n- The **master key\"],[0,\" never\"],[-1,\"\\\n\"],[1,\" \"],[0,\"leave\"],[1,\"s\"],[0,\" the \"],[-1,\"KLMS HSM**. The KLMS:\\\n\\\n**Phase 1 (NXP KDF3)** — inside the HSM:\\\n- M\"],[1,\"generation HSM** (Ford/Clypeum). KDF3 (Phase 1,\\\n  m\"],[0,\"aster\"],[-1,\" Key\"],[1,\"+UID\"],[0,\" → S-ENC\"],[-1,\", S-MAC, S-DEK using AES-CMAC\\\n- P\"],[1,\"/MAC/DEK, p\"],[0,\"urpo\"]],\"start1\":14546,\"start2\":14546,\"length1\":307,\"length2\":211},{\"diffs\":[[0,\"ytes\"],[-1,\": `\"],[1,\" \"],[0,\"0x40\"],[-1,\"` (ENC), `0x60` (MAC), `0x70` (DEK); context: raw 10-byte JCOP UID\\\n- Key length: `0080` (128-bit)\\\n\\\n**Phase 2 (GP SCP03)** — inside the HSM:\\\n- Static keys → Session keys (SES-ENC, SES-MAC, SES-RMAC)\\\n- Context: `SeqCnt(3) || RND.IC(8) || RND.CC(8)`\\\n- + host cryptogram + card-cryptogram verification (KLMS authenticates the card)\\\n\\\nThe KLMS returns only the **ephemeral session keys** (held in RAM, zeroized on\\\ndrop) and the pre-encrypted content\"],[1,\"/0x60/0x70, raw 10-byte UID) runs\\\n  there; per-fob static 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) and all AES work, fetching +\\\n  decrypting bundles (via the HSM) and caching decrypted packages behind a\\\n  watchdog (≥2 weeks of stock).\\\n\\\n**Net:** master key → gen side only; per-fob static keys → factory-side HSM key\\\nobjects; session keys → station (ephemeral, zeroized). The Station↔KLMS boundary\\\nis unchanged\"],[0,\".\\\n\\\n-\"]],\"start1\":14761,\"start2\":14761,\"length1\":458,\"length2\":694},{\"diffs\":[[0,\"the KLMS\"],[-1,\";\"],[1,\" (Phase 2 only — Phase 1 ran at the gen side);\\\n \"],[0,\" the app\"]],\"start1\":16070,\"start2\":16070,\"length1\":17,\"length2\":64},{\"diffs\":[[0,\"m\\\")\\\n\"],[-1,\"Stores master keys; performs full KDF (Phase 1+2)\"],[1,\"Orchestrates Phase-2; fetches + decrypts key bundles via the station-side HSM;\\\ncaches decrypted packages behind a watchdog\"],[0,\"; de\"]],\"start1\":18194,\"start2\":18194,\"length1\":57,\"length2\":130},{\"diffs\":[[0,\"n keys +\"],[-1,\"\\\n\"],[1,\" \"],[0,\"pre-encr\"]],\"start1\":18337,\"start2\":18337,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"pted\"],[-1,\" \"],[1,\"\\\n\"],[0,\"payload.\"],[1,\" Master key lives on the generation side, not the KLMS.\"],[0,\"\\\n\\\n--\"]],\"start1\":18355,\"start2\":18355,\"length1\":17,\"length2\":72},{\"diffs\":[[0,\"|\\\n| \"],[-1,\"KLMS | SecOps (Clypeum) | Stores master keys, performs full KDF (Phase 1+2), delivers session keys + pre-encrypted payload\"],[1,\"Gen side | Ford/Clypeum | Holds master key (gen-HSM); KDF3 (Phase 1); packages + encrypts key bundles |\\\n| KLMS | SecOps (Clypeum) | Orchestrates Phase-2 via station-side HSM primitives; bundle cache + watchdog; delivers session keys + pre-encrypted payload |\\\n| Station-side HSM | (YubiHSM2/Nitrokey/Utimaco) | AES primitives only; holds bundle-decryption key (generated inside)\"],[0,\" |\\\n|\"]],\"start1\":19167,\"start2\":19167,\"length1\":130,\"length2\":385},{\"diffs\":[[0,\"r` test.\"],[1,\" Runs at the generation side in production; in software in `kf-dev-station`.\"],[0,\"\\\n\\\n### Se\"]],\"start1\":20192,\"start2\":20192,\"length1\":16,\"length2\":92},{\"diffs\":[[0,\" feature\"],[1,\", dev model\"],[0,\") |\\\n\\\n---\"]],\"start1\":21143,\"start2\":21143,\"length1\":16,\"length2\":27},{\"diffs\":[[0,\"ilities\\\n\"],[1,\"- [ ] **HSM product** (YubiHSM 2 / Nitrokey / Utimaco) for station-side primitives + bundle decrypt\\\n- [ ] **Bundle encryption scheme** (RSA-OAEP / ECIES / AES-KW) + push vs pull delivery\\\n- [ ] **Static-key placement** (HSM key objects vs KLMS RAM) + whether A003 plaintext reaches the KLMS\\\n- [ ] **2-week stock sizing** (line rate × hours × margin)\\\n\"],[0,\"- [x] ~~\"]],\"start1\":22392,\"start2\":22392,\"length1\":16,\"length2\":365},{\"diffs\":[[0,\"rev \"],[-1,\"5: added NXP contacts (Thomas Denner, Florian Mikulik, Daniel Rinner), consolidated companion notes, folded review follow-ups into \\\"Deferred to Real-Card\\\"\"],[1,\"6: revised production topology — master key now stays at the generation side; station-side HSM (YubiHSM2/Nitrokey/Utimaco) does AES primitives + bundle decryption only; KLMS orchestrates Phase-2 from a watchdog-maintained cache of decrypted packages (≥2 weeks stock)\"],[0,\". 86\"]],\"start1\":23010,\"start2\":23010,\"length1\":162,\"length2\":274}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-30T07:27:45.468Z
created_time: 2026-06-30T07:27:45.468Z
type_: 13