id: 0f0f15b116a14b019312fc415fff3998
parent_id: 04d5b67937ed4e94a3ba0df46db49fa9
item_type: 1
item_id: 3806c04b10e24dad817835acb66e1480
item_updated_time: 1786963043574
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"ne**\"],[-1,\": the station forwards a fob handshake to\\\n>\"],[1,\" (updated 2026-08-17 to reflect the implemented\\\n> REST transport): the station identifies the fob, runs INITIALIZE UPDATE, and\\\n> requests a container from\"],[0,\" Cly\"]],\"start1\":95,\"start2\":95,\"length1\":51,\"length2\":162},{\"diffs\":[[0,\"via \"],[-1,\"a **DLL\"],[1,\"**REST\"],[0,\" ove\"]],\"start1\":262,\"start2\":262,\"length1\":15,\"length2\":14},{\"diffs\":[[0,\" derives the\"],[1,\"\\\n>\"],[0,\" static + se\"]],\"start1\":293,\"start2\":293,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\"ion keys\"],[-1,\"\\\n>\"],[0,\" using t\"]],\"start1\":321,\"start2\":321,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"r key**)\"],[1,\"\\\n>\"],[0,\" and ret\"]],\"start1\":379,\"start2\":379,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\"eturns a\"],[-1,\"\\\n>\"],[0,\" **\"],[1,\"binary Clypeum \"],[0,\"containe\"]],\"start1\":395,\"start2\":395,\"length1\":21,\"length2\":34},{\"diffs\":[[0,\"on keys. The\"],[1,\"\\\n>\"],[0,\" station nev\"]],\"start1\":457,\"start2\":457,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\"olds the\"],[-1,\"\\\n>\"],[0,\" master \"]],\"start1\":487,\"start2\":487,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"n: **\\\"Keyfob\"],[1,\"\\\n>\"],[0,\" Flow 1 — Co\"]],\"start1\":539,\"start2\":539,\"length1\":24,\"length2\":26},{\"diffs\":[[0,\" Content\"],[-1,\"\\\n>\"],[0,\" Supply\\\"\"]],\"start1\":562,\"start2\":562,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"he c\"],[-1,\"ached content comes from\"],[1,\"ontent originates) and **\\\"Keyfob Flow 2b —\\\n> KLMS ↔ NetHSM AES Orchestration\\\"** (the per-message HSM table\"],[0,\").\\\n\"],[1,\">\"],[0,\"\\\n> *\"]],\"start1\":589,\"start2\":589,\"length1\":35,\"length2\":118},{\"diffs\":[[0,\"ead \"],[-1,\"from the\\\n> card\"],[1,\"via GET DATA\\\n> after SELECT ISD\"],[0,\"). *\"]],\"start1\":769,\"start2\":769,\"length1\":23,\"length2\":39},{\"diffs\":[[0,\"hey \"],[-1,\"live in the key\\\n> package (Flow 1) and \"],[0,\"come\"]],\"start1\":853,\"start2\":853,\"length1\":47,\"length2\":8},{\"diffs\":[[0,\"back\"],[1,\"\\\n>\"],[0,\" in the \"],[-1,\"response\"],[1,\"container\"],[0,\"**, \"]],\"start1\":864,\"start2\":864,\"length1\":24,\"length2\":27},{\"diffs\":[[0,\"** (`kf-\"],[1,\"dev-station` KLMS panel; \"],[0,\"prod-sta\"]],\"start1\":969,\"start2\":969,\"length1\":16,\"length2\":41},{\"diffs\":[[0,\"-station\"],[-1,\"`\"],[1,\" pending\"],[0,\") | PC/S\"]],\"start1\":1006,\"start2\":1006,\"length1\":17,\"length2\":24},{\"diffs\":[[0,\"; **\"],[-1,\"DLL → \"],[1,\"REST/\"],[0,\"mTLS\"]],\"start1\":1038,\"start2\":1038,\"length1\":14,\"length2\":13},{\"diffs\":[[0,\"03; \"],[-1,\"looks up cached content **by UID**\"],[1,\"generates containers on demand (seed-based)\"],[0,\"; as\"]],\"start1\":1243,\"start2\":1243,\"length1\":42,\"length2\":51},{\"diffs\":[[0,\"n\\\"**\"],[-1,\" (RFC 4493-over-ECB, exact\\\n> call counts, handle lifecycle)\"],[0,\".\\\n\\\n-\"]],\"start1\":1815,\"start2\":1815,\"length1\":67,\"length2\":8},{\"diffs\":[[0,\"RMAC\"],[-1,\", TTL ~5 s)\\\n \"],[1,\")\"],[0,\" + the\"],[1,\"\\\n \"],[0,\" **p\"]],\"start1\":2071,\"start2\":2071,\"length1\":27,\"length2\":17},{\"diffs\":[[0,\"phertext\"],[-1,\".\"],[1,\" (AES-128-CBC, IV=0, M2 — card-verified format).\\\n \"],[0,\" Never t\"]],\"start1\":2110,\"start2\":2110,\"length1\":17,\"length2\":66},{\"diffs\":[[0,\"til the \"],[-1,\"response\"],[1,\"container arrives\"],[0,\" — they \"]],\"start1\":2255,\"start2\":2255,\"length1\":24,\"length2\":33},{\"diffs\":[[0,\"ted \"],[-1,\"by Clypeum**\"],[1,\"twice**: by the KLMS\"],[0,\" (`c\"]],\"start1\":2331,\"start2\":2331,\"length1\":20,\"length2\":28},{\"diffs\":[[0,\"heck\"],[-1,\") before any\\\n  session\"],[1,\" in\\\n  Phase C, gate before\"],[0,\" keys \"],[-1,\"are \"],[0,\"issue\"],[-1,\"d — a rogue/clone fob is rejected.\\\n- Link security: **Station ↔ Clypeum = mTLS** (via DLL\"],[1,\") **and locally by the station** after container\\\n  decrypt, before EXTERNAL AUTHENTICATE.\\\n- Link security: **Station ↔ Clypeum = mTLS + bearer token** (IAM/Keycloak, client\\\n  cert\"],[0,\"); *\"]],\"start1\":2376,\"start2\":2376,\"length1\":134,\"length2\":224},{\"diffs\":[[0,\"lypeum (\"],[-1,\"DLL\"],[1,\"REST\"],[0,\" over mT\"]],\"start1\":2664,\"start2\":2664,\"length1\":19,\"length2\":20},{\"diffs\":[[0,\"S)\\\n\\\n\"],[-1,\"The station forwards **only the UID + the fob handshake**. No FESN/SPID — Clypeum\\\nresolves the content from the UID.\"],[1,\"`POST {ccs}/cryptoContainers`, `application/x-www-form-urlencoded`:\\\n\\\n| Form field | Value |\\\n|---|---|\\\n| `typeID` | `0x0900` (config: `container_type_id`) |\\\n| `seedUUID` | from `POST {ccs}/seeds` at connect (one per session, reused per tap) |\\\n| `productSerial` | `KF-<chip UID hex>` (7-byte PC/SC chip UID) |\\\n| `extra` | JSON below |\"],[0,\"\\\n\\\n``\"]],\"start1\":2685,\"start2\":2685,\"length1\":124,\"length2\":340},{\"diffs\":[[0,\"\\\": \\\"\"],[-1,\"550e8400-e29b-…\"],[1,\"TPS-01-<uid8>-<unix-sec>\"],[0,\"\\\",\\\n \"]],\"start1\":3050,\"start2\":3050,\"length1\":23,\"length2\":32},{\"diffs\":[[0,\"   \\\"\"],[-1,\"EOL-LINE-03\"],[1,\"TPS-01\"],[0,\"\\\",\\\n \"]],\"start1\":3098,\"start2\":3098,\"length1\":19,\"length2\":14},{\"diffs\":[[0,\"\\\n  \\\"fob\\\": {\\\n\"],[1,\"    \\\"oef\\\":         \\\"B252\\\",\\\n\"],[0,\"    \\\"uid\\\":  \"]],\"start1\":3110,\"start2\":3110,\"length1\":24,\"length2\":51},{\"diffs\":[[0,\"24\\\",\"],[-1,\"   // 10-byte JCOP UID — the only fob identity the station knows\"],[0,\"\\\n   \"]],\"start1\":3187,\"start2\":3187,\"length1\":72,\"length2\":8},{\"diffs\":[[0,\"rsion\\\": \"],[-1,\"1\"],[1,\"\\\"255\\\"\"],[0,\"\\\n  },\\\n  \"]],\"start1\":3203,\"start2\":3203,\"length1\":17,\"length2\":21},{\"diffs\":[[0,\"\\\n  }\"],[-1,\"\\\n}\\\n```\\\n\\\n> **Error path — no package for this UID:** Clypeum returns `NoPackage` (\"],[1,\",\\\n  \\\"keyBundleType\\\": \\\"dev\\\"\\\n}\\\n```\\\n\\\n> **Error path:** any HTTP error (e.g. the 2026-08-14 HTTP 500 during \"],[0,\"the\"],[1,\"ir\"],[0,\"\\\n> \"],[-1,\"watchdog hasn't seen this fob's content yet). The station halts that fob and\\\n> surfaces a setup error; the watchdog prioritizes the missing UID.\\\n\\\n---\\\n\\\n## 4. Response — Clypeum → Station (the **container**)\\\n\\\nClypeum resolves the package by UID and returns the content (incl. **FESN** and\\\n**SPID**) + session keys. SPID is delivered as the `A001` personalization item;\\\nFESN is included as container metadata (for audit/labeling).\\\n\\\n```json\\\n{\\\n  \\\"transaction_id\\\": \\\"550e8400-…\\\",\\\n  \\\"authenticated\\\":  true,\\\n  \\\"expires_at\\\":     \\\"2026-06-30T08:57:18Z\\\",\\\n  \\\"fob\\\": {\\\n    \\\"fesn\\\": \\\"1KM0001E\\\",                  // from the OEM key package (station learns it here)\\\n    \\\"spid\\\": \\\"59918C00…4BD1\\\"              // also present as A001 below\\\n  },\\\n  \\\"scp03\\\": {\\\n    \\\"ses_enc\\\": \\\"9F2A…\\\", \\\"ses_mac\\\": \\\"17B0…\\\", \\\"ses_rmac\\\": \\\"C4D1…\\\",\\\n    \\\"host_c\"],[1,\"card-ready rollout) — the station classifies it as a **server-stage failure**,\\\n> retries the generation once without touching the card, then surfaces the error.\\\n\\\n---\\\n\\\n## 4. Response — Clypeum → Station (the **container**)\\\n\\\n**201 Created** with `application/octet-stream`: the **binary Clypeum container**\\\n(wrapper-key encrypted, see **\\\"Clypeum Crypto Container Binary Format\\\"**), 13 TLV\\\nfields after decrypt:\\\n\\\n| # | Field | Notes |\\\n|---|---|---|\\\n| 0 | UID | echo |\\\n| 1 | FESN | OEM content — station learns it here |\\\n| 2 | SPID | also delivered as A001 |\\\n| 3 | Authenticated | status text |\\\n| 4–6 | S-ENC / S-MAC / S-RMAC | **session keys** |\\\n| 7 | Host C\"],[0,\"rypt\"]],\"start1\":3399,\"start2\":3399,\"length1\":908,\"length2\":775},{\"diffs\":[[0,\"gram\"],[-1,\"\\\": \\\"7E51…\\\", \\\"security_level\\\": \\\"C_MAC\\\"\\\n  },\\\n  \\\"content\\\": {\\\n    \\\"transaction_id\\\": \\\"klms-trx-987\\\",\\\n    \\\"personalization_items\\\": [\\\n      { \\\"dgi\\\": \\\"A001\\\", \\\"data\\\": \\\"<ASCII hex SPID>\\\",   \\\"encrypted\\\": false },\\\n      { \\\"dgi\\\": \\\"A002\\\", \\\"data\\\": \\\"<DER hex>\\\",           \\\"encrypted\\\": false },\\\n      { \\\"dgi\\\": \\\"A003\\\", \\\"data\\\": \\\"<48-byte hex>\\\",       \\\"encrypted\\\": true  },\\\n      { \\\"dgi\\\": \\\"A004\\\", \\\"data\\\": \\\"<DER hex>\\\",           \\\"encrypted\\\": false },\\\n      { \\\"dgi\\\": \\\"A005\\\", \\\"data\\\": \\\"<DER hex>\\\",           \\\"encrypted\\\": false },\\\n      { \\\"dgi\\\": \\\"A006\\\", \\\"data\\\": \\\"<16-byte hex>\\\",       \\\"encrypted\\\": false }\\\n    ],\\\n    \\\"post_perso_commands\\\": [ \\\"00DB0000030A0101\\\", \\\"00DB0000030B0101\\\" ]\\\n  }\\\n}\\\n```\"],[1,\" | for EXTERNAL AUTHENTICATE |\\\n| 8 | Fob Private Key | **card-ready**: 48 B, AES-128-CBC(IV=0)+M2 under S-DEK — forwarded untouched |\\\n| 9 | Fob Public Cert | → A002 |\\\n| 10 | IRK | → A006 |\\\n| 11 | ICA Cert | → A004 |\\\n| 12 | CMS Root Cert | → A005 |\\\n\\\nResponse headers carry `containeruuid` (and `cryptodatacontainerid` — currently\\\nempty, open item). The wrapper key comes from the seed.\\\n\\\n> The earlier design sketch (JSON container with `expires_at` TTL) was superseded\\\n> by the binary format; no TTL is currently enforced by the API.\"],[0,\"\\\n\\\n--\"]],\"start1\":4175,\"start2\":4175,\"length1\":675,\"length2\":540},{\"diffs\":[[0,\"LMS \"],[-1,\"looks up the fob's content in the cache **by UID** (populated by Flow 1),\\\nthen \"],[0,\"driv\"]],\"start1\":4789,\"start2\":4789,\"length1\":87,\"length2\":8},{\"diffs\":[[0,\"single-block\"],[-1,\" \"],[1,\"\\\n\"],[0,\"AES-ECB**;\\\nt\"]],\"start1\":4848,\"start2\":4848,\"length1\":25,\"length2\":25},{\"diffs\":[[0,\"S-ECB**;\"],[-1,\"\\\n\"],[1,\" \"],[0,\"the KLMS\"]],\"start1\":4863,\"start2\":4863,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"the full\"],[-1,\" \"],[1,\"\\\n\"],[0,\"RFC-4493\"]],\"start1\":4934,\"start2\":4934,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"over-ECB\"],[-1,\"\\\n\"],[1,\" \"],[0,\"sequence\"]],\"start1\":4952,\"start2\":4952,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"enticate fob\"],[1,\" (gate)\"],[0,\" |\\\n| Phase 2\"]],\"start1\":5294,\"start2\":5294,\"length1\":24,\"length2\":31},{\"diffs\":[[0,\"le (\"],[-1,\"EA\"],[1,\"station-side\"],[0,\" seq\"]],\"start1\":5858,\"start2\":5858,\"length1\":10,\"length2\":20},{\"diffs\":[[0,\"--|---|\\\n\"],[1,\"| 0 | Station → Fob | SELECT ISD + GET DATA | OEF ID + UID (UID **not** in INIT UPDATE response) |\\\n\"],[0,\"| 1 | St\"]],\"start1\":5934,\"start2\":5934,\"length1\":16,\"length2\":115},{\"diffs\":[[0,\" | `\"],[-1,\"UID[10]\"],[1,\"div(10)\"],[0,\" ‖ key_\"],[-1,\"info ‖ seq_counter[3]\"],[1,\"version ‖ scp_id ‖ i\"],[0,\" ‖ c\"]],\"start1\":6163,\"start2\":6163,\"length1\":43,\"length2\":42},{\"diffs\":[[0,\"hallenge\"],[-1,\"[8]\"],[1,\"(8)\"],[0,\" ‖ card_\"]],\"start1\":6210,\"start2\":6210,\"length1\":19,\"length2\":19},{\"diffs\":[[0,\"yptogram\"],[-1,\"[8]\"],[1,\"(8) ‖ seq_counter(3)\"],[0,\"` |\\\n| 3 \"]],\"start1\":6231,\"start2\":6231,\"length1\":19,\"length2\":36},{\"diffs\":[[0,\"m | \"],[-1,\"establish session (DLL/mTLS) | `transaction_id, station_id, fob{uid, key_version}, scp03{host_challenge,card_challenge,sequence_counter,card_cryptogram}` |\\\n| 4 | Clypeum (self) | cache lookup **by UID** | → content + FESN + SPID (from Flow 1) |\\\n| 5\"],[1,\"`POST /cryptoContainers` (mTLS+token) | form: typeID, seedUUID, productSerial, extra{...} |\\\n| 4–10\"],[0,\" | C\"]],\"start1\":6285,\"start2\":6285,\"length1\":256,\"length2\":106},{\"diffs\":[[0,\" 4–10 | Clypeum \"],[-1,\"→\"],[1,\"↔\"],[0,\" NetHSM | AES-EC\"]],\"start1\":6382,\"start2\":6382,\"length1\":33,\"length2\":33},{\"diffs\":[[0,\"M | \"],[-1,\"AES-ECB ×7 (KDF3, see Flow 2b §A) | `master handle, derivation blocks` → S-ENC/MAC/DEK |\\\n| 6 | Clypeum → NetHSM | AES-ECB-assembled CMAC (card-cg verify) | `SES-MAC handle, derivation data` |\\\n| 7 | Clypeum (self) | authenticate | compare (#2 vs #6); reject rogue fob\"],[1,\"KDF3 → card-cg gate → session keys → host-cg → A003 CBC | see Flow 2b (23 ECB + 4 Import + 4 Destroy)\"],[0,\" |\\\n| \"],[-1,\"8\"],[1,\"11\"],[0,\" | C\"]],\"start1\":6405,\"start2\":6405,\"length1\":280,\"length2\":116},{\"diffs\":[[0,\"m → \"],[-1,\"NetHSM | AES-ECB-assembled CMACs (session KDF) | `S-ENC/S-MAC handles, derivation data` → SES-* |\\\n| 9 | Clypeum → NetHSM | AES-ECB-assembled CMAC (host cryptogram) | `SES-MAC handle, derivation data`\"],[1,\"Station | 201 + binary container | 13 TLV fields (§4); `containeruuid` header\"],[0,\" |\\\n| 1\"],[-1,\"0 | Clypeum → NetHSM | AES-ECB-assembled CBC (A003 encrypt) | `S-DEK handle, private_key` |\\\n| 11 | NetHSM → Clypeum | results | `ses*, host_cryptogram, A003_ciphertext` |\\\n| 12 | Clypeum → Station | container (response) | `fob{fesn,spid}, scp03{ses*,host_cryptogram,security_level}, content{items incl. encrypted A003, post_perso}, expires_at`\"],[1,\"2 | Station (self) | decrypt + verify | wrapper-key decrypt; session-key extraction (tag-keyed); **local card-cryptogram check**\"],[0,\" |\\\n|\"]],\"start1\":6526,\"start2\":6526,\"length1\":555,\"length2\":219},{\"diffs\":[[0,\"ad ‖ MAC[8]`\"],[1,\" (9 blocks typical)\"],[0,\" |\\\n| 16 | St\"]],\"start1\":6960,\"start2\":6960,\"length1\":24,\"length2\":43},{\"diffs\":[[0,\"n → \"],[-1,\"Clypeum | provision result | `transaction_id, fesn, result, stage_reached, apdu_count, timestamp` |\\\n\\\n### Alt / error paths\\\n- **No package for UID / low stock** (#4): `NoPackage` returned; watchdog priority-fetch for that UID; station retries after brief wait\"],[1,\"Fob | validation | certs/FESN/SPID read-back + **GA ECDSA verify** |\\\n| 19 | Station → Clypeum | provision result (`report_usage`) | **PENDING** — awaiting KLMS status semantics |\\\n\\\n### Alt / error paths\\\n- **HTTP error (#3):** server-stage → one plain retry (no card re-install), then fail\"],[0,\".\\\n- \"]],\"start1\":7176,\"start2\":7176,\"length1\":266,\"length2\":295},{\"diffs\":[[0,\"Card\"],[-1,\" not authenticated** (#7): no container/s\"],[1,\"-stage rejection (#13–#16, e.g. 69 82 / 6A 80):** re-install applet + retry once.\\\n- **S\"],[0,\"ession\"],[-1,\" keys issued (#12 = error); station halts.\\\n- **TTL expiry** (`expires_at` before EXTERNAL AUTH): fob rejects #13 (`69 82`); restart from #1.\\\n- **NetHSM unreachable** (#5–#11): `KlmsError::Client`; station surfaces a setup error\"],[1,\"-key / card-cryptogram mismatch (#12):** server-stage (bad container) → plain retry.\\\n- **Card removed mid-flow:** reconnect fails → run fails; operator re-taps\"],[0,\".\\\n\\\n-\"]],\"start1\":7473,\"start2\":7473,\"length1\":282,\"length2\":260},{\"diffs\":[[0,\"orch\"],[-1,\"+cache)\"],[1,\")     \"],[0,\"    \"]],\"start1\":7806,\"start2\":7806,\"length1\":15,\"length2\":14},{\"diffs\":[[0,\"nly)\\\n │ \"],[-1,\"INIT UPD\"],[1,\"SELECT ISD │                  │                               │\\\n │ GET DATA\"],[0,\"   │    \"]],\"start1\":7853,\"start2\":7853,\"length1\":24,\"length2\":91},{\"diffs\":[[0,\"──┤ \"],[-1,\"80 50 … hc\"],[1,\"OEF+UID   \"],[0,\"    \"]],\"start1\":8004,\"start2\":8004,\"length1\":18,\"length2\":18},{\"diffs\":[[0,\"\\\n │ \"],[-1,\"UID‖cc‖cg\"],[1,\"INIT UPD \"],[0,\"  │ \"]],\"start1\":8058,\"start2\":8058,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"             │\\\n \"],[-1,\"├\"],[1,\"│◄\"],[0,\"───────────►│ DL\"]],\"start1\":8111,\"start2\":8111,\"length1\":33,\"length2\":34},{\"diffs\":[[0,\"────\"],[-1,\"►│ DLL/mTLS(uid)\"],[1,\"┤ 80 50 … hc   \"],[0,\"    \"]],\"start1\":8136,\"start2\":8136,\"length1\":24,\"length2\":23},{\"diffs\":[[0,\"\\\n │ \"],[-1,\"           ├─────────────────►│ cache lookup(uid) → FESN/SPID │\\\n │\"],[1,\"div‖cc‖cg  │                  │                               │\\\n ├───────────►│ POST /cryptoContainers (mTLS+token)  \"],[0,\"    \"]],\"start1\":8192,\"start2\":8192,\"length1\":74,\"length2\":125},{\"diffs\":[[0,\")              │\"],[-1,\" \"],[1,\"\\\n │\"],[0,\"                \"]],\"start1\":8310,\"start2\":8310,\"length1\":33,\"length2\":35},{\"diffs\":[[0,\"    \"],[-1,\"     │   +content (from Flow 1)\"],[1,\"├─────────────────►│ generate (seedUUID)     \"],[0,\"    \"]],\"start1\":8337,\"start2\":8337,\"length1\":39,\"length2\":53},{\"diffs\":[[0,\"       │\"],[1,\" 201 +\"],[0,\" contain\"]],\"start1\":8766,\"start2\":8766,\"length1\":16,\"length2\":22},{\"diffs\":[[0,\"tainer  \"],[-1,\"      \"],[0,\"│       \"]],\"start1\":8784,\"start2\":8784,\"length1\":22,\"length2\":16},{\"diffs\":[[0,\"│  (\"],[-1,\"FESN/SPID+ses*)\"],[1,\"13 TLV fields) \"],[0,\"│   \"]],\"start1\":8840,\"start2\":8840,\"length1\":23,\"length2\":23},{\"diffs\":[[0,\" │  \"],[-1,\"                │           \"],[1,\"(local card-cg verify first)\"],[0,\"    \"]],\"start1\":8973,\"start2\":8973,\"length1\":36,\"length2\":36},{\"diffs\":[[0,\"RE DATA×\"],[-1,\"N\"],[1,\"9\"],[0,\" …   │  \"]],\"start1\":9113,\"start2\":9113,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"  │ \"],[-1,\"result(fesn) \"],[1,\"validate (GA)\"],[0,\"    \"]],\"start1\":9240,\"start2\":9240,\"length1\":21,\"length2\":21},{\"diffs\":[[0,\"───►\"],[-1,\"├─────────────────►│ (audit + retire cached pkg)   │\\\n```\\\n\\\n---\\\n\\\n## 8. Code alignment (our boundary)\\\n\\\nOur boundary is the **Station ↔ Clypeum contract only** (this note's §3/§4).\\\nClypeum internals (cache, NetHSM AES orchestration, master-key ECB) are Clypeum's.\\\n\\\n| Type | Status |\\\n|---|---|\\\n| `SessionRequest` | add `transaction_id`, `station_id`; `fob` = `{uid, key_version}` only (**no fesn/spid**) |\\\n| `SessionResponse` | add `fob{fesn, spid}` + `authenticated`, `expires_at`; content carries A001 (SPID) |\\\n| `KlmsContent` | sufficient |\\\n| `KlmsProvisioner` | already enforces `encrypt_with_dek=false` (app holds no S-DEK) |\\\n| DLL-backed `KlmsClient` | maps 1:1 onto the request/response; link = mTLS |\\\n| `Scp03Channel::establish_from_session_keys` | injects the container's session keys |\\\n| `kf-crypto` (`aes_cmac_with_subkeys`/`aes_cmac_via_ecb`/`CmacSubkeys`) | the exact RFC-4493-over-ECB assembly the KLMS↔NetHSM path uses (Flow 2b §2) |\\\n| `kf-hsm` Nitrokey `CKM_AES_ECB` backend | dev model of the same AES-ECB primitive (Flow 2b §1) |\\\n\\\n---\\\n\\\n## 9. Open decisions\\\n\\\n- [ ] **DLL interface** (the real `KlmsClient` binding) + mTLS details\"],[1,\"│ result           │                               │\\\n │            ├─────────────────►│ report_usage — PENDING        │\\\n```\\\n\\\n---\\\n\\\n## 8. Code alignment (our boundary, as implemented)\\\n\\\n| Piece | Status |\\\n|---|---|\\\n| `klms_client.rs` (kf-dev-station) | **REST client implemented**: token auth, seed, generate (form), report_usage (defined, unwired) |\\\n| `container_parser.rs` | binary Clypeum container parse + wrapper-key decrypt, tag-keyed fields |\\\n| `ContainerTlvSource` | fields → DGI items; card-ready A003 forwarded untouched (CBC+IV0+M2) |\\\n| `establish_klms_channel` (nfc_reader) | session-key extraction + **local card-cryptogram gate** + EXTERNAL AUTHENTICATE |\\\n| `Scp03Channel::establish_from_session_keys` | injects the container's session keys |\\\n| `FlowError` classification | server-stage → plain retry; card-stage → re-install + retry |\\\n| Config (`klms-config.toml`) | typeID, keyBundleType, accept_invalid_certs, station_id |\\\n| HW verification | **2026-08-17**: two fobs, GA ECDSA verify true, 24 APDUs each |\\\n\\\n---\\\n\\\n## 9. Open decisions\\\n\\\n- [ ] **`report_usage` semantics** — status values/payload; also populates productSerial\\\n      in the KLMS admin (currently blank).\\\n- [ ] **`cryptoDataContainerId` header** — currently empty; `validate_cid` ready\"],[0,\".\\\n- \"]],\"start1\":9305,\"start2\":9305,\"length1\":1149,\"length2\":1269},{\"diffs\":[[0,\"EC.\\\n\"],[-1,\"- [ ] Session-key **TTL** (~5 s) + single-use enforcement.\\\n\"],[0,\"- [ \"]],\"start1\":10635,\"start2\":10635,\"length1\":67,\"length2\":8},{\"diffs\":[[0,\"s).\\\n\"],[-1,\"- [ ] Whether the KLMS **verifies card_cryptogram** (recommended — the mock does).\\\n\"],[0,\"- [ \"]],\"start1\":10717,\"start2\":10717,\"length1\":91,\"length2\":8},{\"diffs\":[[0,\"[ ] \"],[-1,\"Cache index key = UID only (confirm unique per fob) + `NoPackage` retry policy\"],[1,\"Seed lifecycle policy (single-use? TTL?) — currently one seed per connect,\\\n      reused across taps; accepted by dev KLMS\"],[0,\".\"]],\"start1\":10862,\"start2\":10862,\"length1\":83,\"length2\":126}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-17T10:39:07.238Z
created_time: 2026-08-17T10:39:07.238Z
is_locked: 0
type_: 13