Keyfob Station — SCP03 / KLMS Flow Reference

# Keyfob Station — SCP03 / KLMS Flow Reference
ID: fa9e72ee12554f978a86ab3f7888cc63
Notebook ID: 283dd54f183a4ce69366648f091336d1
Created: 1782487881636
Updated: 1782802444698
Is Todo: No
Tags: rust, scp03, nfc, ford, active-project

---

# Keyfob Station — SCP03 / KLMS Flow Reference

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

## Mode A — Production: Clypeum-orchestrated, session-key offload

**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, the NetHSM
  decrypts them, and a decrypted-package cache is kept at ≥ **2 weeks** of stock.
  *No SCP03 keys here.*
- **Flow 2 — Provisioning (real-time):** the station sends the fob UID + handshake
  to Clypeum via a **DLL over mTLS**. Clypeum looks up cached content and uses the
  NetHSM to derive **static keys (KDF3, master+UID)** → **session keys** +
  cryptograms + A003 S-DEK encryption, returning a **container** (session keys +
  pre-encrypted content). The station then runs EXTERNAL AUTHENTICATE → STORE DATA
  → lifecycle → post-perso → zeroize.

**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 by Clypeum (`card_cryptogram` check) before keys issue.

**Implemented as (our boundary):**
- `Scp03Channel::establish_from_session_keys` — inject the container's session keys.
- `KlmsProvisioner` — rejects items flagged `encrypt_with_dek=true`.
- `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, request/response JSON, and ASCII 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`. 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-07-01T11:06:11.796Z
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-07-01T11:06:11.796Z
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
type_: 1