Skip to main content

noxtls_platform/
entropy.rs

1// Copyright (c) 2019-2026, Argenox Technologies LLC
2// All rights reserved.
3//
4// SPDX-License-Identifier: GPL-2.0-only OR LicenseRef-Argenox-Commercial-License
5
6//! Entropy sources for DRBG seeding on embedded and hosted targets.
7
8/// Fills `dst` with unpredictable bytes suitable for cryptographic seeding.
9pub trait EntropySource {
10    /// Writes entropy into every byte of `dst`.
11    fn fill(&mut self, dst: &mut [u8]);
12}
13
14/// Deterministic bytes for unit tests only.
15#[derive(Debug, Clone)]
16pub struct TestEntropySource {
17    counter: u64,
18}
19
20impl TestEntropySource {
21    /// Creates a test source seeded at zero.
22    #[must_use]
23    pub fn noxtls_new() -> Self {
24        Self { counter: 0 }
25    }
26}
27
28impl EntropySource for TestEntropySource {
29    fn fill(&mut self, dst: &mut [u8]) {
30        for byte in dst.iter_mut() {
31            *byte = (self.counter & 0xff) as u8;
32            self.counter = self.counter.wrapping_add(1);
33        }
34    }
35}
36
37/// Adapts any `rand_core::RngCore` (Embassy TRNG, STM32 RNG, etc.).
38#[cfg(feature = "rand-core")]
39pub struct RandCoreEntropy<R>(pub R);
40
41#[cfg(feature = "rand-core")]
42impl<R: rand_core::RngCore> EntropySource for RandCoreEntropy<R> {
43    fn fill(&mut self, dst: &mut [u8]) {
44        self.0.fill_bytes(dst);
45    }
46}
47
48/// OS randomness via `getrandom` when `std` is enabled.
49#[cfg(feature = "std")]
50#[derive(Debug, Clone, Copy, Default)]
51pub struct StdEntropy;
52
53#[cfg(feature = "std")]
54impl EntropySource for StdEntropy {
55    fn fill(&mut self, dst: &mut [u8]) {
56        getrandom::fill(dst).expect("OS entropy source failed");
57    }
58}