diff --git a/Cargo.toml b/Cargo.toml index 8f43e16b..8149ce6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,9 @@ libc = { version = "0.2.64", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] wasi = "0.10" +[target.'cfg(target_os = "hermit")'.dependencies] +hermit-abi = "0.1" + [target.'cfg(all(target_arch = "wasm32", target_os = "unknown", cargo_web))'.dependencies] stdweb = { version = "0.4.18", default-features = false, optional = true } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown", not(cargo_web)))'.dependencies] diff --git a/src/error.rs b/src/error.rs index 48abdc11..de2e15e2 100644 --- a/src/error.rs +++ b/src/error.rs @@ -53,6 +53,8 @@ impl Error { pub const NODE_CRYPTO: Error = internal_error(12); /// NodeJS does not have support for `crypto.randomFillSync`. pub const NODE_RANDOM_FILL_SYNC: Error = internal_error(13); + /// RNG hardware is not available for Hermit. + pub const HERMIT_NO_HARDWARE: Error = internal_error(14); /// Codes below this point represent OS Errors (i.e. positive i32 values). /// Codes at or above this point, but below [`Error::CUSTOM_START`] are diff --git a/src/hermit.rs b/src/hermit.rs new file mode 100644 index 00000000..876dfb29 --- /dev/null +++ b/src/hermit.rs @@ -0,0 +1,31 @@ +// Copyright 2018 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 Hermit +use crate::Error; +use hermit_abi::secure_rand64; + +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { + unsafe { + let mut chunks = dest.chunks_exact_mut(8); + for chunk in &mut chunks { + let bytes = secure_rand64() + .ok_or(Error::HERMIT_NO_HARDWARE)? + .to_ne_bytes(); + chunk.copy_from_slice(&bytes); + } + let rem = chunks.into_remainder(); + if !rem.is_empty() { + let bytes = secure_rand64() + .ok_or(Error::HERMIT_NO_HARDWARE)? + .to_ne_bytes(); + rem.copy_from_slice(&bytes[..rem.len()]); + } + } + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index e9244398..cc7dfe6a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ //! | Redox | `*‑redox` | [`rand:`][12] //! | CloudABI | `*‑cloudabi` | [`cloudabi_sys_random_get`][13] //! | Haiku | `*‑haiku` | `/dev/random` (identical to `/dev/urandom`) +//! | Hermit | `*-hermit` | [`secure_rand64`][24] //! | SGX | `x86_64‑*‑sgx` | [RDRAND][18] //! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure` //! | Emscripten | `*‑emscripten` | `/dev/random` (identical to `/dev/urandom`) @@ -144,6 +145,7 @@ //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable //! [22]: https://docs.microsoft.com/en-us/windows/uwp/ //! [23]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom +//! [24]: https://hermitcore.github.io/rusty-hermit/hermit_abi/fn.secure_rand64.html #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", @@ -190,6 +192,8 @@ cfg_if! { #[path = "cloudabi.rs"] mod imp; } else if #[cfg(target_os = "fuchsia")] { #[path = "fuchsia.rs"] mod imp; + } else if #[cfg(target_os = "hermit")] { + #[path = "hermit.rs"] mod imp; } else if #[cfg(target_os = "ios")] { #[path = "ios.rs"] mod imp; } else if #[cfg(target_os = "macos")] {