From 53f8a9f1d65f73780abfca3eb0b09ec86e5c8d8b Mon Sep 17 00:00:00 2001 From: bunnie Date: Fri, 14 Jun 2024 16:12:17 +0800 Subject: [PATCH] apply entropy hardening on boot to kernel as well Shoot for 256 bits minimum entropy in the seed pool, gives us some safety margin over our required 128. note that the pool only gets more entropy over time, as every call to the pool folds more entropy in (roughly 2 bits per call). --- kernel/src/platform/cramium/rand.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/src/platform/cramium/rand.rs b/kernel/src/platform/cramium/rand.rs index 32f103f02..56377dc98 100644 --- a/kernel/src/platform/cramium/rand.rs +++ b/kernel/src/platform/cramium/rand.rs @@ -71,10 +71,13 @@ pub fn init() { TRNG_KERNEL = Some(trng_kernel); } - // now run the CSPRNG a few cycles to fold more entropy into the pool before we start - // to use it for reals. 16 iterations will extract 512 bits out of the TRNG, so even - // if it is somewhat degraded, we'll be in good shape... - for _ in 0..16 { + // Now run the CSPRNG many cycles to fold more entropy into the pool before we start + // to use it for reals. The TRNG is quite low quality, so we run it for 128 cycles. + // Each cycle extracts 64 bits of compressed TRNG state, for 8192 bits total. Estimated + // entropy is around 1 in 32 bits on the compressed entropy feed, so this gets us ~256 bit + // strength on boot. The pool is constantly enhanced as the system runs, so it only improves + // over time. + for _ in 0..128 { let _ = get_u32(); } } @@ -84,7 +87,8 @@ pub fn get_u32() -> u32 { let mut state = LOCAL_RNG_STATE_LSB.load(Ordering::SeqCst) as u64 | (LOCAL_RNG_STATE_MSB.load(Ordering::SeqCst) as u64) << 32; - // XOR in 32 bits of entropy from the HW TRNG pool. + // XOR in entropy from the HW TRNG pool. + // lsb state ^= unsafe { TRNG_KERNEL .as_mut() @@ -92,6 +96,15 @@ pub fn get_u32() -> u32 { .get_u32() .expect("Error in random number generation") } as u64; + // msb + state ^= (unsafe { + TRNG_KERNEL + .as_mut() + .expect("TRNG_KERNEL driver not initialized") + .get_u32() + .expect("Error in random number generation") + } as u64) + << 32; let mut rng = ChaCha8Rng::seed_from_u64(state); let next_state = rng.next_u64();