OSC-2026-0005 · github.com/KeystoneHQ/keystone3-firmware
info clean-run claude-fable-5 2026-08-04 signed: nostr
- Repository
- github.com/KeystoneHQ/keystone3-firmware
- Commit
- 31f1fa88a522f492b9ad6260c4c3e316bd209b32
- Scope path
- src/managers/keystore.c
- Model
- claude-fable-5
- Harness
- claude-code
- Prompts
- prompts/entropy-rng-audit-v1.md
- Independent runs
- 1
- Transcript sha256
- a0f8d42e23dd7721e4677db6fa89235d85fda82682b1decc24b3359e1ef94780
- Auditor
- TheIcarusWings (theicaruswings)
- Signature
- nostr-schnorr · npub19tzp8lf3klmqj3dz9mz0qnuvjp7uyy9993gmljmyaxs8phztj7wsnujvq5
Scope. AMENDED 2026-08-04 (original in git history). Seed-entropy generation at HEAD 31f1fa88: GenerateEntropy (src/managers/keystore.c:75), the read path of the MH1903 TRNG driver (src/driver/drv_trng.c), and whether raw entropy can leak via debug output. In scope: number and independence of entropy sources, KDF mixing, error handling of the secure-element RNG calls, debug-gating, buffer clearing. EXPLICITLY NOT EXAMINED: the TRNG driver s status/attack-bit handling - TrngGet was read but its treatment of the MH1903 TRNG ATTACK status bit was not reviewed; a later independent audit (OSC-2026-0017) found it is never inspected, which I have since verified. Also not in scope: the rest of the firmware (PSBT/signing, USB/QR transport, secure-element provisioning, bootloader, vendored external/ libraries), the physical quality of the hardware RNGs, and the Rust components under rust/.
Findings
info OSC-2026-0005-F1 unreviewed
No weakness found in scope; the design specifically resists the Coldcard failure class. Seed entropy is derived from THREE independent hardware sources - the MCU TRNG (SE_GetTRng), the DS28S60 secure element, and the ATECC608B secure element - each folded in via a separate HKDF step with the running value chained forward, and seeded initially from a password-derived salt (HashWithSalt). Degrading or compromising any single source still leaves two independent hardware sources feeding the chain, which is exactly what Coldcard lacked. Raw entropy is never printed in production: every KEYSTORE_PRINT_ARRAY expands to nothing because KEYSTORE_DEBUG is hardcoded to 0 in source (keystore.c:36) rather than set by a build flag, so a build configuration cannot silently enable it - the inverse of the MICROPY_HW_ENABLE_RNG=0 build-flag failure. Working buffers are cleared via CLEAR_ARRAY on all paths. Observation (not a defect): error handling is asymmetric - SE_GetDS28S60Rng and SE_GetAtecc608bRng are checked with CHECK_ERRCODE_BREAK but SE_GetTRng's return value is unchecked, so a silent failure there would mix in a stale buffer. Not exploitable as written, since the two checked sources are still mixed in afterward; noted only because checking all three would make the 'at least N good sources' property explicit rather than incidental.