From b0128c85baa768d5a1c84e880cdc6e1b04d82f63 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Thu, 9 Jan 2025 21:10:23 -0800 Subject: [PATCH] ESP-IDF: Enable unconditionally After reviewing the updated ESP-IDF random documentation: - https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html - https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng I think we should enable this backend by default. Given that ESP-IDF provides such bindings, it's clear they intend for cryptographic libraries (such as their fork of WolfSSL) to use them. Furthurmore, it seems like the only time the Hardware RNG wouldn't be seeded with sufficient entropy is during early boot, so I added a section to our "Early boot" documentation noting this issue. Also note that Rust's standard library unconditonally supports ESP-IDF for both hash seed generation and generating cryptographic random bytes, see https://github.com/rust-lang/rust/blob/62bf38fa600f4beb878d61c537837729d4ee689e/library/std/src/sys/random/espidf.rs#L7 Signed-off-by: Joe Richey --- .github/workflows/build.yml | 14 +------------- Cargo.toml | 2 +- README.md | 13 +++++++++++-- src/backends.rs | 2 +- src/backends/esp_idf.rs | 3 --- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4dfc5703..83a4d72e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,6 +86,7 @@ jobs: armv6k-nintendo-3ds, armv7-sony-vita-newlibeabihf, i686-unknown-hurd-gnu, + riscv32imc-esp-espidf, x86_64-unknown-hermit, x86_64-wrs-vxworks, x86_64-unknown-dragonfly, @@ -207,19 +208,6 @@ jobs: RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rndr" run: cargo build --target=aarch64-unknown-linux-gnu --features std - esp-idf: - name: ESP-IDF - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly # Required to build libcore - with: - components: rust-src - - uses: Swatinem/rust-cache@v2 - - env: - RUSTFLAGS: -Dwarnings --cfg getrandom_backend="esp_idf" - run: cargo build -Z build-std=core --target=riscv32imc-esp-espidf - no-atomics: name: No Atomics runs-on: ubuntu-24.04 diff --git a/Cargo.toml b/Cargo.toml index 15a95dc2..45b17780 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ rustc-dep-of-std = ["dep:compiler_builtins", "dep:core"] [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ - 'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js", "esp_idf"))', + 'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js"))', 'cfg(getrandom_msan)', 'cfg(getrandom_test_linux_fallback)', 'cfg(getrandom_test_netbsd_fallback)', diff --git a/README.md b/README.md index f3489090..ea3b8b01 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ fn get_random_u128() -> Result { | WASI 0.2 | `wasm32‑wasip2` | [`get-random-u64`] | SOLID | `*-kmc-solid_*` | `SOLID_RNG_SampleRandomBytes` | Nintendo 3DS | `*-nintendo-3ds` | [`getrandom`][18] +| ESP-IDF | `*‑espidf` | [`esp_fill_random`] WARNING: see "Early Boot" section below | PS Vita | `*-vita-*` | [`getentropy`][19] | QNX Neutrino | `*‑nto-qnx*` | [`/dev/urandom`][14] (identical to `/dev/random`) | AIX | `*-ibm-aix` | [`/dev/urandom`][15] @@ -81,7 +82,6 @@ of randomness based on their specific needs: | `linux_getrandom` | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow). | `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction | `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register -| `esp_idf` | ESP-IDF | `*‑espidf` | [`esp_fill_random`]. WARNING: can return low-quality entropy without proper hardware configuration! | `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown`, `wasm32v1-none` | [`Crypto.getRandomValues`] | `custom` | All targets | `*` | User-provided custom implementation (see [custom backend]) @@ -247,6 +247,13 @@ sourced according to the platform's best practices, but each platform has its own limits on the grade of randomness it can promise in environments with few sources of entropy. +On ESP-IDF, if `esp_fill_random` is used before enabling WiFi, BT, or the +voltage noise entropy source (SAR ADC), the Hardware RNG will only be seeded +via RC_FAST_CLK. This can occur during early boot unless +`bootloader_random_enable()` is called. For more information see the +[ESP-IDF RNG Docs][esp-idf-rng] or the +[RNG section of the ESP32 Technical Reference Manual][esp-trng-docs]. + ## Error handling We always prioritize failure over returning known insecure "random" bytes. @@ -335,7 +342,9 @@ dual licensed as above, without any additional terms or conditions. [`RNDR`]: https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/RNDR--Random-Number [`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html [`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw -[`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t +[`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html#functions +[esp-idf-rng]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html +[esp-trng-docs]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng [`random_get`]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno [`get-random-u64`]: https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28 [configuration flags]: #configuration-flags diff --git a/src/backends.rs b/src/backends.rs index 900911fb..921b7779 100644 --- a/src/backends.rs +++ b/src/backends.rs @@ -22,7 +22,7 @@ cfg_if! { } else if #[cfg(getrandom_backend = "wasm_js")] { mod wasm_js; pub use wasm_js::*; - } else if #[cfg(getrandom_backend = "esp_idf")] { + } else if #[cfg(target_os = "espidf")] { mod esp_idf; pub use esp_idf::*; } else if #[cfg(any( diff --git a/src/backends/esp_idf.rs b/src/backends/esp_idf.rs index 0f0ff7f4..7ee391ab 100644 --- a/src/backends/esp_idf.rs +++ b/src/backends/esp_idf.rs @@ -4,9 +4,6 @@ use core::{ffi::c_void, mem::MaybeUninit}; pub use crate::util::{inner_u32, inner_u64}; -#[cfg(not(target_os = "espidf"))] -compile_error!("`esp_idf` backend can be enabled only for ESP-IDF targets!"); - extern "C" { fn esp_fill_random(buf: *mut c_void, len: usize) -> u32; }