Skip to content

Commit 7060cff

Browse files
authored
Add functions to generate random u32 and u64 values (rust-random#544)
These functions can be helpful for seed generation and implementation of `OsRng`. Additionally, some backends (Hermit, RDRAND, RNDR, WASI p2) can directly generate random `u32`/`u64` values. Relying on the byte API may be less efficient in these cases. Using `u32` and `u64` as function names may seem problematic, but based on the `fasrand` experience, it works well in practice, provided that users reference them as `getrandom::u32/u64` without importing them directly.
1 parent 5376242 commit 7060cff

27 files changed

Lines changed: 353 additions & 91 deletions

src/backends.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,20 @@ cfg_if! {
116116
mod apple_other;
117117
pub use apple_other::*;
118118
} else if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] {
119-
mod wasi;
120-
pub use wasi::*;
119+
cfg_if! {
120+
if #[cfg(target_env = "p1")] {
121+
mod wasi_p1;
122+
pub use wasi_p1::*;
123+
} else if #[cfg(target_env = "p2")] {
124+
mod wasi_p2;
125+
pub use wasi_p2::*;
126+
} else {
127+
compile_error!(
128+
"Unknown version of WASI (only previews 1 and 2 are supported) \
129+
or Rust version older than 1.80 was used"
130+
);
131+
}
132+
}
121133
} else if #[cfg(target_os = "hermit")] {
122134
mod hermit;
123135
pub use hermit::*;

src/backends/apple_other.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use crate::Error;
33
use core::{ffi::c_void, mem::MaybeUninit};
44

5+
pub use crate::util::{inner_u32, inner_u64};
6+
57
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
68
let dst_ptr = dest.as_mut_ptr().cast::<c_void>();
79
let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) };

src/backends/custom.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use crate::Error;
33
use core::mem::MaybeUninit;
44

5+
pub use crate::util::{inner_u32, inner_u64};
6+
57
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
68
extern "Rust" {
79
fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>;

src/backends/esp_idf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use crate::Error;
33
use core::{ffi::c_void, mem::MaybeUninit};
44

5+
pub use crate::util::{inner_u32, inner_u64};
6+
57
#[cfg(not(target_os = "espidf"))]
68
compile_error!("`esp_idf` backend can be enabled only for ESP-IDF targets!");
79

src/backends/fuchsia.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use crate::Error;
33
use core::mem::MaybeUninit;
44

5+
pub use crate::util::{inner_u32, inner_u64};
6+
57
#[link(name = "zircon")]
68
extern "C" {
79
fn zx_cprng_draw(buffer: *mut u8, length: usize);

src/backends/getentropy.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use crate::Error;
1111
use core::{ffi::c_void, mem::MaybeUninit};
1212

13+
pub use crate::util::{inner_u32, inner_u64};
14+
1315
#[path = "../util_libc.rs"]
1416
mod util_libc;
1517

src/backends/getrandom.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use crate::Error;
1919
use core::{ffi::c_void, mem::MaybeUninit};
2020

21+
pub use crate::util::{inner_u32, inner_u64};
22+
2123
#[path = "../util_libc.rs"]
2224
mod util_libc;
2325

src/backends/hermit.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@ use core::mem::MaybeUninit;
44

55
extern "C" {
66
fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;
7+
// Note that `sys_secure_rand32/64` are implemented using `sys_read_entropy`:
8+
// https://github.com/hermit-os/kernel/blob/430da84/src/syscalls/entropy.rs#L62-L104
9+
// But this may change in future and can depend on compilation target,
10+
// so to future-proof we use these "syscalls".
11+
fn sys_secure_rand32(value: *mut u32) -> i32;
12+
fn sys_secure_rand64(value: *mut u64) -> i32;
13+
}
14+
15+
pub fn inner_u32() -> Result<u32, Error> {
16+
let mut res = MaybeUninit::uninit();
17+
let ret = unsafe { sys_secure_rand32(res.as_mut_ptr()) };
18+
match ret {
19+
0 => Ok(unsafe { res.assume_init() }),
20+
-1 => Err(Error::UNSUPPORTED),
21+
_ => Err(Error::UNEXPECTED),
22+
}
23+
}
24+
25+
pub fn inner_u64() -> Result<u64, Error> {
26+
let mut res = MaybeUninit::uninit();
27+
let ret = unsafe { sys_secure_rand64(res.as_mut_ptr()) };
28+
match ret {
29+
0 => Ok(unsafe { res.assume_init() }),
30+
-1 => Err(Error::UNSUPPORTED),
31+
_ => Err(Error::UNEXPECTED),
32+
}
733
}
834

935
pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {

src/backends/linux_android.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
use crate::Error;
33
use core::mem::MaybeUninit;
44

5+
pub use crate::util::{inner_u32, inner_u64};
6+
57
#[path = "../util_libc.rs"]
68
mod util_libc;
79

src/backends/linux_android_with_fallback.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use core::{
99
};
1010
use use_file::util_libc;
1111

12+
pub use crate::util::{inner_u32, inner_u64};
13+
1214
type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t;
1315

1416
/// Sentinel value which indicates that `libc::getrandom` either not available,

0 commit comments

Comments
 (0)