From 616bad8834f7c374c60cd54718ce15787d510c7c Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 25 Jan 2024 16:48:56 +0100 Subject: [PATCH 1/2] WIP made randomness ensuring function implemented RngCore trait (final version i guess) --- esp-hal-common/src/rng.rs | 93 +++++++++++++++++++++++++++++++++++++++ esp32h2-hal/Cargo.toml | 1 + 2 files changed, 94 insertions(+) diff --git a/esp-hal-common/src/rng.rs b/esp-hal-common/src/rng.rs index 9dd79d858ed..72564fa62b3 100644 --- a/esp-hal-common/src/rng.rs +++ b/esp-hal-common/src/rng.rs @@ -67,6 +67,8 @@ use core::{convert::Infallible, marker::PhantomData}; use crate::{peripheral::Peripheral, peripherals::RNG}; +use rand_core::{CryptoRng, Error, RngCore}; + /// Random number generator driver #[derive(Clone, Copy)] pub struct Rng { @@ -90,6 +92,60 @@ impl Rng { .read() .bits() } + + pub fn ensure_randomness(&self) { + unsafe { + #[cfg(feature = "esp32c6")] + if (&*crate::soc::peripherals::LPWR::PTR) + .lp_clk_conf() + .read() + .fast_clk_sel() + .bit_is_set() + { + (&*crate::soc::peripherals::LPWR::PTR) + .lp_clk_conf() + .modify(|_, w| w.fast_clk_sel().clear_bit()) + } + + #[cfg(feature = "esp32h2")] + if (&*crate::soc::peripherals::LPWR::PTR) + .lp_clk_conf() + .read() + .fast_clk_sel() + .bits() + != 0b00 + { + (&*crate::soc::peripherals::LPWR::PTR) + .lp_clk_conf() + .modify(|_, w| w.fast_clk_sel().bits(0b00)) + } + + #[cfg(feature = "esp32p4")] + if (&*crate::soc::peripherals::LP_AON_CLKRST::PTR) + .lp_aon_clkrst_lp_clk_conf() + .read() + .lp_aonclkrst_fast_clk_sel() + .bits() + != 0b00 + { + (&*crate::soc::peripherals::LPWR::PTR) + .lp_aon_clkrst_lp_clk_conf() + .modify(|_, w| w.lp_aonclkrst_fast_clk_sel().bits(0b00)) + } + + #[cfg(not(any(feature = "esp32c6", feature = "esp32h2", feature = "esp32p4")))] + if (&*crate::soc::peripherals::LPWR::PTR) + .clk_conf() + .read() + .fast_clk_rtc_sel() + .bit_is_set() + { + (&*crate::soc::peripherals::LPWR::PTR) + .clk_conf() + .modify(|_, w| w.fast_clk_rtc_sel().clear_bit()) + } + } + } } impl embedded_hal::blocking::rng::Read for Rng { @@ -104,3 +160,40 @@ impl embedded_hal::blocking::rng::Read for Rng { Ok(()) } } + +// Marker trait. `ensure_randomness` function helps to be sure that RNG generates really random numbers +impl CryptoRng for Rng {} + +impl RngCore for Rng { + fn next_u32(&mut self) -> u32 { + self.ensure_randomness(); + // Directly use the existing random method to get a u32 random number + self.random() + } + + fn next_u64(&mut self) -> u64 { + self.ensure_randomness(); + // Call random() twice to generate a u64 random number (сombine two u32) + let upper = self.random() as u64; + let lower = self.random() as u64; + (upper << 32) | lower + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.ensure_randomness(); + // Fill the destination buffer with random bytes + for chunk in dest.chunks_mut(4) { + let rand_bytes = self.random().to_le_bytes(); + for (dest_byte, rand_byte) in chunk.iter_mut().zip(&rand_bytes) { + *dest_byte = *rand_byte; + } + } + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + self.ensure_randomness(); + // Similar implementation as fill_bytes, but encapsulated in a Result + self.fill_bytes(dest); + Ok(()) + } +} diff --git a/esp32h2-hal/Cargo.toml b/esp32h2-hal/Cargo.toml index 24eed5ca18a..352e66a62c7 100644 --- a/esp32h2-hal/Cargo.toml +++ b/esp32h2-hal/Cargo.toml @@ -51,6 +51,7 @@ sha2 = { version = "0.10.8", default-features = false} smart-leds = "0.4.0" ssd1306 = "0.8.4" static_cell = { version = "2.0.0", features = ["nightly"] } +rand_core = "0.6.4" [features] default = ["embassy-integrated-timers", "rt", "vectored", "zero-rtc-bss"] From a51cf9af3d8d8bfaba15067c967bf63a1bea289f Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 29 Jan 2024 13:26:54 +0100 Subject: [PATCH 2/2] Revert part of changes and leave TODO comment Changelog entry Get rid of warning --- CHANGELOG.md | 1 + esp-hal-common/Cargo.toml | 1 + esp-hal-common/src/rng.rs | 69 +++------------------------------------ 3 files changed, 7 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc760733423..05f465e4993 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ESP32-P4: Add efuse reading support (#1114) - Allow for splitting of the USB Serial JTAG peripheral into tx/rx components (#1024) +- `RngCore` trait is implemented (#1122) ### Fixed diff --git a/esp-hal-common/Cargo.toml b/esp-hal-common/Cargo.toml index 98625c611b4..8d4998c4d41 100644 --- a/esp-hal-common/Cargo.toml +++ b/esp-hal-common/Cargo.toml @@ -38,6 +38,7 @@ procmacros = { version = "0.8.0", features = ["enum-dispatch", "ram"], strum = { version = "0.25.0", default-features = false, features = ["derive"] } void = { version = "1.0.2", default-features = false } usb-device = { version = "0.3.1", optional = true } +rand_core = { version = "0.6.4" } # async embedded-hal-async = { version = "1.0.0", optional = true } diff --git a/esp-hal-common/src/rng.rs b/esp-hal-common/src/rng.rs index 72564fa62b3..c3d9bd9fe67 100644 --- a/esp-hal-common/src/rng.rs +++ b/esp-hal-common/src/rng.rs @@ -65,9 +65,9 @@ use core::{convert::Infallible, marker::PhantomData}; -use crate::{peripheral::Peripheral, peripherals::RNG}; +use rand_core::RngCore; -use rand_core::{CryptoRng, Error, RngCore}; +use crate::{peripheral::Peripheral, peripherals::RNG}; /// Random number generator driver #[derive(Clone, Copy)] @@ -92,60 +92,6 @@ impl Rng { .read() .bits() } - - pub fn ensure_randomness(&self) { - unsafe { - #[cfg(feature = "esp32c6")] - if (&*crate::soc::peripherals::LPWR::PTR) - .lp_clk_conf() - .read() - .fast_clk_sel() - .bit_is_set() - { - (&*crate::soc::peripherals::LPWR::PTR) - .lp_clk_conf() - .modify(|_, w| w.fast_clk_sel().clear_bit()) - } - - #[cfg(feature = "esp32h2")] - if (&*crate::soc::peripherals::LPWR::PTR) - .lp_clk_conf() - .read() - .fast_clk_sel() - .bits() - != 0b00 - { - (&*crate::soc::peripherals::LPWR::PTR) - .lp_clk_conf() - .modify(|_, w| w.fast_clk_sel().bits(0b00)) - } - - #[cfg(feature = "esp32p4")] - if (&*crate::soc::peripherals::LP_AON_CLKRST::PTR) - .lp_aon_clkrst_lp_clk_conf() - .read() - .lp_aonclkrst_fast_clk_sel() - .bits() - != 0b00 - { - (&*crate::soc::peripherals::LPWR::PTR) - .lp_aon_clkrst_lp_clk_conf() - .modify(|_, w| w.lp_aonclkrst_fast_clk_sel().bits(0b00)) - } - - #[cfg(not(any(feature = "esp32c6", feature = "esp32h2", feature = "esp32p4")))] - if (&*crate::soc::peripherals::LPWR::PTR) - .clk_conf() - .read() - .fast_clk_rtc_sel() - .bit_is_set() - { - (&*crate::soc::peripherals::LPWR::PTR) - .clk_conf() - .modify(|_, w| w.fast_clk_rtc_sel().clear_bit()) - } - } - } } impl embedded_hal::blocking::rng::Read for Rng { @@ -161,18 +107,16 @@ impl embedded_hal::blocking::rng::Read for Rng { } } -// Marker trait. `ensure_randomness` function helps to be sure that RNG generates really random numbers -impl CryptoRng for Rng {} +// TODO: CryptoRng trait will be implemented when true randomness of RNG is +// ensured impl RngCore for Rng { fn next_u32(&mut self) -> u32 { - self.ensure_randomness(); // Directly use the existing random method to get a u32 random number self.random() } fn next_u64(&mut self) -> u64 { - self.ensure_randomness(); // Call random() twice to generate a u64 random number (сombine two u32) let upper = self.random() as u64; let lower = self.random() as u64; @@ -180,7 +124,6 @@ impl RngCore for Rng { } fn fill_bytes(&mut self, dest: &mut [u8]) { - self.ensure_randomness(); // Fill the destination buffer with random bytes for chunk in dest.chunks_mut(4) { let rand_bytes = self.random().to_le_bytes(); @@ -191,9 +134,7 @@ impl RngCore for Rng { } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - self.ensure_randomness(); // Similar implementation as fill_bytes, but encapsulated in a Result - self.fill_bytes(dest); - Ok(()) + Ok(self.fill_bytes(dest)) } }