Keyfob Flow 1 — Content Supply: Ford IVSS/GIVIS → Clypeum KLMS

# Keyfob Flow 1 — Content Supply: Ford IVSS/GIVIS → Clypeum KLMS

> The **OEM → supplier content-delivery plane**: how Ford's backend ships
> per-fob provisioning data to Clypeum's KLMS, encrypted to a keypair generated
> in the NetHSM, and maintained as a watchdog-governed cache. This flow carries
> **application/personalization content only** — it does **not** touch the SCP03
> master key or static keys (those are derived in Flow 2). Companion: **"Keyfob
> Flow 2 — Provisioning: Station ↔ Key Fob ↔ Clypeum"**.

> **Why `uid` matters here:** in Flow 2 the station sends **only the UID**, so the
> KLMS must be able to resolve a fob's content by UID. Therefore the **UID is the
> cache index key**, and each package **must** include the UID.

---

## 1. Actors

| Actor | Role |
|---|---|
| **Ford IVSS / GIVIS** (OEM backend) | Holds per-fob data (FESN, SPID, certs, device key); builds + encrypts **bundles**; ships to Clypeum |
| **Clypeum KLMS** (supplier) | Inventory **watchdog**; fetches bundles; asks the NetHSM to decrypt; caches decrypted **packages** indexed by **UID** |
| **NetHSM** (Clypeum-side) | Holds the **bundle-decryption private key** (generated inside it); performs bundle decryption |

> This is an **asynchronous** plane, fully decoupled from the factory line. The
> watchdog keeps ≥ **2 weeks of production** buffered so provisioning never blocks
> on Ford-side latency/availability.

---

## 2. Trust & invariants

- The **bundle keypair is generated in the NetHSM**; the **private key never
  leaves** it. Ford encrypts bundles with the exported **public key**.
- Per-fob content (including the sensitive device private key, A003) is
  **encrypted in transit** inside the bundle. Plaintext appears only inside the
  NetHSM-decrypt step and the trusted KLMS cache.
- **No SCP03 material** (master key, static keys, S-DEK) is involved here — that
  is Flow 2's concern. The device private key here is *content*, later wrapped
  with S-DEK during provisioning.

---

## 3. One-time setup

| # | From → To | Message | Data |
|---|---|---|---|
| 1.0 | NetHSM → Ford IVSS | export bundle-encryption public key | HSM-generated keypair; **private key never leaves**; Ford provisions the public key on its encrypting side |

---

## 4. Per-fob package (the unit of content)

```jsonc
{
  "uid":         "00002317229409204524",    // 10-byte JCOP UID — REQUIRED (KLMS cache index key)
  "fesn":        "1KM0001E",                 // serial
  "spid":        "59918C0096F859EC8BF6DA454E2E554A14DD4BD1", // → DGI A001
  "device_cert": "<DER hex>",                // → DGI A002
  "private_key": "<32-byte P-256 scalar>",   // → DGI A003 (S-DEK-encrypted later, in Flow 2)
  "irk":         "<16-byte hex>"             // → DGI A006 (BLE)
}
```
> Factory-wide **A004 (ICA)** and **A005 (CMS/Root)** certs are shared/static —
> delivered once (not per-package) and stored at the KLMS.

---

## 5. Bundle

A **bundle** = many per-fob packages, encrypted to the NetHSM public key:

```
bundle = Enc_to_pubHSM( packages[], metadata{ batch_id, count, created_at } )  +  Sig_Ford
```

---

## 6. Message table (EA sequence)

| # | From → To | Message | Data |
|---|---|---|---|
| 1.0 | NetHSM → Ford IVSS | export public key | bundle-encryption keypair; private key stays in HSM |
| 1.1 | Ford IVSS → Clypeum | deliver encrypted bundle | `Enc(packages) to pubHSM` (+ Ford sig); push or pull |
| 1.2 | Clypeum → NetHSM | decrypt bundle | ciphertext |
| 1.3 | NetHSM → Clypeum | decrypted packages | per-fob packages → cache (plaintext, trusted service) |
| 1.4 | Clypeum (self) | cache + index **by UID** | index `uid → {fesn, spid, certs, keys}`; stock counter++ |
| 1.5 | watchdog → Ford IVSS | request more bundles | when `stock < 2-week threshold` |

---

## 7. ASCII overview

```
Ford IVSS / GIVIS                Clypeum KLMS (watchdog)          NetHSM
────────────────────────────────────────────────────────────────────────
 (1.0) ◄── export bundle pub key ───────────────────────────────── generated keypair
                                                                    (privkey never leaves)
 encrypt bundle of packages
 (1.1) ──── deliver Enc(packages) ────►
                                     (1.2) decrypt bundle ──────────►
                                     (1.3) ◄── decrypted packages ────
                                     (1.4) cache + index by UID (→fesn/spid/keys)
                                     (1.5) stock < 2-wk? ──► request more bundles
```

---

## 8. Open decisions

- [ ] Bundle encryption scheme (RSA-OAEP / ECIES / AES-KW) + key size.
- [ ] **Push** (Ford pushes) vs **pull** (Clypeum fetches) + cadence/trigger.
- [ ] **2-week stock sizing** (line rate × hours × margin) + low-water mark.
- [ ] Bundle **signature** (Ford signing key) for authenticity/integrity.
- [ ] Inventory/availability **API** between the Clypeum watchdog and Ford IVSS.
- [x] ~~Is `uid` in packages?~~ → **Yes — required.** It is the KLMS cache index
      key (Flow 2 sends only the UID, so content must be resolvable by UID).
- [ ] UID uniqueness per fob (confirm the 10-byte JCOP UID is unique across the fleet).
- [ ] Failure/retry semantics; partial-bundle / duplicate handling.
- [ ] Cache storage: encrypted-at-rest vs plaintext (trusted service) + retention.

id: 67dacd63422b4accbe2949fc7ebd0d24
parent_id: 61ba8f290b7b4faf9199916387419665
created_time: 2026-06-30T08:04:42.460Z
updated_time: 2026-07-01T11:06:11.723Z
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: 1782806682460
user_created_time: 2026-06-30T08:04:42.460Z
user_updated_time: 2026-07-01T11:06:11.723Z
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