Mix secure element entropy into seed generation
What changed, and why it matters
This commit strengthens how the COLDCARD wallet creates the master secret (seed) by blending randomness from the main microcontroller's true random number generator with additional randomness from two separate secure-element chips. Previously the seed relied only on the microcontroller's TRNG. The change is a defensive hardening measure: even if the TRNG were biased or partially compromised, the secure elements' independent entropy would still contribute unpredictability. The commit also documents a separate bugfix for detecting random-number-generator fault flags and failing safely.
Treat as a positive security hardening patch. Users should upgrade when the release becomes available, especially those who rely on newly generated wallets. No immediate incident response is warranted because the change is defensive and there is no evidence of an exploited vulnerability. Reviewers may also want to verify that callgate.read_rng() is itself robust and that concatenation-before-hashing is an approved combiner in the device's threat model.
Security signals we found
Entropy source diversification for master seed generation
Use of independent secure-element TRNGs alongside STM32 TRNG
Defense-in-depth against TRNG bias or failure
Related RNG fault-detection bugfix in same changelog
Explicit vendor labeling as 'Security Improvement'
Evidence from the diff
In shared/seed.py, generate_seed() now calls callgate.read_rng(1) and callgate.read_rng(2) to obtain entropy from Secure Element 1 (32 bytes) and Secure Element 2 (8 bytes), concatenates them with the existing 32 bytes from ngu.random.bytes (STM32 TRNG), and hashes the combined buffer with double SHA-256. The previous implementation hashed only the TRNG output. The change is a security improvement, not a fix for a known exploitable vulnerability, and the changelog explicitly labels it as such. A related bugfix in the same changelog addresses RNG_SR_SEIS/RNG_SR_SECS fault detection.
Changed components
shared/seed.pyMaster seed generation routine (generate_seed)COLDCARD secure elements (SE1/SE2)STM32 TRNG subsystemInspect captured patch +11 / −3
### releases/Next-ChangeLog.md
@@ -4,6 +4,8 @@ This lists the new changes that have not yet been published in a normal release.
# Shared Improvements - Both Mk and Q
+- Security Improvement: Master seed generation mixes entropy from both Secure
+ Elements with the STM32 TRNG (previously TRNG only).
- Bugfix: Detect RNG_SR_SEIS and RNG_SR_SECS, retry safely, and fail closed on persistent faults.
- Bugfix: Prevent access to Seed Vault entries through Seed XOR restore in Delta Mode. Thanks to
Rety for reporting this.
### shared/seed.py
@@ -600,13 +600,19 @@ async def ephemeral_seed_generate_from_dice(nwords):
await set_ephemeral_seed_words(words, origin='Dice')
def generate_seed():
- # Generate 32 bytes of best-quality high entropy TRNG bytes.
+ # Generate 32 bytes of best-quality high entropy from independent sources.
+ import callgate
seed = ngu.random.bytes(32)
assert len(set(seed)) > 4 # TRNG failure
- # hash to mitigate any possible bias in TRNG
- return ngu.hash.sha256d(seed)
+ a = callgate.read_rng(1) # SE1
+ b = callgate.read_rng(2) # SE2
+ assert len(a) == 32
+ assert len(b) == 8
+
+ # hash to combine the sources and mitigate any possible bias
+ return ngu.hash.sha256d(seed + a + b)
async def make_new_wallet(nwords):
# Pick a new random seed.Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.