Keyfob Station — Code Audit Open Items

# Keyfob Station — Code Audit Open Items

Last updated: 2026-08-14 19:05 (week close-out: ae5531f pushed, all notes consolidated into this notebook)

## TOP OPEN — private key cipher mode (ours + theirs, next week)

The card-verified wire format for DGI A003 is **AES-128-CBC, IV=0, ISO 9797-1 M2** over the
32-byte scalar (proven by the HW-verified local-encryption path, `perso.rs::encrypt_with_dek`).
Our meeting agenda told the KLMS "ECB" — wrong for multi-block payloads. The KLMS now delivers
48-byte card-ready blobs as **ECB+M2** → card rejects with `6A 80` at PAYLOAD_DELIVERY.

**Station bridge (ae5531f, in place):** `worker.rs::prepare_card_ready_private_key` —
CBC(IV=0)+M2 blobs are forwarded untouched (target state); ECB+M2 blobs are verified
(M2 + 32-byte scalar) and re-encrypted locally as CBC with a WARN. Misclassification odds
≈2^-128; GA signature check at validation is the end-to-end backstop. **Untested on HW** —
the session ended before a tap after the bridge landed.

**Next week:**
1. Tap-test the bridge (expect WARN ECB→CBC, then full provisioning + GA validation pass)
2. Ask the KLMS team to switch field[8] encryption to AES-128-CBC, IV=0, M2 — then the
   bridge's ECB branch can be removed

## KLMS Team — RESOLVED & OPEN items

**RESOLVED — M5/M10 (2026-08-14):** KLMS delivers field[8] card-ready (48 bytes). Format
detail above. Container generation now returns 201 (their 500 is fixed).

**Still open (external):**

| # | Issue | What's needed |
|---|-------|---------------|
| — | field[8] cipher mode | Switch KLMS to CBC(IV=0)+M2 (see top item) |
| C1 | `accept_invalid_certs` | Valid root CA or fixed cert chain — station side is config-ready (default secure, dev config opts in) |
| — | Empty `cryptoDataContainerId` header | Populate (`validate_cid` ready to enforce) |
| — | Container signature key confirmation | Confirm signing pubkey (`verify_signature` ready to wire) |
| — | Container checksum algorithm unspecified | Spec for header values 0x00–0x03 |
| — | `report_usage` alignment | Status values/payload semantics (method ready, unwired by decision; likely why admin serials are blank) |
| — | 7-vs-10-byte UID | Failing fob returned 7-byte card UID (chip-UID fallback); confirm KLMS expectation |

## 2026-08-14 session log

- KLMS 500 fixed their side → 201 Created; flow ran to PAYLOAD_DELIVERY
- `6A 80` root-caused to ECB-vs-CBC spec error (ours) → bridge committed
- productSerial → chip UID; request-form + response-header debug logging
- Config: `container_type_id` / `key_bundle_type` / `accept_invalid_certs`
- Retry classification: server-stage failures retry once without applet re-install
- Final audit (mechanical + fresh subagent): clippy 0 ×3 variants, 105 tests, fmt/doc clean.
  Findings fixed: ECB test vector was accidentally CBC (conversion path untested) — now
  genuine; two stale comments corrected. Accepted as-is: retry-policy placement in
  nfc_reader (matches codebase conventions), duplicated config-default placeholders (P3).

## Documented as Intentional (won't fix)

IAM empty user/pass (mTLS public client) · textbook RSA verify (Clypeum format) · wrapper KDF
zero LABEL/CONTEXT · KF_APPLET_SELECT_AID copy (dependency direction) · STATIC_KEY_TABLE test
duplication · ISD SELECT variants via `builders::select` · prod-station dev-keys copy ·
ProvisionResult/ProdResult/ValidateResult mirrors.

## Refactoring — COMPLETE

H7 SCP03 handshake ×5, M20 god functions, H2 audit doc (HW-verified) · Audit round 5 (aabf7b6):
error unification, typed StepStatus, C-MAC helper, builders::select, kf-klms tests, fail-closed
validation paths, tag-keyed KLMS fields, panic-safe workers, dep cleanup.

## Remaining open (ours)

- HW tap-test of the ECB→CBC bridge (first item next week)

## Workspace & Notes

- Single canonical location: `D:\Development\Workspaces\rust-workspace\keyfob-station`
  (origin ssh://192.168.1.2, pushed through ae5531f)
- All project notes consolidated in the **Key Fob Station** notebook (9 notes): this audit
  note, Project Status 2026-08-14, KLMS REST API Flow, Container Binary Format, Production
  (Files) Reference Flow, KLMS Known Issues, Locked-Fob Incident, Windows Configuration,
  Implementation Plan (marked IMPLEMENTED). The duplicate "Key Fob Station 2" notebook was
  emptied and deleted 2026-08-14.

## Current state (commit ae5531f)

- All 3 build variants ZERO warnings; clippy/rustfmt/rustdoc clean; 105 tests pass
- Deploy via kfs-prod.bat; debug evidence via RUST_LOG=debug

id: bb3506f46ead40df8a7f965a73339928
parent_id: beb251c3b3f9490285e6cb68942a5145
created_time: 2026-08-13T20:19:34.178Z
updated_time: 2026-08-14T17:00:35.739Z
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: 1786652374178
user_created_time: 2026-08-13T20:19:34.178Z
user_updated_time: 2026-08-14T17:00:35.739Z
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