Skip to content

Commit e889c6d

Browse files
committed
Use getentropy on Emscripten
Signed-off-by: Joe Richey <joerichey@google.com>
1 parent 2ec38ad commit e889c6d

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

src/emscripten.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! Implementation for Emscripten
2+
use crate::{util_libc::last_os_error, Error};
3+
use core::mem::MaybeUninit;
4+
5+
// Not yet defined in libc crate.
6+
extern "C" {
7+
fn getentropy(buffer: *mut libc::c_void, length: usize) -> libc::c_int;
8+
}
9+
10+
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
11+
// Emscripten 2.0.5 added getentropy, so we can use it unconditionally.
12+
// Unlike other getentropy implementations, there is no max buffer length.
13+
let ret = unsafe { getentropy(dest.as_mut_ptr() as *mut libc::c_void, dest.len()) };
14+
if ret < 0 {
15+
return Err(last_os_error());
16+
}
17+
Ok(())
18+
}

src/lib.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
//! | SGX | `x86_64‑*‑sgx` | [`RDRAND`]
2929
//! | VxWorks | `*‑wrs‑vxworks‑*` | `randABytes` after checking entropy pool initialization with `randSecure`
3030
//! | ESP-IDF | `*‑espidf` | [`esp_fill_random`]
31-
//! | Emscripten | `*‑emscripten` | `/dev/random` (identical to `/dev/urandom`)
31+
//! | Emscripten | `*‑emscripten` | [`getentropy`][13]
3232
//! | WASI | `wasm32‑wasi` | [`random_get`]
3333
//! | Web Browser and Node.js | `wasm32‑*‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js, see [WebAssembly support]
3434
//! | SOLID | `*-kmc-solid_*` | `SOLID_RNG_SampleRandomBytes`
@@ -159,6 +159,7 @@
159159
//! [10]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
160160
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
161161
//! [12]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
162+
//! [13]: https://github.com/emscripten-core/emscripten/pull/12240
162163
//!
163164
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
164165
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
@@ -208,8 +209,7 @@ pub use crate::error::Error;
208209
// The function MUST NOT ever write uninitialized bytes into `dest`,
209210
// regardless of what value it returns.
210211
cfg_if! {
211-
if #[cfg(any(target_os = "emscripten", target_os = "haiku",
212-
target_os = "redox"))] {
212+
if #[cfg(any(target_os = "haiku", target_os = "redox"))] {
213213
mod util_libc;
214214
#[path = "use_file.rs"] mod imp;
215215
} else if #[cfg(any(target_os = "android", target_os = "linux"))] {
@@ -251,6 +251,9 @@ cfg_if! {
251251
#[path = "espidf.rs"] mod imp;
252252
} else if #[cfg(windows)] {
253253
#[path = "windows.rs"] mod imp;
254+
} else if #[cfg(target_os = "emscripten")] {
255+
mod util_libc;
256+
#[path = "emscripten.rs"] mod imp;
254257
} else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
255258
#[path = "rdrand.rs"] mod imp;
256259
} else if #[cfg(all(feature = "rdrand",

src/use_file.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use core::{
2020

2121
#[cfg(any(
2222
target_os = "dragonfly",
23-
target_os = "emscripten",
2423
target_os = "haiku",
2524
target_os = "macos",
2625
target_os = "solaris",
@@ -32,19 +31,9 @@ const FILE_PATH: &str = "/dev/urandom\0";
3231

3332
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
3433
let fd = get_rng_fd()?;
35-
let read = |buf: &mut [MaybeUninit<u8>]| unsafe {
34+
sys_fill_exact(dest, |buf: &mut [MaybeUninit<u8>]| unsafe {
3635
libc::read(fd, buf.as_mut_ptr() as *mut _, buf.len())
37-
};
38-
39-
if cfg!(target_os = "emscripten") {
40-
// `Crypto.getRandomValues` documents `dest` should be at most 65536 bytes.
41-
for chunk in dest.chunks_mut(65536) {
42-
sys_fill_exact(chunk, read)?;
43-
}
44-
} else {
45-
sys_fill_exact(dest, read)?;
46-
}
47-
Ok(())
36+
})
4837
}
4938

5039
// Returns the file descriptor for the device file used to retrieve random

0 commit comments

Comments
 (0)