Skip to main content

rs_matter_stack/
rand.rs

1//! A simple adaptor to convert between `rand_core` V0.6 and `rand_core` V0.9
2//!
3//! A reseeding RNG implementation that wraps an existing RNG and reseeds it after a specified number of generated bytes.
4//! Copied over from the `rand` project which recently retired theirs.
5
6pub use rand_chacha::*;
7pub use reseeding::ReseedingRng;
8
9use crate::matter::crypto::{CryptoRng, RngCore};
10
11mod reseeding;
12
13/// A simple adaptor to convert between `rand_core` V0.6 and `rand_core` V0.9
14pub struct RngAdaptor<T>(T);
15
16impl<T> RngAdaptor<T> {
17    /// Create a new `RandAdaptor` instance wrapping the provided RNG.
18    pub const fn new(rng: T) -> Self {
19        Self(rng)
20    }
21}
22
23impl<T> rand_core09::RngCore for RngAdaptor<T>
24where
25    T: RngCore,
26{
27    fn next_u32(&mut self) -> u32 {
28        self.0.next_u32()
29    }
30
31    fn next_u64(&mut self) -> u64 {
32        self.0.next_u64()
33    }
34
35    fn fill_bytes(&mut self, dest: &mut [u8]) {
36        self.0.fill_bytes(dest);
37    }
38}
39
40impl<T> rand_core09::CryptoRng for RngAdaptor<T> where T: RngCore + CryptoRng {}
41
42impl<T> RngCore for RngAdaptor<T>
43where
44    T: rand_core09::RngCore,
45{
46    fn next_u32(&mut self) -> u32 {
47        self.0.next_u32()
48    }
49
50    fn next_u64(&mut self) -> u64 {
51        self.0.next_u64()
52    }
53
54    fn fill_bytes(&mut self, dest: &mut [u8]) {
55        self.0.fill_bytes(dest);
56    }
57
58    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core06::Error> {
59        self.0.fill_bytes(dest);
60
61        Ok(())
62    }
63}
64
65impl<T> CryptoRng for RngAdaptor<T> where T: rand_core09::RngCore + rand_core09::CryptoRng {}
66
67/// Create a reseeding CSPRNG using ChaCha12Core as the underlying PRNG.
68/// A good default as an argument to the various `rs-matter` crypto backends, especially in baremetal environments.
69///
70/// # Arguments
71/// - `trng`: The true random number generator to use for reseeding.
72/// - `reseed_threshold`: The number of bytes to generate before reseeding.
73///
74/// # Returns
75/// An adaptor wrapping the reseeding RNG, or an error if the underlying TRNG fails to initialize.
76pub fn reseeding_csprng<T: rand_core09::TryRngCore>(
77    trng: T,
78    reseed_threshold: u64,
79) -> Result<RngAdaptor<ReseedingRng<ChaCha12Core, T>>, T::Error> {
80    Ok(RngAdaptor::new(ReseedingRng::new(reseed_threshold, trng)?))
81}