From 936a08b725b7f30a7d4e1b8fda5536b1f15e0f2b Mon Sep 17 00:00:00 2001 From: Noah Stiltner Date: Sun, 21 Jan 2024 10:44:16 -0600 Subject: [PATCH 1/3] first go at zeroize for blockrng; I want to try to make it simpler --- rand_core/Cargo.toml | 1 + rand_core/src/block.rs | 63 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/rand_core/Cargo.toml b/rand_core/Cargo.toml index 8c9d902a70..633b49bc18 100644 --- a/rand_core/Cargo.toml +++ b/rand_core/Cargo.toml @@ -33,3 +33,4 @@ serde1 = ["serde"] # enables serde for BlockRng wrapper serde = { version = "1", features = ["derive"], optional = true } getrandom = { version = "0.2", optional = true } zerocopy = { version = "0.7.20", default-features = false } +zeroize = { version = "1.7", optional = true } \ No newline at end of file diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index a8cefc8e40..99848c455e 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -59,6 +59,8 @@ use core::convert::AsRef; use core::fmt; #[cfg(feature = "serde1")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "zeroize")] +use zeroize::{DefaultIsZeroes, Zeroize}; /// A trait for RNGs which do not generate random numbers individually, but in /// blocks (typically `[u32; N]`). This technique is commonly used by @@ -71,7 +73,12 @@ pub trait BlockRngCore { /// Results type. This is the 'block' an RNG implementing `BlockRngCore` /// generates, which will usually be an array like `[u32; 16]`. + #[cfg(not(feature = "zeroize"))] type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default; + /// Results type. This is the 'block' an RNG implementing `BlockRngCore` + /// generates, which will usually be an array like `[u32; 16]`. + #[cfg(feature = "zeroize")] + type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default + DefaultIsZeroes; /// Generate a new block of results. fn generate(&mut self, results: &mut Self::Results); @@ -262,6 +269,12 @@ impl SeedableRng for BlockRng { } } +impl Zeroize for BlockRng { + fn zeroize(&mut self) { + self.results.zeroize(); + } +} + impl> CryptoRng for BlockRng {} /// A wrapper type implementing [`RngCore`] for some type implementing @@ -436,19 +449,41 @@ impl> CryptoRng for BlockRng64 { mod test { use crate::{SeedableRng, RngCore}; use crate::block::{BlockRng, BlockRng64, BlockRngCore}; + #[cfg(feature = "zeroize")] + use zeroize::DefaultIsZeroes; #[derive(Debug, Clone)] struct DummyRng { counter: u32, } + #[cfg_attr(feature = "zeroize", derive(Copy, Clone))] + struct DummyRngResults([u32; 16]); + impl AsRef<[u32]> for DummyRngResults { + fn as_ref(&self) -> &[u32] { + &self.0 + } + } + impl AsMut<[u32]> for DummyRngResults { + fn as_mut(&mut self) -> &mut [u32] { + &mut self.0 + } + } + impl Default for DummyRngResults { + fn default() -> Self { + Self([0u32; 16]) + } + } + #[cfg(feature = "zeroize")] + impl DefaultIsZeroes for DummyRngResults {} + impl BlockRngCore for DummyRng { type Item = u32; - type Results = [u32; 16]; + type Results = DummyRngResults; fn generate(&mut self, results: &mut Self::Results) { - for r in results { + for r in results.as_mut() { *r = self.counter; self.counter = self.counter.wrapping_add(3511615421); } @@ -492,13 +527,33 @@ mod test { counter: u64, } + #[cfg_attr(feature = "zeroize", derive(Copy, Clone))] + struct DummyRng64Results([u64; 8]); + impl AsRef<[u64]> for DummyRng64Results { + fn as_ref(&self) -> &[u64] { + &self.0 + } + } + impl AsMut<[u64]> for DummyRng64Results { + fn as_mut(&mut self) -> &mut [u64] { + &mut self.0 + } + } + impl Default for DummyRng64Results { + fn default() -> Self { + Self([0u64; 8]) + } + } + #[cfg(feature = "zeroize")] + impl DefaultIsZeroes for DummyRng64Results {} + impl BlockRngCore for DummyRng64 { type Item = u64; - type Results = [u64; 8]; + type Results = DummyRng64Results; fn generate(&mut self, results: &mut Self::Results) { - for r in results { + for r in results.as_mut() { *r = self.counter; self.counter = self.counter.wrapping_add(2781463553396133981); } From a1fab6301ccc001ca40296b5fc6f55ce84122601 Mon Sep 17 00:00:00 2001 From: Noah Stiltner Date: Sun, 21 Jan 2024 10:55:05 -0600 Subject: [PATCH 2/3] minimized the changes for zeroize --- rand_core/src/block.rs | 67 +++++++++++------------------------------- 1 file changed, 17 insertions(+), 50 deletions(-) diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index 99848c455e..85d8195003 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -69,16 +69,15 @@ use zeroize::{DefaultIsZeroes, Zeroize}; /// See the [module][crate::block] documentation for details. pub trait BlockRngCore { /// Results element type, e.g. `u32`. + #[cfg(not(feature = "zeroize"))] type Item; + /// Results element type, e.g. `u32`. + #[cfg(feature = "zeroize")] + type Item: DefaultIsZeroes; /// Results type. This is the 'block' an RNG implementing `BlockRngCore` /// generates, which will usually be an array like `[u32; 16]`. - #[cfg(not(feature = "zeroize"))] type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default; - /// Results type. This is the 'block' an RNG implementing `BlockRngCore` - /// generates, which will usually be an array like `[u32; 16]`. - #[cfg(feature = "zeroize")] - type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default + DefaultIsZeroes; /// Generate a new block of results. fn generate(&mut self, results: &mut Self::Results); @@ -269,9 +268,11 @@ impl SeedableRng for BlockRng { } } +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl Zeroize for BlockRng { fn zeroize(&mut self) { - self.results.zeroize(); + self.results.as_mut().zeroize() } } @@ -443,44 +444,30 @@ impl SeedableRng for BlockRng64 { } } +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl Zeroize for BlockRng64 { + fn zeroize(&mut self) { + self.results.as_mut().zeroize() + } +} + impl> CryptoRng for BlockRng64 {} #[cfg(test)] mod test { use crate::{SeedableRng, RngCore}; use crate::block::{BlockRng, BlockRng64, BlockRngCore}; - #[cfg(feature = "zeroize")] - use zeroize::DefaultIsZeroes; #[derive(Debug, Clone)] struct DummyRng { counter: u32, } - #[cfg_attr(feature = "zeroize", derive(Copy, Clone))] - struct DummyRngResults([u32; 16]); - impl AsRef<[u32]> for DummyRngResults { - fn as_ref(&self) -> &[u32] { - &self.0 - } - } - impl AsMut<[u32]> for DummyRngResults { - fn as_mut(&mut self) -> &mut [u32] { - &mut self.0 - } - } - impl Default for DummyRngResults { - fn default() -> Self { - Self([0u32; 16]) - } - } - #[cfg(feature = "zeroize")] - impl DefaultIsZeroes for DummyRngResults {} - impl BlockRngCore for DummyRng { type Item = u32; - type Results = DummyRngResults; + type Results = [u32; 16]; fn generate(&mut self, results: &mut Self::Results) { for r in results.as_mut() { @@ -527,30 +514,10 @@ mod test { counter: u64, } - #[cfg_attr(feature = "zeroize", derive(Copy, Clone))] - struct DummyRng64Results([u64; 8]); - impl AsRef<[u64]> for DummyRng64Results { - fn as_ref(&self) -> &[u64] { - &self.0 - } - } - impl AsMut<[u64]> for DummyRng64Results { - fn as_mut(&mut self) -> &mut [u64] { - &mut self.0 - } - } - impl Default for DummyRng64Results { - fn default() -> Self { - Self([0u64; 8]) - } - } - #[cfg(feature = "zeroize")] - impl DefaultIsZeroes for DummyRng64Results {} - impl BlockRngCore for DummyRng64 { type Item = u64; - type Results = DummyRng64Results; + type Results = [u64; 8]; fn generate(&mut self, results: &mut Self::Results) { for r in results.as_mut() { From 194b831062242fe316ea7ac3523cd9199a5bd776 Mon Sep 17 00:00:00 2001 From: Noah Stiltner Date: Sun, 21 Jan 2024 10:57:19 -0600 Subject: [PATCH 3/3] removed an unnecessary change --- rand_core/src/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rand_core/src/block.rs b/rand_core/src/block.rs index 85d8195003..be1ab512bd 100644 --- a/rand_core/src/block.rs +++ b/rand_core/src/block.rs @@ -470,7 +470,7 @@ mod test { type Results = [u32; 16]; fn generate(&mut self, results: &mut Self::Results) { - for r in results.as_mut() { + for r in results { *r = self.counter; self.counter = self.counter.wrapping_add(3511615421); } @@ -520,7 +520,7 @@ mod test { type Results = [u64; 8]; fn generate(&mut self, results: &mut Self::Results) { - for r in results.as_mut() { + for r in results { *r = self.counter; self.counter = self.counter.wrapping_add(2781463553396133981); }