From ed6438cd4311c96c4125f0203c1bf8e54eca33ae Mon Sep 17 00:00:00 2001 From: Ivan Markov Date: Sun, 15 Nov 2020 13:21:07 +0200 Subject: [PATCH 1/4] Support for the ESP-IDF framework --- src/espidf.rs | 24 ++++++++++++++++++++++++ src/lib.rs | 4 ++++ 2 files changed, 28 insertions(+) create mode 100644 src/espidf.rs diff --git a/src/espidf.rs b/src/espidf.rs new file mode 100644 index 00000000..10d433b3 --- /dev/null +++ b/src/espidf.rs @@ -0,0 +1,24 @@ +// Copyright 2021 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementation for ESP-IDF +use crate::Error; + +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + // ESP-IDF fails and returns -1 only when the passed buffer is NULL, which cannot happen in our case: + // https://github.com/espressif/esp-idf/blob/master/components/newlib/random.c#L33 + // + // Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`) + // will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process: + // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html + // + // However tracking if some of these entropy sources is enabled is way too difficult to implement here + unsafe { libc::getrandom(dest.as_mut_ptr().cast(), dest.len(), 0) }; + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index f0cfb503..f5a89a57 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ //! | Hermit | `x86_64-*-hermit` | [`RDRAND`][18] //! | SGX | `x86_64‑*‑sgx` | [RDRAND][18] //! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure` +//! | ESP-IDF | `*‑espidf` | [`getrandom()`][23] //! | Emscripten | `*‑emscripten` | `/dev/random` (identical to `/dev/urandom`) //! | WASI | `wasm32‑wasi` | [`random_get`][17] //! | Web Browser | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16] @@ -142,6 +143,7 @@ //! [20]: https://www.unix.com/man-page/mojave/4/random/ //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable //! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom +//! [23]: https://cygwin.com/git/?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/include/sys/random.h;hb=HEAD#l22 #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", @@ -209,6 +211,8 @@ cfg_if! { #[path = "vxworks.rs"] mod imp; } else if #[cfg(target_os = "solid_asp3")] { #[path = "solid.rs"] mod imp; + } else if #[cfg(target_os = "espidf")] { + #[path = "espidf.rs"] mod imp; } else if #[cfg(windows)] { #[path = "windows.rs"] mod imp; } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] { From c3b02b8e4b6556baa4f18e67d4dbdbf80df3a36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9E=C3=B3rhallur=20Sverrisson?= Date: Sun, 30 Jan 2022 14:30:02 +0000 Subject: [PATCH 2/4] Use esp_fill_random instead of libc::getrandom Import esp_fill_random by using extern "C" and skip depending of esp-idf-sys. Opted for esp_fill_random instead of esp_random since esp_fill_random implements logic for filling the u8 array efficiently from a u32 source. Figured it was more efficient than what I would implement. --- src/espidf.rs | 13 +++++++++---- src/lib.rs | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/espidf.rs b/src/espidf.rs index 10d433b3..83bf1f09 100644 --- a/src/espidf.rs +++ b/src/espidf.rs @@ -8,17 +8,22 @@ //! Implementation for ESP-IDF use crate::Error; +use core::ffi::c_void; + +extern "C" { + fn esp_fill_random(buf: *mut c_void, len: usize) -> u32; +} pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { - // ESP-IDF fails and returns -1 only when the passed buffer is NULL, which cannot happen in our case: - // https://github.com/espressif/esp-idf/blob/master/components/newlib/random.c#L33 - // // Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`) // will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process: // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html // // However tracking if some of these entropy sources is enabled is way too difficult to implement here - unsafe { libc::getrandom(dest.as_mut_ptr().cast(), dest.len(), 0) }; + // + // Using esp_fill_random since it has some optimizations regarding filling a byte array from an + // u32 source. See https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/hw_random.c + unsafe { esp_fill_random(dest.as_mut_ptr().cast(), dest.len()) }; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index f5a89a57..6736543a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ //! | Hermit | `x86_64-*-hermit` | [`RDRAND`][18] //! | SGX | `x86_64‑*‑sgx` | [RDRAND][18] //! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure` -//! | ESP-IDF | `*‑espidf` | [`getrandom()`][23] +//! | ESP-IDF | `*‑espidf` | [`esp_fill_random()`][23] //! | Emscripten | `*‑emscripten` | `/dev/random` (identical to `/dev/urandom`) //! | WASI | `wasm32‑wasi` | [`random_get`][17] //! | Web Browser | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16] @@ -143,7 +143,7 @@ //! [20]: https://www.unix.com/man-page/mojave/4/random/ //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable //! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom -//! [23]: https://cygwin.com/git/?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/include/sys/random.h;hb=HEAD#l22 +//! [23]: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/hw_random.c #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", From 6aaa41b4d96a7c36aa2de0b97d7f6a146628677d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9E=C3=B3rhallur=20Sverrisson?= Date: Sun, 30 Jan 2022 15:26:25 +0000 Subject: [PATCH 3/4] Updated documentation link for ESP32 target --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6736543a..336c8ae1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -143,7 +143,7 @@ //! [20]: https://www.unix.com/man-page/mojave/4/random/ //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable //! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom -//! [23]: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/hw_random.c +//! [23]: https://docs.espressif.com/projects/esp-idf/en/release-v4.1/api-reference/system/system.html?highlight=esp_fill_random#_CPPv415esp_fill_randomPv6size_t #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", From 4d49673107ae0b724f471bdcc8c1bd65887498f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9E=C3=B3rhallur=20Sverrisson?= Date: Sun, 30 Jan 2022 15:52:53 +0000 Subject: [PATCH 4/4] Removed misleading comment about optimization --- src/espidf.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/espidf.rs b/src/espidf.rs index 83bf1f09..dce8a2aa 100644 --- a/src/espidf.rs +++ b/src/espidf.rs @@ -20,9 +20,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html // // However tracking if some of these entropy sources is enabled is way too difficult to implement here - // - // Using esp_fill_random since it has some optimizations regarding filling a byte array from an - // u32 source. See https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/hw_random.c unsafe { esp_fill_random(dest.as_mut_ptr().cast(), dest.len()) }; Ok(())