id: 8dd64381729c4567a316530ce3df133e
parent_id: 87e1c4b6e3f54c94ac77468027ef4fab
item_type: 1
item_id: 1fbaa70f2fb94ffcaabbeca7b39482da
item_updated_time: 1786727988706
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\".\\\n> \"],[-1,\"Files live in\"],[1,\"**This note is\"],[0,\" the \"],[-1,\"repo\"],[1,\"only copy** —\"],[0,\" a\"],[-1,\"t\"],[0,\" `do\"]],\"start1\":126,\"start2\":126,\"length1\":33,\"length2\":42},{\"diffs\":[[0,\"ams/\"],[-1,\"*.puml`; r\"],[1,\"` folder was never committed to the\\\n> repo. R\"],[0,\"endered \"],[-1,\"**\"],[0,\"SVG\"],[-1,\"** (scalable, for\\\n> PPT/Word) and **PNG** go alongside each source.\"],[1,\"/PNG were generated ad hoc (PPT/Word embeds use the SVG).\\\n>\"],[0,\" Com\"]],\"start1\":176,\"start2\":176,\"length1\":98,\"length2\":123},{\"diffs\":[[0,\"low 1**,\"],[-1,\"\\\n>\"],[0,\" **Keyfo\"]],\"start1\":318,\"start2\":318,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"l), \"],[-1,\"**Keyfob Flow 2b — KLMS ↔ NetHSM AES\\\n> Orchestration**\"],[1,\"audit note\\\n> (**Keyfob Station — Code Audit Open Items**).\\\n\\\n> **Review status 2026-08-14** — verified against the code (kf-scp03 derive.rs,\\\n> kf-provision perso.rs/helpers.rs, kf-source container.rs, nfc_reader.rs):\\\n> - **Phase A–D KDF diagrams: correct as drawn.** Purposes 0x40/0x60/0x70, header\\\n>   `00^11‖p‖00‖0080‖01`, K1-for-full / K2-for-partial CMAC blocks, ECB call counts\\\n>   (7+8+5+3 = 23), Phase D CBC chaining — all match code + tests.\\\n> - **Phase D (A003 = AES-CBC, IV=0, M2) is CONFIRMED by hardware**: the card accepts\\\n>   CBC and rejects the KLMS's ECB blob with `6A 80`. The dev KLMS currently emits\\\n>   ECB+M2; the station converts locally until they switch to CBC\"],[0,\" (\"],[1,\"o\"],[0,\"pe\"],[-1,\"r-message AES-ECB table)\"],[1,\"n item).\\\n> - Flow 2 diagrams updated: REST transport (was DLL), seed-based on-demand generation\\\n>   (was Flow-1 cache/NoPackage), INIT UPDATE response layout fixed (UID is read via\\\n>   GET DATA beforehand, not returned by INITIALIZE UPDATE), step 9 marked PENDING\"],[0,\".\\\n\\\n#\"]],\"start1\":360,\"start2\":360,\"length1\":90,\"length2\":959},{\"diffs\":[[0,\"ws |\"],[-1,\" SVG (px W×H) |\\\n| --- \"],[1,\"\\\n\"],[0,\"| --\"]],\"start1\":1343,\"start2\":1343,\"length1\":30,\"length2\":9},{\"diffs\":[[0,\"rview — \"],[-1,\"**\"],[0,\"two-row \"]],\"start1\":1399,\"start2\":1399,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"w — two-row flow\"],[-1,\"**\"],[0,\" (both rows star\"]],\"start1\":1403,\"start2\":1403,\"length1\":34,\"length2\":32},{\"diffs\":[[0,\"D) |\"],[-1,\" 1712×538 |\"],[0,\"\\\n| `\"]],\"start1\":1460,\"start2\":1460,\"length1\":19,\"length2\":8},{\"diffs\":[[0,\"s) |\"],[-1,\" 915×1225 |\"],[0,\"\\\n| `\"]],\"start1\":1525,\"start2\":1525,\"length1\":19,\"length2\":8},{\"diffs\":[[0,\"de |\"],[-1,\" 906×704 |\"],[0,\"\\\n| `\"]],\"start1\":1590,\"start2\":1590,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"de |\"],[-1,\" 836×718 |\"],[0,\"\\\n| `\"]],\"start1\":1653,\"start2\":1653,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"s) |\"],[-1,\" 690×1076 |\"],[0,\"\\\n| `\"]],\"start1\":1706,\"start2\":1706,\"length1\":19,\"length2\":8},{\"diffs\":[[0,\"de |\"],[-1,\" 684×699 |\"],[0,\"\\\n| `\"]],\"start1\":1773,\"start2\":1773,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"de |\"],[-1,\" 747×543 |\"],[0,\"\\\n| `\"]],\"start1\":1841,\"start2\":1841,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"g) |\"],[-1,\" 885×983 |\"],[0,\"\\\n| `\"]],\"start1\":1910,\"start2\":1910,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"up |\"],[-1,\" 908×700 |\"],[0,\"\\\n| `\"]],\"start1\":1968,\"start2\":1968,\"length1\":18,\"length2\":8},{\"diffs\":[[0,\"e) |\"],[-1,\" 1384×2210 |\"],[0,\"\\\n| `\"]],\"start1\":2034,\"start2\":2034,\"length1\":20,\"length2\":8},{\"diffs\":[[0,\"e) |\"],[-1,\" 1639×1134 |\"],[0,\"\\\n| `\"]],\"start1\":2120,\"start2\":2120,\"length1\":20,\"length2\":8},{\"diffs\":[[0,\"e) |\"],[-1,\" 967×1087 |\\\n\\\n> **Layout notes.** `kdf-overview` is now a **two-row flow** (both rows start on the\\\n> left; end of row 1 wraps to the start of row 2), and **A003 now correctly feeds\\\n> Phase D** (not Phase A). Phases A and B are split into two **slide-fit** halves\\\n> each (`-1`/`-2`); the unsuffixed files are the full single-page (Word) versions.\\\n> The combined `flow-2b-kdf-nethsm.puml` was removed (covered by the four phase\\\n> diagrams + overview).\"],[0,\"\\\n\\\n##\"]],\"start1\":2196,\"start2\":2196,\"length1\":456,\"length2\":8},{\"diffs\":[[0,\"svg \"],[-1,\"docs/diagrams/*\"],[1,\"<file>\"],[0,\".pum\"]],\"start1\":2275,\"start2\":2275,\"length1\":23,\"length2\":14},{\"diffs\":[[0,\"late\"],[-1,\"/map6\"],[0,\" encoder\"],[-1,\" (+ UA header)\\\npython3 ~/render_puml.py docs/diagrams        # PNG always; SVG only if missing\\\npython3 ~/render_puml.py docs/diagrams --svg  # also (re)render SVG\\\n```\\\n\\\nFor PPT/Word embed the **SVG** (scalable). Server URL:\\\n`https://www.plantuml.com/plantuml/{png,svg}/<encoded>`\"],[1,\"\\\n# https://www.plantuml.com/plantuml/{png,svg}/<encoded>\\\n```\\\n\\\nFor PPT/Word embed the **SVG** (scalable)\"],[0,\".\\\n\\\n*\"]],\"start1\":2335,\"start2\":2335,\"length1\":299,\"length2\":119},{\"diffs\":[[0,\"ction.\\\nend note\\\n\"],[1,\"note right of pD #FFEEEE\\\n  HW-confirmed 2026-08-14: card accepts\\\n  CBC(IV=0)+M2 and rejects ECB (6A80).\\\n  Dev KLMS currently emits ECB+M2;\\\n  station converts until KLMS fixes.\\\nend note\\\n\"],[0,\"@enduml\\\n```\\\n\\\n* *\"]],\"start1\":4727,\"start2\":4727,\"length1\":32,\"length2\":217},{\"diffs\":[[0,\"3 CMAC).\"],[1,\"\\\n' Constants validated against kf-scp03 derive.rs (jcshell_reference_vector test).\"],[0,\"\\\n\\\nautonu\"]],\"start1\":5097,\"start2\":5097,\"length1\":16,\"length2\":98},{\"diffs\":[[0,\"leanup.\\\n\"],[1,\"' HW-CONFIRMED 2026-08-14: card accepts CBC(IV=0)+M2; ECB is rejected (6A80).\\\n\"],[0,\"autonumb\"]],\"start1\":13481,\"start2\":13481,\"length1\":16,\"length2\":94},{\"diffs\":[[0,\"station.\"],[1,\"\\\\\n**Dev status**: KLMS currently emits ECB+M2 instead; the station\\\\\nre-encrypts to CBC locally until the KLMS switches (open item).\"],[0,\"\\\n== A003\"]],\"start1\":13880,\"start2\":13880,\"length1\":16,\"length2\":147},{\"diffs\":[[0,\")\\\n' \"],[-1,\"Station knows only the UID; FESN/SPID come back in the response\"],[1,\"Updated 2026-08-14: REST transport, seed-based generation, INIT UPDATE layout\"],[0,\".\\\n' \"]],\"start1\":14713,\"start2\":14713,\"length1\":71,\"length2\":85},{\"diffs\":[[0,\"er key)\\\" as HSM\\\n\"],[1,\"== 0. Identify (station <-> fob) ==\\\nStation -> Fob : SELECT ISD\\\\\n00 A4 04 00 || A000000151000000\\\nStation -> Fob : GET DATA (OEF ID + UID)\\\nFob --> Station : OEF ID (B252) + UID\\\\\n(10-B JCOP UID; 7-B chip UID fallback)\\\n\"],[0,\"== 1. SCP03 init\"]],\"start1\":15045,\"start2\":15045,\"length1\":32,\"length2\":248},{\"diffs\":[[0,\"n : \"],[-1,\"UID\"],[1,\"key_div_data\"],[0,\"[10] \"],[-1,\"||\"],[1,\"‖\"],[0,\" key_\"],[-1,\"info || seq_counter[3]\\\\\n|| \"],[1,\"version ‖ scp_id ‖ i ‖\\\\\n\"],[0,\"card\"]],\"start1\":15417,\"start2\":15417,\"length1\":50,\"length2\":55},{\"diffs\":[[0,\"rd_challenge[8] \"],[-1,\"||\"],[1,\"‖\"],[0,\" card_cryptogram\"]],\"start1\":15470,\"start2\":15470,\"length1\":34,\"length2\":33},{\"diffs\":[[0,\"m[8]\"],[-1,\"\\\n== 2. Forward handshake to KLMS (DLL over mTLS) ==\\\nStation -> KLMS : establish session\\\\\n\"],[1,\" ‖ seq_counter[3]\\\\\nnote right: UID is NOT in this response (read in step 0)\\\n== 2. Container request (REST over mTLS; seed from POST /seeds at connect) ==\\\nStation -> KLMS : POST /cryptoContainers\\\\\nform{ typeID, seedUUID, productSerial=KF-<chip UID>,\\\\\n  extra\"],[0,\"{ tr\"]],\"start1\":15502,\"start2\":15502,\"length1\":97,\"length2\":265},{\"diffs\":[[0,\"tion_id,\\\\\n  fob{\"],[1,\"oef, \"],[0,\"uid, key_version\"]],\"start1\":15784,\"start2\":15784,\"length1\":32,\"length2\":37},{\"diffs\":[[0,\"ram}\"],[-1,\" }\\\nKLMS -> KLMS : cache lookup **by UID**\\\\\n-> content + FESN + SPID (from Flow 1)\\\nalt no package for UID\\\n  KLMS --> Station : NoPackage  (watchdog priority-fetches\"],[1,\",\\\\\n  keyBundleType } }\\\nalt HTTP 5xx / error\\\n  KLMS --> Station : error (HTTP 500 etc.)\\\\\nstation retries once without touching\"],[0,\" the \"],[-1,\"UID)\"],[1,\"card\"],[0,\"\\\nend\"]],\"start1\":15904,\"start2\":15904,\"length1\":180,\"length2\":142},{\"diffs\":[[0,\"phertext\"],[1,\" (CBC, IV=0, M2)\"],[0,\"\\\n  HSM -\"]],\"start1\":16908,\"start2\":16908,\"length1\":16,\"length2\":32},{\"diffs\":[[0,\"ion \"],[-1,\"==\\\nKLMS --> Station : container\\\\\n{ fob{fesn, spid}, authenticated,\\\\\n  scp03{ses_enc, ses_mac, ses_rmac, host_c\"],[1,\"(binary Clypeum container, wrapper-key encrypted) ==\\\nKLMS --> Station : container (13 TLV fields)\\\\\n{ UID, FESN, SPID, Authenticated,\\\\\n  S-ENC, S-MAC, S-RMAC, Host C\"],[0,\"rypt\"]],\"start1\":17014,\"start2\":17014,\"length1\":118,\"length2\":172},{\"diffs\":[[0,\"\\\\\n  \"],[-1,\"     security_level},\\\\\n  content{A001..A006 (A003 pre-encrypted), post_perso},\\\\\n  expires_at (~5 s) }\\\nStation -> Station : Scp03Channel::establish_\"],[1,\"Private Key (A003 pre-encrypted),\\\\\n  Fob Pub Cert, IRK, ICA Cert, CMS Root Cert }\\\nStation -> Station : parse + decrypt (wrapper key \"],[0,\"from\"],[-1,\"_session_keys(\"],[1,\" seed)\\\\\nverify card cryptogram locally (safety gate\"],[0,\")\\\n==\"]],\"start1\":17192,\"start2\":17192,\"length1\":173,\"length2\":195},{\"diffs\":[[0,\" Result + audit \"],[1,\"— PENDING \"],[0,\"==\\\nStation -> KL\"]],\"start1\":18095,\"start2\":18095,\"length1\":32,\"length2\":42},{\"diffs\":[[0,\"provision result\"],[1,\" (report_usage)\"],[0,\"\\\\\n{ transaction_\"]],\"start1\":18142,\"start2\":18142,\"length1\":32,\"length2\":47},{\"diffs\":[[0,\"mp }\"],[-1,\"\\\nKLMS -> KLMS : audit + retire cached package\"],[1,\"\\\\\nnote right #FFEEEE : NOT YET WIRED - awaiting KLMS\\\\\nstatus-value semantics (open item);\\\\\nlikely also populates productSerial\\\\\nin the KLMS admin\"],[0,\"\\\nSta\"]],\"start1\":18244,\"start2\":18244,\"length1\":53,\"length2\":153},{\"diffs\":[[0,\"e-fit).\\\n\"],[1,\"' Updated 2026-08-14: REST transport, seed-based generation, INIT UPDATE layout.\\\n\"],[0,\"' Compac\"]],\"start1\":18873,\"start2\":18873,\"length1\":16,\"length2\":97},{\"diffs\":[[0,\"e).\\\n\"],[-1,\"' Station knows only the UID; FESN/SPID come back in the response.\\\n\"],[0,\"titl\"]],\"start1\":19146,\"start2\":19146,\"length1\":75,\"length2\":8},{\"diffs\":[[0,\" as HSM\\\n\"],[1,\"== 0. Identify (station <-> fob) ==\\\nStation -> Fob : SELECT ISD + GET DATA\\\nFob --> Station : OEF ID (B252) + UID\\\\\n(10-B JCOP UID; 7-B chip UID fallback)\\\n\"],[0,\"== 1. SC\"]],\"start1\":19370,\"start2\":19370,\"length1\":16,\"length2\":169},{\"diffs\":[[0,\"n : \"],[-1,\"UID\"],[1,\"key_div_data\"],[0,\"[10] \"],[-1,\"||\"],[1,\"‖\"],[0,\" key_\"],[-1,\"info || seq_counter[3]\\\\\n|| \"],[1,\"version ‖ scp_id ‖ i ‖\\\\\n\"],[0,\"card\"]],\"start1\":19671,\"start2\":19671,\"length1\":50,\"length2\":55},{\"diffs\":[[0,\"enge[8] \"],[-1,\"||\"],[1,\"‖\"],[0,\" card_cr\"]],\"start1\":19732,\"start2\":19732,\"length1\":18,\"length2\":17},{\"diffs\":[[0,\"m[8]\"],[-1,\"\\\n== 2. Forward handshake to KLMS (DLL over mTLS) ==\\\nStation -> KLMS : establish session\\\\\n{ transaction_id, station_id,\\\\\n  fob{uid, key_version},\\\\\n  scp03{host_challenge, card_challenge,\\\\\n        sequence_counter, card_cryptogram} }\\\nKLMS -> KLMS : cache lookup **by UID**\\\\\n-> content + FESN + SPID (from Flow 1)\\\nalt no package for UID\\\n  KLMS --> Station : NoPackage  (watchdog priority-fetches\"],[1,\" ‖ seq_counter[3]\\\n== 2. Container request (REST over mTLS; seed from POST /seeds at connect) ==\\\nStation -> KLMS : POST /cryptoContainers\\\\\nform{ typeID, seedUUID, productSerial, extra{...} }\\\nalt HTTP 5xx / error\\\n  KLMS --> Station : error — station retries once without touching\"],[0,\" the \"],[-1,\"UID)\"],[1,\"card\"],[0,\"\\\nend\"]],\"start1\":19756,\"start2\":19756,\"length1\":409,\"length2\":294},{\"diffs\":[[0,\"k to station\"],[1,\" (binary Clypeum container)\"],[0,\" ==\\\nKLMS -->\"]],\"start1\":20672,\"start2\":20672,\"length1\":24,\"length2\":51},{\"diffs\":[[0,\"iner\"],[-1,\"\\\\\n{ fob{fesn, spid}, authenticated,\\\\\n  scp03{ses_enc, ses_mac, ses_rmac, host_c\"],[1,\" (13 TLV fields)\\\\\n{ UID, FESN, SPID, Authenticated, S-ENC, S-MAC,\\\\\n  S-RMAC, Host C\"],[0,\"rypt\"]],\"start1\":20739,\"start2\":20739,\"length1\":87,\"length2\":91},{\"diffs\":[[0,\"am, \"],[-1,\"security_level},\\\\\n  content{A001..A006\"],[1,\"Private Key\"],[0,\" (A003\"],[1,\"\\\\\n \"],[0,\" pre\"]],\"start1\":20833,\"start2\":20833,\"length1\":52,\"length2\":28},{\"diffs\":[[0,\"d), \"],[-1,\"post_perso}, expires_at (~5 s) }\\\nStation -> Station : Scp03Channel::establish_\"],[1,\"Fob Pub Cert, IRK, ICA, CMS Root }\\\nStation -> Station : parse + decrypt (wrapper key \"],[0,\"from\"],[-1,\"_session_keys(\"],[1,\" seed)\\\\\nverify card cryptogram locally (safety gate\"],[0,\")\\\nno\"]],\"start1\":20870,\"start2\":20870,\"length1\":104,\"length2\":148},{\"diffs\":[[0,\"+ audit \"],[1,\"— PENDING \"],[0,\"==\\\nStati\"]],\"start1\":22454,\"start2\":22454,\"length1\":16,\"length2\":26},{\"diffs\":[[0,\"n result\"],[1,\" (report_usage)\"],[0,\"\\\\\n{ tran\"]],\"start1\":22501,\"start2\":22501,\"length1\":16,\"length2\":31},{\"diffs\":[[0,\"p }\\\n\"],[-1,\"KLMS -> KLMS : audit + retire cached package\"],[1,\"note right #FFEEEE : NOT YET WIRED - awaiting KLMS\\\\\nstatus-value semantics (open item)\"],[0,\"\\\nSta\"]],\"start1\":22596,\"start2\":22596,\"length1\":52,\"length2\":94},{\"diffs\":[[0,\"\\\nend note\\\n@enduml\\\n```\\\n\\\n* * *\"],[-1,\"\\\n\"]],\"start1\":22901,\"start2\":22901,\"length1\":29,\"length2\":28}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-14T17:20:00.824Z
created_time: 2026-08-14T17:20:00.824Z
is_locked: 0
type_: 13