id: f0a971209ab84374a8fb753db8f1c927
parent_id: f494e13a8b2e4169ba24bfdd6ff69b1f
item_type: 1
item_id: fa9e72ee12554f978a86ab3f7888cc63
item_updated_time: 1782802444698
title_diff: "[{\"diffs\":[[0,\"n — \"],[-1,\"Operating Modes & KLMS Session-Key Offload\"],[1,\"SCP03 / KLMS Flow Reference\"]],\"start1\":13,\"start2\":13,\"length1\":46,\"length2\":31}]"
body_diff: "[{\"diffs\":[[0,\"n — \"],[-1,\"Operating Modes & KLMS Session-Key Offload\\\n\\\n> **Status:** ✅ **Implemented (2026-06-26, rev 4).** The two modes are now two\\\n> binaries — `kf-dev-station` (Mode B + C) and `kf-prod-station` (Mode A) — plus\\\n> the `kf-klms` crate (`KlmsClient` + `MockKlmsClient`), `KlmsProvisioner`, and\\\n> `Scp03Channel::establish_from_session_keys`. 86 tests green.\\\n> See companion note **\\\"Keyfob Station — Two-Binary Split (dev vs production)\\\"**.\\\n> The original design below is retained for reference.\\\n\\\n---\\\n\\\n## 1. Three operating modes\\\n\\\nThe station supports three modes. Provisioning splits into two **key-source strategies**; firmware flashing is independent.\\\n\\\n| Mode | Master / static keys location | Station holds | Use case | Binary |\\\n|---|---|---|---|---|\\\n| **A — Production provisioning (KLMS session-key offload)** | KLMS enterprise HSM (master key never leaves) | **Only ephemeral session keys** for the active channel | Factory floor (untrusted station) | `kf-prod-station` |\\\n| **B — Development provisioning (static keys inline)** | Known dev key set on the station | Static keys (S-ENC/MAC/DEK) in RAM for the run | Lab bring-up, protocol validation, dev samples (OEF B212) | `kf-dev-station` |\\\n| **C — Firmware flashing (SEMS Lite)** | N/A (load-file playback, not SCP03 personalization) | Script + APDU stream | (Re)flash secure-element firmware before/instead of provisioning | `kf-dev-station` |\\\n\\\n### GUI mapping\\\n- `kf-dev-station` top-level switch: **Provisioning** ↔ **Firmware Flashing**.\\\n- `kf-prod-station`: **Provisioning only** (no flashing selector).\\\n\\\n---\\\n\\\n## 2.\"],[1,\"SCP03 / KLMS Flow Reference\\\n\\\n> Focused reference for the **production (KLMS session-key offload)** event/data\\\n> flow and the security rationale. For the architecture overview, contacts, and\\\n> current status see **\\\"Ford EoL Key Fob Provisioning System (SCP03)\\\"**.\\\n\\\n##\"],[0,\" Mod\"]],\"start1\":15,\"start2\":15,\"length1\":1575,\"length2\":274},{\"diffs\":[[0,\"ad\\\n\\\n\"],[-1,\"### 2.1 Goal\\\nT\"],[1,\"**Goal:** t\"],[0,\"he \"],[-1,\"**\"],[0,\"mast\"]],\"start1\":329,\"start2\":329,\"length1\":27,\"length2\":22},{\"diffs\":[[0,\"key and \"],[-1,\"the \"],[0,\"per-fob \"]],\"start1\":354,\"start2\":354,\"length1\":20,\"length2\":16},{\"diffs\":[[0,\"ic keys \"],[1,\"**\"],[0,\"never le\"]],\"start1\":374,\"start2\":374,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\" HSM\"],[-1,\".\"],[0,\"**\"],[-1,\" \"],[1,\".\\\n\"],[0,\"The \"]],\"start1\":404,\"start2\":404,\"length1\":12,\"length2\":12},{\"diffs\":[[0,\" is \"],[-1,\"treated as \"],[0,\"untr\"]],\"start1\":431,\"start2\":431,\"length1\":19,\"length2\":8},{\"diffs\":[[0,\"ntrusted\"],[-1,\" and\"],[1,\"; it\"],[0,\" receive\"]],\"start1\":436,\"start2\":436,\"length1\":20,\"length2\":20},{\"diffs\":[[0,\"eys plus\"],[-1,\" \"],[1,\"\\\n\"],[0,\"the alre\"]],\"start1\":482,\"start2\":482,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"d.\\\n\\\n\"],[-1,\"### 2.2 Why this is safe &\"],[1,\"**Why\"],[0,\" fea\"]],\"start1\":535,\"start2\":535,\"length1\":34,\"length2\":13},{\"diffs\":[[0,\"ible\"],[-1,\"\\\nE\"],[1,\":** e\"],[0,\"very\"]],\"start1\":549,\"start2\":549,\"length1\":10,\"length2\":13},{\"diffs\":[[0,\"P03 \"],[-1,\"operation\"],[1,\"step\"],[0,\" (KD\"]],\"start1\":565,\"start2\":565,\"length1\":17,\"length2\":12},{\"diffs\":[[0,\"sion-key\"],[-1,\" \"],[1,\"\\\n\"],[0,\"derivati\"]],\"start1\":610,\"start2\":610,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"tion can\"],[-1,\" \"],[1,\"\\\n\"],[0,\"supply. \"]],\"start1\":686,\"start2\":686,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"HSM \"],[-1,\"that \"],[0,\"hold\"],[-1,\"s\"],[1,\"ing\"],[0,\" the\"]],\"start1\":706,\"start2\":706,\"length1\":18,\"length2\":15},{\"diffs\":[[0,\"key \"],[-1,\"and performs AES-CMAC on-device \"],[0,\"can \"]],\"start1\":729,\"start2\":729,\"length1\":40,\"length2\":8},{\"diffs\":[[0,\"the \"],[-1,\"**\"],[0,\"entire\"],[-1,\"**\"],[0,\" han\"]],\"start1\":745,\"start2\":745,\"length1\":18,\"length2\":14},{\"diffs\":[[0,\"ake \"],[-1,\"internally \"],[0,\"and emit\"],[-1,\" \"],[1,\"\\\n\"],[0,\"only\"]],\"start1\":762,\"start2\":762,\"length1\":28,\"length2\":17},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.3\"],[0,\" Eve\"]],\"start1\":794,\"start2\":794,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.4\"],[0,\" Wha\"]],\"start1\":2610,\"start2\":2610,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"text fob\"],[1,\"\\\n \"],[0,\" private\"]],\"start1\":2714,\"start2\":2714,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.5\"],[0,\" Wha\"]],\"start1\":2775,\"start2\":2775,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"terminal\"],[1,\"\\\n \"],[0,\" must C-\"]],\"start1\":2903,\"start2\":2903,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"table by the\"],[1,\"\\\n \"],[0,\" station).\\\n\\\n\"]],\"start1\":3012,\"start2\":3012,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.6\"],[0,\" Sec\"]],\"start1\":3037,\"start2\":3037,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"ies \"],[-1,\"gained over\"],[1,\"(vs.\"],[0,\" \\\"KL\"]],\"start1\":3058,\"start2\":3058,\"length1\":19,\"length2\":12},{\"diffs\":[[0,\"ic keys\\\"\"],[1,\")\"],[0,\"\\\n- A com\"]],\"start1\":3085,\"start2\":3085,\"length1\":16,\"length2\":17},{\"diffs\":[[0,\"n**, not the\"],[1,\"\\\n \"],[0,\" fob for lif\"]],\"start1\":3240,\"start2\":3240,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\"ue/blank\"],[1,\"\\\n \"],[0,\" fob pre\"]],\"start1\":3343,\"start2\":3343,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"n't \"],[-1,\"actually \"],[0,\"hold\"]],\"start1\":3382,\"start2\":3382,\"length1\":17,\"length2\":8},{\"diffs\":[[0,\"ore \"],[-1,\"any \"],[0,\"sess\"]],\"start1\":3406,\"start2\":3406,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.7\"],[0,\" Imp\"]],\"start1\":3435,\"start2\":3435,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"ted \"],[-1,\"in the codeb\"],[0,\"as\"],[-1,\"e\"],[0,\"\\\n- \"],[-1,\"**\"],[0,\"`Scp\"]],\"start1\":3448,\"start2\":3448,\"length1\":28,\"length2\":13},{\"diffs\":[[0,\"on_keys`\"],[-1,\"**\"],[0,\" — injec\"]],\"start1\":3492,\"start2\":3492,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"ion keys\"],[1,\"\\\n \"],[0,\" (no sta\"]],\"start1\":3526,\"start2\":3526,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"keys\"],[-1,\", no card-cryptogram check; the\"],[1,\";\"],[0,\" KLM\"]],\"start1\":3548,\"start2\":3548,\"length1\":39,\"length2\":9},{\"diffs\":[[0,\"ard).\\\n- \"],[-1,\"**\"],[0,\"`KlmsPro\"]],\"start1\":3578,\"start2\":3578,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"isioner`\"],[-1,\"**\"],[0,\" (`kf-pr\"]],\"start1\":3595,\"start2\":3595,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"`) —\"],[-1,\" production pipeline;\"],[0,\" rej\"]],\"start1\":3630,\"start2\":3630,\"length1\":29,\"length2\":8},{\"diffs\":[[0,\" flagged\"],[1,\"\\\n \"],[0,\" `encryp\"]],\"start1\":3648,\"start2\":3648,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"rue`.\\\n- \"],[-1,\"**\"],[0,\"`kf-klms\"]],\"start1\":3678,\"start2\":3678,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"kf-klms`\"],[-1,\"**\"],[0,\" — `Klms\"]],\"start1\":3687,\"start2\":3687,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"it +\"],[-1,\" `SessionRequest/Response/Content` +\"],[0,\" `Mo\"]],\"start1\":3714,\"start2\":3714,\"length1\":44,\"length2\":8},{\"diffs\":[[0,\"verifies\"],[1,\"\\\n  the\"],[0,\" card cr\"]],\"start1\":3755,\"start2\":3755,\"length1\":16,\"length2\":22},{\"diffs\":[[0,\"\\\n###\"],[-1,\" 2.8\"],[0,\" Ope\"]],\"start1\":3788,\"start2\":3788,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"\\\n---\\\n\\\n##\"],[-1,\" 3.\"],[0,\" Mode B \"]],\"start1\":4239,\"start2\":4239,\"length1\":19,\"length2\":16},{\"diffs\":[[0,\"line\"],[-1,\"\\\n\\\n- **\"],[1,\" (summary)\\\n\\\n\"],[0,\"Dev \"]],\"start1\":4284,\"start2\":4284,\"length1\":14,\"length2\":20},{\"diffs\":[[0,\" samples\"],[-1,\"**\"],[0,\" (OEF B2\"]],\"start1\":4303,\"start2\":4303,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"h a \"],[-1,\"**pre-defined\"],[1,\"known\"],[0,\" sta\"]],\"start1\":4331,\"start2\":4331,\"length1\":21,\"length2\":13},{\"diffs\":[[0,\" set\"],[-1,\"** already loaded — no KLMS, no diversification:\"],[1,\" →\"],[0,\" Pha\"]],\"start1\":4357,\"start2\":4357,\"length1\":56,\"length2\":10},{\"diffs\":[[0,\"nly,\"],[-1,\" \"],[1,\"\\\n\"],[0,\"locally\"],[-1,\".\\\n- The **KDF/diversification path** (Phase 1)\"],[1,\", via `kf-dev-station`. The Phase-1 KDF\"],[0,\" can\"]],\"start1\":4373,\"start2\":4373,\"length1\":62,\"length2\":55},{\"diffs\":[[0,\"sed \"],[-1,\"in dev using\"],[1,\"with\"],[0,\" the dev\"],[-1,\" \"],[1,\"\\\n\"],[0,\"mast\"]],\"start1\":4443,\"start2\":4443,\"length1\":29,\"length2\":21},{\"diffs\":[[0,\"lly.\"],[-1,\"\\\n- This is what `kf-dev-station` does today against the simulated JCOP applet.\\\n\\\n---\\\n\\\n## 4.\"],[1,\" See the main note + NXP contacts for dev\\\nsamples.\\\n\\\n##\"],[0,\" Mod\"]],\"start1\":4493,\"start2\":4493,\"length1\":98,\"length2\":62},{\"diffs\":[[0,\"e)\\\n\\\n\"],[-1,\"- Independent of SCP03 personaliz\"],[1,\"`kf-dev-st\"],[0,\"ation\"],[-1,\":\"],[1,\"`\"],[0,\" pla\"]],\"start1\":4588,\"start2\":4588,\"length1\":47,\"length2\":24},{\"diffs\":[[0,\"plays a \"],[-1,\"**\"],[0,\"SEMS Lit\"]],\"start1\":4609,\"start2\":4609,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"ript\"],[-1,\"** natively\"],[0,\" to \"],[1,\"(re)\"],[0,\"flash \"],[-1,\"new \"],[0,\"firmware\"],[1,\";\"],[0,\" \"],[-1,\"onto the secure element.\\\n- UI shell exists in `kf-dev-station` (load + preview); the **\"],[0,\"native\"],[-1,\" \"],[1,\"\\\n\"],[0,\"player \"],[-1,\"is \"],[0,\"pend\"]],\"start1\":4639,\"start2\":4639,\"length1\":146,\"length2\":46},{\"diffs\":[[0,\"ing the \"],[-1,\"SEMS Lite \"],[0,\"script-f\"]],\"start1\":4685,\"start2\":4685,\"length1\":26,\"length2\":16},{\"diffs\":[[0,\"mple\"],[-1,\"**.\\\n- A dev station will frequently: **flash firmware (C) → then provision (B)**.\\\n\\\n---\\\n\\\n## 5. How the three modes coexist\\\n\\\n```\\\n  kf-dev-station ──┬─ Provisioning (static keys inline)   [Mode B]\\\n                   └─ Firmware Flashing (SEMS Lite)       [Mode C]\\\n\\\n  kf-prod-station ──── Provisioning (KLMS session offload) [Mode A]\\\n```\\\n- Shared core: `Provisioner`/`KlmsProvisioner` + `Scp03Channel` + DGI/STORE-DATA/lifecycle logic.\\\n- Diverges only at: **where keys come from** and **who establishes the channel**.\\\n\\\n---\\\n\\\n## 6. Suggested implementation order (status)\\\n1. ✅ Decouple `Scp03Channel` — `establish_from_session_keys`.\\\n2. ✅ `KlmsProvisioner` externally-established-channel path.\\\n3. ✅ Define the KLMS session-offload serde contract (`SessionRequest/Response/Content`).\\\n4. ✅ `kf-prod-station` GUI (provisioning only).\\\n5. ✅ Keep Mode B as default (`kf-dev-station`).\\\n6. ⏳ DLL-backed `KlmsClient`.\\\n7. ⏳ Real `pcsc` transport\"],[1,\". Frequent lab flow: flash firmware →\\\nprovision\"],[0,\".\"]],\"start1\":4710,\"start2\":4710,\"length1\":934,\"length2\":52}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-30T06:57:45.537Z
created_time: 2026-06-30T06:57:45.537Z
type_: 13