id: 3e6a706170634861bd5880b96ca68380
parent_id: 
item_type: 1
item_id: 8d45e6d88cfa449dba47be00ce6a4608
item_updated_time: 1786726740996
title_diff: "[{\"diffs\":[[1,\"Production (Files) Reference Flow\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":33}]"
body_diff: "[{\"diffs\":[[1,\"# Production (Files) Reference Flow\\\n\\\n## Known-good flow — fast fob detection, reliable provisioning, re-install + retry.\\\n\\\n### Card Detection\\\n- `NfcMonitor::start()` — PC/SC event loop, polls readers every 500ms\\\n- On `CardPresent` → `connect_with_retry(5)` + `cold_reset()` → provision\\\n\\\n### Provisioning Pipeline (`production.rs::run_production`)\\\n1. **Connect** — `connect_with_retry(reader_name, 5)` with 200ms backoff, then `cold_reset()`\\\n2. **Keys** — B252 profile from `dev_profiles.toml` → `Scp03StaticKeys { enc, mac, dek }`\\\n3. **Source** — `FileContainerSource::new()` reads container dir:\\\n   - `FESN.txt` → SPID (DGI A001, 40 hex ASCII bytes)\\\n   - `irk_keyfob.key` → base64 → IRK (DGI A006, 16 bytes)\\\n   - `keyfob_private.der` → `extract_ec_scalar()` → 32-byte scalar (DGI A003, DEK-encrypted)\\\n   - `keyfob_public.der` → device cert (DGI A002)\\\n   - Static ICA cert (DGI A004), CMS root cert (DGI A005)\\\n4. **Provisioner::new(transport, source, config).run()**:\\\n   - `transport.uid()` — PC/SC attribute (not APDU)\\\n   - `source.fetch(&uid)` — async, returns `ProvisioningInput`\\\n   - **SELECT ISD** — `00 A4 04 00 00` (empty AID, resets CM routing)\\\n   - **SELECT KF** — `00 A4 04 00 A0 00 00 08 57 00`\\\n   - **INITIALIZE UPDATE** — `80 50 00 00 <8-byte host challenge> 00`\\\n   - **Parse response** → card challenge, card cryptogram, key version, seq counter\\\n   - **Derive session keys** — `SessionKeys::derive(enc, mac, host_challenge, card_challenge)`\\\n   - **EXTERNAL AUTHENTICATE** — C_MAC level (P1=01), wraps host cryptogram\\\n   - **STORE DATA blocks** — DGI streams split into blocks, each wrapped with SCP03 MAC\\\n     - Block 0: DGI A003 (private key, DEK-encrypted, 48 bytes → padded to 48)\\\n     - Block 1: DGI A001 (SPID, 40 hex ASCII bytes)\\\n     - Block 2: DGI A002 (device cert, DER)\\\n     - Block 3: DGI A004 (ICA cert, DER)\\\n     - Block 4: DGI A005 (CMS root cert, DER)\\\n     - Block 5: DGI A006 (IRK, 16 bytes)\\\n   - **Lifecycle transition** — `84 E2 80 <next_p2> 00` (STORE DATA P1=80, P2=incremented)\\\n   - **Post-personalization** (raw, no SM):\\\n     - `00 DB 00 00 0A 01 01` (enable UICC)\\\n     - `00 DB 00 00 0B 01 01` (enable BLE)\\\n5. **Validate** — `connect_with_retry(5)` + `cold_reset()` → `validate_only_verbose()`:\\\n   - SELECT KF: `00 A4 04 00 A0 00 00 08 57 00`\\\n   - Read certs via GET DATA tag list: `00 CB 3F FF 05 5C 03 <tag> 00`\\\n     - `5FC101` = KF cert, `5FC102` = ICA cert, `5FC103` = CMS cert\\\n   - Read FESN: `00 CA 00 0A 00` → P2=0x0A\\\n   - Read SPID: `00 CA 00 09 00` → P2=0x09\\\n   - General Authenticate: `00 87 11 9E` with 32-byte challenge → 64-byte ECDSA sig\\\n   - Verify ECDSA P-256 signature against device cert\\\n\\\n### Retry Logic\\\n- Up to `max_attempts` (default 3)\\\n- On failure: reconnect → `applet_reset::run()` (SCP03 auth, delete KF, install KF) → re-provision\\\n- On validate failure: retry\\\n\\\n### Key Observations\\\n- `cold_reset()` after every connect for clean card state\\\n- `connect_with_retry(5)` with 200ms backoff for flaky NFC\\\n- Single ISD SELECT + single INIT UPDATE per provisioning attempt\\\n- Private key: 32-byte EC scalar extracted from PKCS#8 DER, then DEK-encrypted (ISO 9797-1 M2)\\\n- DGI order: A003, A001, A002, A004, A005, A006\\\n- Security level: C_MAC (P1=01 in EXTERNAL AUTHENTICATE)\\\n- Post-perso only after successful lifecycle transition\\\n\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":3283}]"
metadata_diff: {"new":{"id":"8d45e6d88cfa449dba47be00ce6a4608","parent_id":"beb251c3b3f9490285e6cb68942a5145","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":1786605587471,"markup_language":1,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":0},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-14T17:00:00.707Z
created_time: 2026-08-14T17:00:00.707Z
is_locked: 0
type_: 13