id: ab7ad63b93f248ff94155f25acbe1f86
parent_id: 
item_type: 1
item_id: 46c5c42fcaec4f298b5cac05534bca67
item_updated_time: 1785830142668
title_diff: "[{\"diffs\":[[1,\"Production Windows Configuration for Key Fob Provisioning\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":57}]"
body_diff: "[{\"diffs\":[[1,\"# Production Windows Configuration for Key Fob Provisioning\\\n\\\n## Problem\\\n\\\nACS ACR1281U-C1 reader on Windows: the first `CLA=0x80` (GlobalPlatform) APDU takes **23 seconds** because Windows Smart Card Service (SCardSvr) searches Windows Update for a smart card minidriver on every proprietary command. The search times out after ~23s (network SYN retry).\\\n\\\nThis makes the 7-second contactless provisioning budget impossible.\\\n\\\n## Root Cause\\\n\\\nSCardSvr intercepts `CLA=0x80` commands and attempts to load a minidriver via Windows Update. The network query times out after ~23 seconds. After the first command, the result is cached and subsequent commands return in ~20ms.\\\n\\\n## Fix: Registry Settings (run as Admin)\\\n\\\n### 1. Disable Windows Update driver search (eliminates the 23s delay)\\\n\\\n```\\\nHKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\DriverSearching\\\n  SearchOrderConfig = 0 (DWORD)\\\n\\\nHKLM\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\DriverSearching\\\n  DriverSearchMode = 0 (DWORD)\\\n  SearchOrderConfig = 0 (DWORD)\\\n```\\\n\\\n### 2. Disable Smart Card Credential Provider node enumeration\\\n\\\n```\\\nHKLM\\\\SOFTWARE\\\\Policies\\\\Microsoft\\\\Windows\\\\SmartCardCredentialProvider\\\n  TurnOffSmartCardNode = 1 (DWORD)\\\n```\\\n\\\n### 3. Restart Smart Card Service\\\n\\\n```powershell\\\nRestart-Service SCardSvr -Force\\\n```\\\n\\\nSystem restart recommended after applying.\\\n\\\n## Deployment Script\\\n\\\n`scripts/configure-windows.ps1` in the repo automates all three steps.\\\n\\\n## Code-Level Requirements (implemented)\\\n\\\n- **Per-thread `SCARDCONTEXT`** - monitor and reader threads use separate contexts\\\n- **`SCARD_STATE_UNAWARE`** - initial state in `SCardGetStatusChange`\\\n- **Single INITIALIZE UPDATE** - P1=0x00 only, never retry with other key versions\\\n- **Case-4 APDU with `Le=0x00`** - card requires the Le byte\\\n- **Correct key version: `P1=0x00`** - uses card default (resolves to 0xFF)\\\n- **SELECT ISD before GP commands** - AID `A000000151000000` (NXP JCOP)\\\n- **Card cryptogram verification** - local check before EXTERNAL AUTHENTICATE (safety gate)\\\n\\\n## Expected Performance\\\n\\\n| Operation | Before Fix | After Fix |\\\n|-----------|-----------|-----------|\\\n| INITIALIZE UPDATE (1st CLA=0x80) | ~23,000ms | ~50ms |\\\n| INITIALIZE UPDATE (subsequent) | ~20ms | ~20ms |\\\n| EXTERNAL AUTHENTICATE | ~20ms | ~20ms |\\\n| SELECT (CLA=0x00) | ~15ms | ~15ms |\\\n| Pseudo-APDU (CLA=0xFF) | ~1ms | ~1ms |\\\n\\\n## Key Fob Details\\\n\\\n- **Card type**: JCOP 4.5 P71 (OEF ID B252)\\\n- **ISD AID**: `A000000151000000` (NXP JCOP, NOT standard GP `A000000003000000`)\\\n- **SCP03 keys**: Shared static (not per-card derived) - `255/1` (ENC), `255/2` (MAC), `255/3` (DEK)\\\n- **ATR**: `3B8580018073C821100E` (ISO 14443-4, Part 4 format)\\\n- **Protocol**: T=1 (contactless ISO 14443-4)\\\n- **Reader**: ACS ACR1281U-C1 DualBoost II, PICC 0 slot (contactless)\\\n- **GP auth counter**: ~15 (estimated), resets on successful auth, does NOT reset on power cycle\\\n\\\n## SCP03 Session Establishment Flow\\\n\\\n1. SELECT ISD (`A000000151000000`) - safe, no counter impact\\\n2. GET DATA IDENTIFY (tag DF28) - safe, returns OEF ID\\\n3. INITIALIZE UPDATE (P1=0x00) - safe, 9000 does not decrement counter\\\n4. Card cryptogram verification (local) - safety gate, no card interaction\\\n5. EXTERNAL AUTHENTICATE (C-MAC) - only sent if step 4 passes\\\n\\\nVerified on real hardware: card cryptogram matched, MAC accepted (9000), counter reset.\\\n\\\n## Provisioning Flow\\\n\\\nContainer folder: `FESN.txt`, `irk_keyfob.key`, `keyfob_private.der`, `keyfob_public.der`\\\nCerts folder: `ica_cert.der`, `cms_root_cert.der`\\\n\\\nPersonalization order (device cert LAST):\\\n1. A003 - Private key (S-DEK encrypted)\\\n2. A001 - SPID\\\n3. A004 - ICA certificate\\\n4. A005 - CMS root certificate\\\n5. A006 - BLE IRK\\\n6. A002 - Device certificate (last, for read-back verification)\\\n\\\nFACTORY transition is separate/explicit - not done during personalization.\\\n\\\n## Lessons Learned\\\n\\\n1. SCardSvr intercepts CLA=0x80 for minidriver search, not the CCID driver\\\n2. The delay is one-time but 23s is unacceptable for 7s budget\\\n3. T=0 protocol corrupts CCID state - never use on contactless\\\n4. SCardReconnect causes card removal - do NOT reconnect during transmit\\\n5. Multiple key versions risk locking the card - always use P1=0x00\\\n6. GET DATA requires SELECT ISD first (returns 6D00 without it)\\\n7. All JCShell scripts use contactless (`/term SCComm:1` = PICC slot)\\\n\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":4265}]"
metadata_diff: {"new":{"id":"46c5c42fcaec4f298b5cac05534bca67","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":1785773901131,"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-04T07:58:49.352Z
created_time: 2026-08-04T07:58:49.352Z
is_locked: 0
type_: 13