diff --git a/src/hermit.rs b/src/hermit.rs new file mode 100644 index 00000000..570b03d9 --- /dev/null +++ b/src/hermit.rs @@ -0,0 +1,21 @@ +use crate::Error; +use core::{cmp::min, mem::MaybeUninit, num::NonZeroU32}; + +extern "C" { + fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize; +} + +pub fn getrandom_inner(mut dest: &mut [MaybeUninit]) -> Result<(), Error> { + while !dest.is_empty() { + let res = unsafe { sys_read_entropy(dest.as_mut_ptr() as *mut u8, dest.len(), 0) }; + if res < 0 { + // SAFETY: all Hermit error codes use i32 under the hood: + // https://github.com/hermitcore/libhermit-rs/blob/master/src/errno.rs + let code = unsafe { NonZeroU32::new_unchecked((-res) as u32) }; + return Err(code.into()); + } + let len = min(res as usize, dest.len()); + dest = &mut dest[len..]; + } + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index b3e09460..26490e69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,7 @@ //! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`] //! | Redox | `*‑redox` | `/dev/urandom` //! | Haiku | `*‑haiku` | `/dev/urandom` (identical to `/dev/random`) -//! | Hermit | `x86_64-*-hermit` | [`RDRAND`] +//! | Hermit | `*-hermit` | [`sys_read_entropy`] //! | SGX | `x86_64‑*‑sgx` | [`RDRAND`] //! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure` //! | ESP-IDF | `*‑espidf` | [`esp_fill_random`] @@ -179,6 +179,7 @@ //! [`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html //! [CommonJS modules]: https://nodejs.org/api/modules.html //! [ES modules]: https://nodejs.org/api/esm.html +//! [`sys_read_entropy`]: https://hermitcore.github.io/libhermit-rs/hermit/fn.sys_read_entropy.html #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", @@ -245,8 +246,8 @@ cfg_if! { #[path = "openbsd.rs"] mod imp; } else if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] { #[path = "wasi.rs"] mod imp; - } else if #[cfg(all(target_arch = "x86_64", target_os = "hermit"))] { - #[path = "rdrand.rs"] mod imp; + } else if #[cfg(target_os = "hermit")] { + #[path = "hermit.rs"] mod imp; } else if #[cfg(target_os = "vxworks")] { mod util_libc; #[path = "vxworks.rs"] mod imp;