Security News

Cybersecurity news aggregator

🔓
HIGH Vulnerabilities Reddit r/netsec

Predictable RNG Fallback and 32-Bit Reseed in COLDCARD Firmware

A critical RNG integration error in COLDCARD firmware causes the `ngu.random` function to use a deterministic software fallback (Yasmarang) instead of the hardware RNG, making wallet generation predictable under certain conditions. Affected firmware versions are Mk2/Mk3 v4.0.0–v4.1.9, Mk4 production v5.0.0 onward, and all production firmware for Q and Mk5 models. The exposure depends on the firmware version active when a secret was generated; upgrading does not retroactively repair an existing seed.
Read Full Article →

~/posts/ predictable-rng-fallback-and-32-bit-reseed-in... $ cd .. $ cat content.md By Block Bitcoin Engineering and Security, in collaboration with anonymous security researchers. Summary Following reports from COLDCARD users, and working alongside other security researchers, Block’s Bitcoin Engineering and Security teams root-caused vulnerabilities that allow for theft of Bitcoin from COLDCARD users. This analysis is based on our current understanding of the situation. We have not done full empirical testing to confirm exploitability. We are publishing this advisory early, because active exploitation is under way. This analysis is the opinion of Block, and based on our internal research; we recommend looking at Coinkite's definitive report once available. This report does not pertain to Block products; no Block products or customers are affected by this vulnerability. COLDCARD firmware contains an RNG integration error that causes ngu.random to use MicroPython's deterministic Yasmarang fallback instead of the STM32 hardware RNG. The production board configuration defines MICROPY_HW_ENABLE_RNG as zero because COLDCARD provides a separate hardware-RNG wrapper . Libngu incorrectly checks whether that macro is defined rather than whether it is enabled . The build therefore succeeds, and libngu binds to MicroPython's rng_get() . With the macro set to zero, that function is a Yasmarang software generator initialized from the MCU UID and timer registers . The consequences differ by device: Mk2/Mk3 v4: No cryptographic entropy is added to ngu.random . For a known UID, timer state and call history, wallet generation is deterministic. Mk4/Q/Mk5: Boot adds secure-element entropy, but hashes it and retains only four bytes. reseed() then replaces only one 32-bit Yasmarang state word. For a fixed fallback state and call history, there are at most 2^32 securely distinguished output streams. Wallet generation hashes the resulting 32 bytes, but deterministic hashing cannot increase the number of possible seeds. Affected products Device Firmware used when generating the secret Assessment Mk1 All released firmware through v3.0.6 Outside this regression Mk2 Through v3.2.2 Uses the direct STM32 hardware RNG Mk2 v4.0.0–v4.1.9 Confirmed vulnerable path; no secure reseed Mk3 Through v3.2.2 Uses the direct STM32 hardware RNG Mk3 v4.0.0–v4.1.9 Confirmed vulnerable path; no secure reseed Mk4 Production v5.0.0 onward Fallback remains; secure reseed is limited to 32 bits Q All production firmware Same Mk4 fallback and reseed construction Mk5 All production firmware Same current Mk firmware construction Exposure depends on the firmware used when a secret was generated, not the device's manufacturing date. Upgrading does not retroactively weaken or repair an existing seed. Impact An attacker who can determine or sufficiently constrain the device UID, timer state and RNG-call history can reproduce the fallback stream offline. A wallet xpub, address or generated public key provides a candidate-validation oracle. Successful recovery of a wallet seed or private key permits theft of all associated funds. For Mk2/Mk3 v4, there is no cryptographically generated secret input to enumerate. For current devices, once the fallback state and call history are fixed, the remaining secure-element-derived search space is at most 2^32 , averaging approximately 2^31 candidate trials. This does not mean every remote attacker can immediately recover every seed. Practical cost depends on available UID information, boot timing, prior RNG calls and derivation cost. No end-to-end brute-force benchmark is claimed here. Impact due to seed export If you exported a seed generated in a vulnerable coldcard, moving it to another wallet, then that same insecure seed is still affected. Technical details 1. Production disables MicroPython's hardware-RNG implementation The relevant board headers contain: c 1 // We have our own version of this code. 2 # define MICROPY_HW_ENABLE_RNG ( 0 ) Locations: stm32/COLDCARD/mpconfigboard.h:76-77 stm32/COLDCARD_MK4/mpconfigboard.h:77-78 stm32/COLDCARD_Q1/mpconfigboard.h:79-80 This is the normal compiled board configuration, not an environment variable or unusual build override. COLDCARD does provide a separate hardware-RNG implementation. Its random_buffer() reads the STM32 RNG peripheral and fails on timeout or repeated samples. Python exposes that implementation as ckcc.rng_bytes . 2. Libngu checks the macro incorrectly Libngu selects its STM32 entropy function with: c 1 extern uint32_t rng_get ( void ) ; 2 # define CHIP_TRNG_32 ( ) rng_get ( ) 3 4 # ifndef MICROPY_HW_ENABLE_RNG 5 # error "get a HW TRNG plz" 6 # endif #ifndef verifies only that the macro exists. It does not reject a macro whose value is zero. The board-local implementation exports random32() and random_buffer() , not a global rng_get() . Consequently, libngu's reference resolves to MicroPython's implementation. 3. MicroPython compiles the software fallback MicroPyth...

Share this article