Merge commit 'refs/pull/2036/head' of https://github.com/BitBoxSwiss/bitbox02-firmware
What changed, and why it matters
This commit improves how the BitBox02 hardware wallet generates the secret seed used to back up cryptocurrency. It adds an extra source of randomness—derived from the user's password—into the seed creation process. The change also documents that the seed already mixes randomness from the device's main chip, its secure chip, and factory-installed randomness. There is no direct evidence in the commit that this fixes a known exploitable vulnerability; it appears to be a defense-in-depth improvement to make the seed harder to predict or weaken.
Treat as a routine hardening improvement rather than an urgent security fix. Review the full PR #2036 context and any release notes to confirm whether this addresses a reported weakness. Continue normal firmware QA and ensure the password hashing function used for `password_salted_hashed` is robust.
Security signals we found
Adds password-derived entropy to seed generation (defense-in-depth)
Clarifies existing multi-source entropy mixing (MCU TRNG, secure chip TRNG, factory randomness)
No direct vulnerability or exploit mechanism shown in diff
No CVE, advisory, or security changelog language present in commit
Evidence from the diff
The patch modifies create_and_store_seed in keystore.rs so the generated seed is XOR-mixed with password_salted_hashed in addition to the existing host_entropy. It also updates comments in random.rs and keystore.rs to clarify that seed entropy already combines MCU TRNG, secure-chip TRNG, and factory randomness. The actual functional change is small: a few lines adding password_salted_hashed to the XOR mixing. No buffer overflow, memory-safety bug, or cryptographic flaw is directly visible in the diff.
Changed components
src/rust/bitbox02-rust/src/keystore.rssrc/rust/bitbox-core-utils/src/random.rsBitBox02 seed generation / keystore subsystemInspect captured patch +9 / −3
### src/rust/bitbox-core-utils/src/random.rs
@@ -13,10 +13,12 @@ pub fn random_32_bytes_with_mixin(
let mut mixed = zeroize::Zeroizing::new([0u8; 32]);
hal_random.mcu_32_bytes(&mut mixed);
+ // Mix MCU TRNG entropy with secure chip TRNG entropy.
for (byte, mixin_byte) in mixed.iter_mut().zip(mixin.iter()) {
*byte ^= *mixin_byte;
}
+ // Mix in factory randomness.
let factory_randomness = hal_random.factory_randomness();
for (byte, factory_randomness_byte) in mixed.iter_mut().zip(factory_randomness.iter()) {
*byte ^= *factory_randomness_byte;
### src/rust/bitbox02-rust/src/keystore.rs
@@ -570,9 +570,9 @@ pub async fn copy_bip39_seed(
.map_err(|_| ())
}
-/// Generates the seed, mixes it with host_entropy, and stores it encrypted with the
-/// password. The size of the host entropy determines the size of the seed. Can be either 16 or 32
-/// bytes, resulting in 12 or 24 BIP39 recovery words.
+/// Generates the seed, mixes it with host_entropy and password_salted_hashed, and stores it
+/// encrypted with the password. The size of the host entropy determines the size of the seed.
+/// Can be either 16 or 32 bytes, resulting in 12 or 24 BIP39 recovery words.
/// This also unlocks the keystore with the new seed.
pub async fn create_and_store_seed(
hal: &mut impl crate::hal::Hal,
@@ -584,6 +584,10 @@ pub async fn create_and_store_seed(
return Err(Error::SeedSize);
}
+ // Generate seed which already includes:
+ // * Entropy from the secure chip TRNG.
+ // * Entropy from the MCU TRNG.
+ // * Entropy set during factory installation.
let mut seed_vec = bitbox_core_utils::random::random_32_bytes_from_hal(hal).await?;
let seed = &mut seed_vec[..seed_len];
Why this scored 29/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.