Keyfob Station — SCP03 / KLMS Flow Reference

# Keyfob Station — SCP03 / KLMS Flow Reference

> Focused reference for the **modes** and security rationale. Production detail lives in:
> - **"Keyfob Flow 1 — Content Supply: Ford IVSS/GIVIS → Clypeum KLMS"**
> - **"Keyfob Flow 2 — Provisioning: Station ↔ Key Fob ↔ Clypeum"** (updated 2026-08-17 to the REST transport)
>
> For the architecture overview, contacts, and current status see **"Ford EoL Key
> Fob Provisioning System (SCP03)"**.

## Mode A — Production: Clypeum-orchestrated, session-key offload — IMPLEMENTED & HW-VERIFIED

**Goal:** the **master key never reaches the factory floor.** It lives in the
**Clypeum NetHSM** (imported from NXP, never exported); the NetHSM does **AES
primitives only** and the **KLMS orchestrates** SCP03.

Two independent planes:

- **Flow 1 — Content Supply (async):** Ford IVSS/GIVIS ships per-fob **content**
  (FESN, SPID, certs, device key) as encrypted **bundles** (encrypted to a keypair
  generated in the NetHSM). The Clypeum **watchdog** fetches bundles and the NetHSM
  decrypts them into their backend. *No SCP03 keys here.*
- **Flow 2 — Provisioning (real-time):** the station identifies the fob (SELECT ISD
  + GET DATA → OEF/UID), runs INITIALIZE UPDATE, and requests a container via
  **REST over mTLS** (`POST /cryptoContainers`, form: typeID/seedUUID/productSerial +
  `extra` JSON carrying the handshake metadata; seed from `POST /seeds` at connect).
  The KLMS derives keys via the NetHSM and returns a **binary Clypeum container**
  (13 TLV fields: session keys, host cryptogram, content incl. the card-ready
  S-DEK-encrypted A003). The station verifies the card cryptogram locally, then
  EXTERNAL AUTHENTICATE → STORE DATA → lifecycle → post-perso → zeroize.

**Status (2026-08-17):** implemented in `kf-dev-station`'s KLMS panel and verified
end-to-end on hardware (two fobs, GA ECDSA signatures passing). `kf-prod-station`
still runs the mock client.

**What the station holds (RAM-only, zeroized):** ephemeral session keys + the
pre-encrypted A003 ciphertext. **Never** the master key, static keys, or S-DEK.

**Security properties:**
- A compromised station cannot derive keys for other UIDs (no master/static keys).
- A leaked session key compromises only that one finished session.
- The card is authenticated twice: by the KLMS (`card_cryptogram` gate, Phase C)
  **and locally by the station** before EXTERNAL AUTHENTICATE.

**Implemented as (our boundary):**
- `klms_client.rs` (kf-dev-station) — REST client: token auth, seed, generate,
  report_usage (wired pending KLMS status semantics).
- `Scp03Channel::establish_from_session_keys` — inject the container's session keys.
- `ContainerTlvSource` — tag-keyed field extraction; card-ready A003 forwarded
  untouched (CBC+IV0+M2, verified 2026-08-17).
- `kf-klms` — `KlmsClient` trait + `MockKlmsClient` (emulates KLMS+NetHSM).
- KLMS internals (watchdog, cache, NetHSM orchestration) are Clypeum's.

> See the two Flow notes for full message tables and the PlantUML note for diagrams.

---

## Mode B — Development: static keys inline (summary)

Dev samples (OEF B212) ship with a known static SCP03 key set → Phase 2 only,
locally, via `kf-dev-station` (keys from `dev_profiles.toml`). The Phase-1 KDF can
also be exercised with the dev master key + static UID held locally. See the main
note + NXP contacts for dev samples.

## Mode C — Firmware flashing (SEMS Lite)

`kf-dev-station` plays a SEMS Lite load-file script to (re)flash firmware; native
player pending the script-format example. Frequent lab flow: flash firmware →
provision.

id: fa9e72ee12554f978a86ab3f7888cc63
parent_id: 61ba8f290b7b4faf9199916387419665
created_time: 2026-06-26T15:31:21.636Z
updated_time: 2026-08-17T10:36:26.595Z
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: 1782487881636
user_created_time: 2026-06-26T15:31:21.636Z
user_updated_time: 2026-08-17T10:36:26.595Z
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