Skip to content

Commit

Permalink
Merge branch 'master' into target_flags
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed Jan 16, 2025
2 parents 43ca98e + 6be4012 commit ca12a88
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 40 deletions.
14 changes: 1 addition & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ windows-targets = "0.52"
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies]
wasm-bindgen = { version = "0.2.98", default-features = false, optional = true }
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), target_feature = "atomics"))'.dependencies]
js-sys = { version = "0.3.75", default-features = false, optional = true }
js-sys = { version = "0.3.77", default-features = false, optional = true }
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies]
wasm-bindgen-test = "0.3"

[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)',
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fn get_random_u128() -> Result<u128, getrandom::Error> {
| 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]
Expand All @@ -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`]. Requires feature `js`.
| `custom` | All targets | `*` | User-provided custom implementation (see [custom backend])

Expand Down Expand Up @@ -248,6 +248,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.
Expand Down Expand Up @@ -336,7 +343,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
Expand Down
2 changes: 1 addition & 1 deletion src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ cfg_if! {
} else if #[cfg(all(feature = "js", 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(
Expand Down
3 changes: 0 additions & 3 deletions src/backends/esp_idf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
3 changes: 1 addition & 2 deletions src/backends/wasm_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
return Err(Error::WEB_CRYPTO);
}

// SAFETY: `sub_buf`'s length is the same length as `chunk`
unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr().cast::<u8>()) };
sub_buf.copy_to_uninit(chunk);
}
Ok(())
}
Expand Down
29 changes: 14 additions & 15 deletions src/backends/windows.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Implementation for Windows 10 and later
//!
//! On Windows 10 and later, ProcessPrng "is the primary interface to the
//! user-mode per-processer PRNGs" and only requires bcryptprimitives.dll,
//! user-mode per-processor PRNGs" and only requires bcryptprimitives.dll,
//! making it a better option than the other Windows RNG APIs:
//! - BCryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! - Requires bcrypt.dll (which loads bcryptprimitives.dll anyway)
Expand All @@ -28,20 +28,19 @@ pub use crate::util::{inner_u32, inner_u64};
// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As
// bcryptprimitives.dll lacks an import library, we use the windows-targets
// crate to link to it.
windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL);
#[allow(clippy::upper_case_acronyms)]
pub type BOOL = i32;
pub const TRUE: BOOL = 1i32;
//
// TODO(MSRV 1.71): Migrate to linking as raw-dylib directly.
// https://github.com/joboet/rust/blob/5c1c72572479afe98734d5f78fa862abe662c41a/library/std/src/sys/pal/windows/c.rs#L119
// https://github.com/microsoft/windows-rs/blob/0.60.0/crates/libs/targets/src/lib.rs
windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> i32);

pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// ProcessPrng should always return TRUE, but we check just in case.
match unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) } {
TRUE => Ok(()),
_ => Err(Error::WINDOWS_PROCESS_PRNG),
}
}

impl Error {
/// Calling Windows ProcessPrng failed.
pub(crate) const WINDOWS_PROCESS_PRNG: Error = Self::new_internal(10);
let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) };
// Since Windows 10, calls to the user-mode RNG are guaranteed to never
// fail during runtime (rare windows W); `ProcessPrng` will only ever
// return 1 (which is how windows represents TRUE).
// See the bottom of page 6 of the aforementioned Windows RNG
// whitepaper for more information.
debug_assert!(result == 1);
Ok(())
}
2 changes: 0 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ impl Error {
target_os = "tvos",
))]
Error::IOS_RANDOM_GEN => "SecRandomCopyBytes: iOS Security framework failure",
#[cfg(all(windows, not(target_vendor = "win7")))]
Error::WINDOWS_PROCESS_PRNG => "ProcessPrng: Windows system function failure",
#[cfg(all(windows, target_vendor = "win7"))]
Error::WINDOWS_RTL_GEN_RANDOM => "RtlGenRandom: Windows system function failure",
#[cfg(all(feature = "js", getrandom_backend = "wasm_js"))]
Expand Down

0 comments on commit ca12a88

Please sign in to comment.