Skip to content

Commit

Permalink
Use getentropy on Emscripten (#307)
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Richey <joerichey@google.com>

Signed-off-by: Joe Richey <joerichey@google.com>
  • Loading branch information
josephlr committed Oct 23, 2022
1 parent 68b4d7a commit 710b24d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 17 deletions.
18 changes: 18 additions & 0 deletions src/emscripten.rs
@@ -0,0 +1,18 @@
//! Implementation for Emscripten
use crate::{util_libc::last_os_error, Error};
use core::mem::MaybeUninit;

// Not yet defined in libc crate.
extern "C" {
fn getentropy(buffer: *mut libc::c_void, length: usize) -> libc::c_int;
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Emscripten 2.0.5 added getentropy, so we can use it unconditionally.
// Unlike other getentropy implementations, there is no max buffer length.
let ret = unsafe { getentropy(dest.as_mut_ptr() as *mut libc::c_void, dest.len()) };
if ret < 0 {
return Err(last_os_error());
}
Ok(())
}
9 changes: 6 additions & 3 deletions src/lib.rs
Expand Up @@ -28,7 +28,7 @@
//! | SGX | `x86_64‑*‑sgx` | [`RDRAND`]
//! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure`
//! | ESP-IDF | `*‑espidf` | [`esp_fill_random`]
//! | Emscripten | `*‑emscripten` | `/dev/urandom` (identical to `/dev/random`)
//! | Emscripten | `*‑emscripten` | [`getentropy`][13]
//! | WASI | `wasm32‑wasi` | [`random_get`]
//! | Web Browser and Node.js | `wasm*‑*‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js, see [WebAssembly support]
//! | SOLID | `*-kmc-solid_*` | `SOLID_RNG_SampleRandomBytes`
Expand Down Expand Up @@ -159,6 +159,7 @@
//! [10]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
//! [12]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
//! [13]: https://github.com/emscripten-core/emscripten/pull/12240
//!
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
Expand Down Expand Up @@ -208,8 +209,7 @@ pub use crate::error::Error;
// The function MUST NOT ever write uninitialized bytes into `dest`,
// regardless of what value it returns.
cfg_if! {
if #[cfg(any(target_os = "emscripten", target_os = "haiku",
target_os = "redox"))] {
if #[cfg(any(target_os = "haiku", target_os = "redox"))] {
mod util_libc;
#[path = "use_file.rs"] mod imp;
} else if #[cfg(any(target_os = "android", target_os = "linux"))] {
Expand Down Expand Up @@ -256,6 +256,9 @@ cfg_if! {
// uses Horizon OS (it is aarch64).
mod util_libc;
#[path = "3ds.rs"] mod imp;
} else if #[cfg(target_os = "emscripten")] {
mod util_libc;
#[path = "emscripten.rs"] mod imp;
} else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
#[path = "rdrand.rs"] mod imp;
} else if #[cfg(all(feature = "rdrand",
Expand Down
17 changes: 3 additions & 14 deletions src/use_file.rs
Expand Up @@ -29,27 +29,16 @@ const FILE_PATH: &str = "/dev/random\0";
target_os = "linux",
target_os = "redox",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "haiku",
target_os = "macos"
))]
const FILE_PATH: &str = "/dev/urandom\0";

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let fd = get_rng_fd()?;
let read = |buf: &mut [MaybeUninit<u8>]| unsafe {
libc::read(fd, buf.as_mut_ptr() as *mut _, buf.len())
};

if cfg!(target_os = "emscripten") {
// `Crypto.getRandomValues` documents `dest` should be at most 65536 bytes.
for chunk in dest.chunks_mut(65536) {
sys_fill_exact(chunk, read)?;
}
} else {
sys_fill_exact(dest, read)?;
}
Ok(())
sys_fill_exact(dest, |buf| unsafe {
libc::read(fd, buf.as_mut_ptr() as *mut libc::c_void, buf.len())
})
}

// Returns the file descriptor for the device file used to retrieve random
Expand Down

0 comments on commit 710b24d

Please sign in to comment.