1
#![cfg_attr(docsrs, procmacros::doc_replace(
2
    "documentation" => concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", chip!(), "/api-reference/system/random.html).")
3
))]
4
//! # Random Number Generator (RNG)
5
//!
6
//! ## Overview
7
//!
8
//! The Random Number Generator (RNG) module provides an interface to generate
9
//! random numbers using the RNG peripheral on ESP chips. The driver generates
10
//! random numbers that can be used for various cryptographic, security, or
11
//! general-purpose applications.
12
//!
13
//! There are certain pre-conditions which must be met in order for the RNG to
14
//! produce *true* random numbers.
15
#![cfg_attr(rng_trng_supported, doc = r"For more details see [`Trng`].")]
16
//! The hardware RNG produces true random numbers
17
//! under any of the following conditions:
18
//!
19
//! - RF subsystem is enabled (i.e. Wi-Fi or Bluetooth are enabled).
20
//! - An ADC is used to generate entropy.
21
//!
22
//! When any of these conditions are true, samples of physical noise are
23
//! continuously mixed into the internal hardware RNG state to provide entropy.
24
//! If none of the above conditions are true, the output of the RNG should be
25
//! considered pseudo-random only. See [`Rng`].
26
//!
27
//! For more information, please refer to the
28
//! # {documentation}
29
//!
30
//! ## Example
31
//!
32
//! ```rust, no_run
33
//! # {before_snippet}
34
//! # use esp_hal::rng::Rng;
35
//! #
36
//! let rng = Rng::new();
37
//!
38
//! // Generate a random word (u32):
39
//! let rand_word = rng.random();
40
//!
41
//! // Fill a buffer with random bytes:
42
//! let mut buf = [0u8; 16];
43
//! rng.read(&mut buf);
44
//!
45
//! loop {}
46
//! # }
47
//! ```
48
//!
49
//! ## Compatibility with [`getrandom`]
50
//!
51
//! The driver can be used directly, or integrated as a [custom backend]
52
//! for `getrandom` (e.g. v0.4):
53
//!
54
//! ```rust, no_run
55
//! # {before_snippet}
56
//! # mod getrandom {
57
//! # use core::result::Result::{self, Ok};
58
//! # pub struct Error;
59
//! #[unsafe(no_mangle)]
60
//! unsafe extern "Rust" fn __getrandom_v04_custom(
61
//!     dest: *mut u8,
62
//!     len: usize,
63
//! ) -> Result<(), Error> {
64
//!      unsafe { esp_hal::rng::Rng::new().read_into_raw(dest, len) };
65
//!      Ok(())
66
//! # }
67
//! # }
68
//! # {after_snippet}
69
//! ```
70
//!
71
//! [`getrandom`]: https://crates.io/crates/getrandom
72
//! [custom backend]: https://github.com/rust-random/getrandom/tree/v0.4.2?tab=readme-ov-file#custom-backend
73

            
74
mod ll;
75

            
76
#[cfg(rng_trng_supported)]
77
mod trng;
78

            
79
#[cfg(rng_trng_supported)]
80
#[instability::unstable]
81
pub use trng::*;
82

            
83
/// (Pseudo-)Random Number Generator.
84
///
85
/// [`Rng`] can be created at any time to generate pseudo-random numbers
86
#[cfg_attr(
87
    rng_trng_supported,
88
    doc = r"To generate true random numbers, see [`Trng`]."
89
)]
90
#[derive(Clone, Copy, Default, Debug)]
91
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
92
#[non_exhaustive]
93
pub struct Rng;
94

            
95
impl Rng {
96
    /// Creates a new random number generator instance.
97
    #[inline]
98
    pub fn new() -> Self {
99
        Self
100
    }
101

            
102
    #[procmacros::doc_replace]
103
    /// Reads currently available `u32` integer from `RNG`.
104
    ///
105
    /// # Examples
106
    ///
107
    /// ```rust, no_run
108
    /// # {before_snippet}
109
    /// use esp_hal::rng::Rng;
110
    ///
111
    /// let rng = Rng::new();
112
    /// let random_number = rng.random();
113
    /// # {after_snippet}
114
    /// ```
115
    #[inline]
116
    pub fn random(&self) -> u32 {
117
        let mut n = [0; 4];
118
        self.read(&mut n);
119
        u32::from_le_bytes(n)
120
    }
121

            
122
    #[procmacros::doc_replace]
123
    /// Reads enough bytes from hardware random number generator to fill
124
    /// `buffer`.
125
    ///
126
    /// # Examples
127
    ///
128
    /// ```rust, no_run
129
    /// # {before_snippet}
130
    /// use esp_hal::rng::Rng;
131
    ///
132
    /// let rng = Rng::new();
133
    /// let mut rng_values = [0; 10];
134
    /// rng.read(&mut rng_values);
135
    /// # {after_snippet}
136
    #[inline]
137
    pub fn read(&self, buffer: &mut [u8]) {
138
        unsafe { self.read_into_raw(buffer.as_mut_ptr(), buffer.len()) };
139
    }
140

            
141
    /// Reads enough bytes from hardware random number generator to fill
142
    /// `buffer`.
143
    ///
144
    /// If any error is encountered then this function immediately returns. The
145
    /// contents of buf are unspecified in this case.
146
    ///
147
    /// # Safety
148
    ///
149
    /// `ptr` must not be `null` and valid for writes for `len` bytes.
150
    #[inline]
151
    #[instability::unstable]
152
    pub unsafe fn read_into_raw(&self, ptr: *mut u8, len: usize) {
153
1
        ll::fill_ptr_range(ptr, len);
154
    }
155
}
156

            
157
// Implement RngCore traits
158

            
159
/// Compatibility with `rand_core 0.6`. Documentation can be found at
160
/// <https://docs.rs/rand_core/0.6.4/rand_core/trait.RngCore.html>.
161
#[instability::unstable]
162
impl rand_core_06::RngCore for Rng {
163
    fn next_u32(&mut self) -> u32 {
164
        self.random()
165
    }
166

            
167
    fn next_u64(&mut self) -> u64 {
168
        let mut bytes = [0; 8];
169
        self.read(&mut bytes);
170
        u64::from_le_bytes(bytes)
171
    }
172

            
173
    fn fill_bytes(&mut self, dest: &mut [u8]) {
174
        self.read(dest);
175
    }
176

            
177
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
178
        self.read(dest);
179
        Ok(())
180
    }
181
}
182

            
183
/// Compatibility with `rand_core 0.9`. Documentation can be found at
184
/// <https://docs.rs/rand_core/0.9.5/rand_core/trait.RngCore.html>.
185
#[instability::unstable]
186
impl rand_core_09::RngCore for Rng {
187
    fn next_u32(&mut self) -> u32 {
188
        self.random()
189
    }
190
    fn next_u64(&mut self) -> u64 {
191
        let mut bytes = [0; 8];
192
        self.read(&mut bytes);
193
        u64::from_le_bytes(bytes)
194
    }
195
    fn fill_bytes(&mut self, dest: &mut [u8]) {
196
        self.read(dest);
197
    }
198
}
199

            
200
/// Compatibility with `rand_core 0.10`
201
#[instability::unstable]
202
impl rand_core_010::TryRng for Rng {
203
    type Error = core::convert::Infallible;
204
    fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
205
        Ok(self.random())
206
    }
207
    fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
208
        let mut bytes = [0; 8];
209
        self.read(&mut bytes);
210
        Ok(u64::from_le_bytes(bytes))
211
    }
212
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
213
        self.read(dest);
214
        Ok(())
215
    }
216
}