Keyfob Station — PlantUML Diagram Sources

# Keyfob Station — PlantUML Diagram Sources

> Index + status for every PlantUML diagram. **Canonical sources live in the repo at
> `docs/diagrams/`**: `KDF/` (12 sets), `Transport/` (2 sets) and `HSM_Backup/`
> (5 sets), each as `.puml` + rendered `.svg` + `.png`. Edit the files, not this
> note. PPT/Word embeds use the **SVG**. Companions: **Keyfob Flow 1**,
> **Keyfob Flow 2** (sequence detail), audit note.

> **Review status (2026-08-21)**
> - **KDF set: correct as drawn** — verified against kf-scp03 derive.rs,
>   kf-provision perso.rs/helpers.rs, kf-source container.rs, nfc_reader.rs.
>   Purposes 0x40/0x60/0x70, header `00^11‖p‖00‖0080‖01`, K1-full/K2-partial CMAC
>   blocks, ECB counts (7+8+5+3=23), Phase D CBC chaining.
> - **Phase D (A003 = AES-128-CBC, IV=0, M2) HW-confirmed**; KLMS delivers it since
>   2026-08-17, station forwards untouched (ECB bridge removed).
> - **klms-connection (Transport/, 2026-08-21, split into two slides same day)** —
>   station↔KLMS connection security, split for slide use:
>   **1/2** mTLS handshake with BOTH certificate validations (server chain to
>   Clypeum Root CA + hostname; client cert at the server) + OAuth2 bearer token;
>   **2/2** seed → NIST SP 800-108 → 32-B wrapper key (derived on BOTH sides, never
>   transmitted) + AES-256-CBC(IV=0) container payload encryption/decryption with
>   the double-protection note. Verified against klms_client.rs +
>   container_parser.rs. (Removed on request: the accept_invalid_certs note, the
>   validation-failure alt box, and the empty-user/password note.)
> - **HSM_Backup set**: wrap algorithm decided — **ECIES (ECDH P-256 → HKDF-SHA256 →
>   AES-256-GCM)** for every ceremony/backup. Rationale: NitroHSM (SmartCard-HSM) is
>   ECC-only → RSA-OAEP impossible for its two ceremonies; P-256 ECDH supported by
>   YubiHSM2 (derive-ecdh), SmartCard-HSM, NXP. Implementation caveat: verify exact
>   AEAD per SDK (YubiHSM native wrap = AES-CCM; SmartCard-HSM import = own AEAD).
> - **hsm-topology layout (38d66c7, approved)**: left column = key custody chain
>   (NXP → NitroHSM → MK backup into YubiHSM-1 → DK replication to YubiHSM-2);
>   right cluster = runtime (Ford → VM-1/VM-2 → their YubiHSMs). AES-ECB arrows
>   attach to the VM **left sides** and enter the NitroHSM from the right
>   (`-left->` hints). Total edge length ~25% shorter than the 3-row arrangement;
>   one crossing (Ford→VM-1 × VM2→NH) is topologically unavoidable.
>   Lessons: ranks come from down-edges; horizontal hints only between same-rank
>   neighbours; `together` does NOT pin ranks for deployment nodes.
> - All 19 diagram sets verified renders.

## Diagrams

### docs/diagrams/KDF/ (12 sets)

| File | Shows |
| --- | --- |
| `kdf-overview` | KDF phase overview — two-row flow (A003 feeds Phase D) |
| `kdf-phase-a` / `-a-1` / `-a-2` | Phase A full + two slide halves (master+UID → static keys) |
| `kdf-phase-b` / `-b-1` / `-b-2` | Phase B full + two slide halves (session keys) |
| `kdf-phase-c` | Phase C — cryptograms (card-cg gate + host-cg) |
| `kdf-phase-d` | Phase D — A003 AES-CBC(IV=0,M2) + cleanup |
| `flow-2-provisioning` | Full end-to-end (Word full-page) |
| `flow-2-provisioning-1` / `-2` | Flow 2a session establishment / 2b personalize & finalize (slides) |

### docs/diagrams/Transport/ (2 sets)

| File | Shows |
| --- | --- |
| `klms-connection-1` | Connection 1/2: mTLS handshake with certificate validation (server chain + client cert) + OAuth2 bearer token |
| `klms-connection-2` | Connection 2/2: seed → wrapper key (both sides, KDF) + AES-256-CBC container payload transport |

### docs/diagrams/HSM_Backup/ (5 sets)

| File | Shows |
| --- | --- |
| `hsm-topology` | Deployment + key placement: left custody column (NXP→NitroHSM→YubiHSM-1→YubiHSM-2 backups), right runtime cluster (Ford→VMs→YubiHSMs); AES-ECB arrows side-routed into the NitroHSM |
| `hsm-backup-pattern` | Universal transfer ceremony: ECIES (ECDH P-256 + HKDF + AES-256-GCM), ciphertext-only |
| `decryption-key-create-and-backup` | Ford decrypt key: generated in YubiHSM-1, pubkey to Ford, ECIES backup to YubiHSM-2 |
| `nxp-master-key-ceremony` | NXP master key: EC P-256 import keypair on NitroHSM, NXP ECIES-wraps M, decrypt-inside |
| `nxp-master-key-backup` | NXP master key backup: NitroHSM → YubiHSM-1, same ECIES ceremony |

## Rendering

```sh
# from the repo root — renders .svg + .png next to each .puml
python scripts/render-puml.py docs/diagrams/KDF
python scripts/render-puml.py docs/diagrams/Transport
python scripts/render-puml.py docs/diagrams/HSM_Backup

# local alternative (needs java + plantuml.jar)
plantuml -tpng -tsvg <file>.puml
```

Rendered via the public PlantUML server (deflate + map6 encoder).

id: 1fbaa70f2fb94ffcaabbeca7b39482da
parent_id: 61ba8f290b7b4faf9199916387419665
created_time: 2026-06-30T11:39:29.304Z
updated_time: 2026-08-21T05:53:20.240Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1782819569304
user_created_time: 2026-06-30T11:39:29.304Z
user_updated_time: 2026-08-21T05:53:20.240Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
is_locked: 0
extracted_resource_ids: 
type_: 1