Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Breaking Changes
- Update MSRV to 1.60 [#472]

#### Changed
- Bump MSRV to 1.60 [#472]
- Rename `getrandom` and `getrandom_uninit` functions to `fill` and `fill_uninit` respectively [#532]

#### Removed
- `wasm32-wasi` target support (use `wasm32-wasip1` or `wasm32-wasip2` instead) [#499]
Expand Down Expand Up @@ -46,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#520]: https://github.com/rust-random/getrandom/pull/520
[#521]: https://github.com/rust-random/getrandom/pull/521
[#522]: https://github.com/rust-random/getrandom/pull/522
[#532]: https://github.com/rust-random/getrandom/pull/532

## [0.2.15] - 2024-05-06
### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Then invoke the `getrandom` function:
```rust
fn get_random_buf() -> Result<[u8; 32], getrandom::Error> {
let mut buf = [0u8; 32];
getrandom::getrandom(&mut buf)?;
getrandom::fill(&mut buf)?;
Ok(buf)
}
```
Expand Down
18 changes: 9 additions & 9 deletions benches/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use std::mem::MaybeUninit;

// Call getrandom on a zero-initialized stack buffer
#[inline(always)]
fn bench_getrandom<const N: usize>() {
fn bench_fill<const N: usize>() {
let mut buf = [0u8; N];
getrandom::getrandom(&mut buf).unwrap();
getrandom::fill(&mut buf).unwrap();
test::black_box(&buf[..]);
}

// Call getrandom_uninit on an uninitialized stack buffer
// Call fill_uninit on an uninitialized stack buffer
#[inline(always)]
fn bench_getrandom_uninit<const N: usize>() {
fn bench_fill_uninit<const N: usize>() {
let mut uninit = [MaybeUninit::uninit(); N];
let buf: &[u8] = getrandom::getrandom_uninit(&mut uninit).unwrap();
let buf: &[u8] = getrandom::fill_uninit(&mut uninit).unwrap();
test::black_box(buf);
}

Expand All @@ -30,20 +30,20 @@ macro_rules! bench {
( $name:ident, $size:expr ) => {
pub mod $name {
#[bench]
pub fn bench_getrandom(b: &mut test::Bencher) {
pub fn bench_fill(b: &mut test::Bencher) {
#[inline(never)]
fn inner() {
super::bench_getrandom::<{ $size }>()
super::bench_fill::<{ $size }>()
}

b.bytes = $size as u64;
b.iter(inner);
}
#[bench]
pub fn bench_getrandom_uninit(b: &mut test::Bencher) {
pub fn bench_fill_uninit(b: &mut test::Bencher) {
#[inline(never)]
fn inner() {
super::bench_getrandom_uninit::<{ $size }>()
super::bench_fill_uninit::<{ $size }>()
}

b.bytes = $size as u64;
Expand Down
2 changes: 1 addition & 1 deletion nopanic_check/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
#[no_mangle]
pub extern "C" fn getrandom_wrapper(buf_ptr: *mut u8, buf_len: usize) -> u32 {
let buf = unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), buf_len) };
let res = getrandom::getrandom_uninit(buf).map(|_| ());
let res = getrandom::fill_uninit(buf).map(|_| ());
unsafe { core::mem::transmute(res) }
}

Expand Down
2 changes: 1 addition & 1 deletion src/apple-other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Error;
use core::{ffi::c_void, mem::MaybeUninit};

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let dst_ptr = dest.as_mut_ptr().cast::<c_void>();
let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) };
if ret == libc::kCCSuccess {
Expand Down
2 changes: 1 addition & 1 deletion src/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Error;
use core::mem::MaybeUninit;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
extern "Rust" {
fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>;
}
Expand Down
2 changes: 1 addition & 1 deletion src/esp_idf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern "C" {
fn esp_fill_random(buf: *mut c_void, len: usize) -> u32;
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`)
// will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html
Expand Down
2 changes: 1 addition & 1 deletion src/fuchsia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extern "C" {
fn zx_cprng_draw(buffer: *mut u8, length: usize);
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
unsafe { zx_cprng_draw(dest.as_mut_ptr().cast::<u8>(), dest.len()) }
Ok(())
}
2 changes: 1 addition & 1 deletion src/getentropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use crate::{util_libc::last_os_error, Error};
use core::{ffi::c_void, mem::MaybeUninit};

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(256) {
let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::<c_void>(), chunk.len()) };
if ret != 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/getrandom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use crate::{util_libc::sys_fill_exact, Error};
use core::{ffi::c_void, mem::MaybeUninit};

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
sys_fill_exact(dest, |buf| unsafe {
libc::getrandom(buf.as_mut_ptr().cast::<c_void>(), buf.len(), 0)
})
Expand Down
2 changes: 1 addition & 1 deletion src/hermit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern "C" {
fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;
}

pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
while !dest.is_empty() {
let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::<u8>(), dest.len(), 0) };
match res {
Expand Down
43 changes: 26 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@
//!
//! ## Sanitizer support
//!
//! If your code uses `getrandom_uninit` and you use memory sanitizer
//! If your code uses [`fill_uninit`] and you use memory sanitizer
//! (i.e. `-Zsanitizer=memory`), then you need to pass `getrandom_sanitize`
//! configuration flag for `getrandom_uninit` to unpoison destination buffer.
//! configuration flag for `fill_uninit` to unpoison destination buffer.
//!
//! For example, it can be done like this (requires Nightly compiler):
//! ```text
Expand Down Expand Up @@ -304,8 +304,8 @@ use crate::util::{slice_as_uninit_mut, slice_assume_init_mut};

// System-specific implementations.
//
// These should all provide getrandom_inner with the signature
// `fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>`.
// These should all provide fill_inner with the signature
// `fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>`.
// The function MUST fully initialize `dest` when `Ok(())` is returned.
// The function MUST NOT ever write uninitialized bytes into `dest`,
// regardless of what value it returns.
Expand Down Expand Up @@ -442,8 +442,7 @@ cfg_if! {
}
}

/// Fill `dest` with random bytes from the system's preferred random number
/// source.
/// Fill `dest` with random bytes from the system's preferred random number source.
///
/// This function returns an error on any failure, including partial reads. We
/// make no guarantees regarding the contents of `dest` on error. If `dest` is
Expand All @@ -455,17 +454,27 @@ cfg_if! {
/// In general, `getrandom` will be fast enough for interactive usage, though
/// significantly slower than a user-space CSPRNG; for the latter consider
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), getrandom::Error> {
/// let mut buf = [0u8; 32];
/// getrandom::fill(&mut buf)?;
/// # Ok(()) }
/// ```
#[inline]
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
// SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape, and
// `getrandom_uninit` guarantees it will never de-initialize any part of
// `dest`.
getrandom_uninit(unsafe { slice_as_uninit_mut(dest) })?;
pub fn fill(dest: &mut [u8]) -> Result<(), Error> {
// SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape,
// and `fill_uninit` guarantees it will never de-initialize
// any part of `dest`.
fill_uninit(unsafe { slice_as_uninit_mut(dest) })?;
Ok(())
}

/// Version of the `getrandom` function which fills `dest` with random bytes
/// returns a mutable reference to those bytes.
/// Fill potentially uninitialized buffer `dest` with random bytes from
/// the system's preferred random number source and return a mutable
/// reference to those bytes.
///
/// On successful completion this function is guaranteed to return a slice
/// which points to the same memory as `dest` and has the same length.
Expand All @@ -482,13 +491,13 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
/// #![feature(maybe_uninit_uninit_array)]
/// # fn main() -> Result<(), getrandom::Error> {
/// let mut buf = core::mem::MaybeUninit::uninit_array::<1024>();
/// let buf: &mut [u8] = getrandom::getrandom_uninit(&mut buf)?;
/// let buf: &mut [u8] = getrandom::fill_uninit(&mut buf)?;
/// # Ok(()) }
/// ```
#[inline]
pub fn getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
pub fn fill_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
if !dest.is_empty() {
imp::getrandom_inner(dest)?;
imp::fill_inner(dest)?;
}

#[cfg(getrandom_sanitize)]
Expand All @@ -497,7 +506,7 @@ pub fn getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error
fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);
}

// SAFETY: `dest` has been fully initialized by `imp::getrandom_inner`
// SAFETY: `dest` has been fully initialized by `imp::fill_inner`
// since it returned `Ok`.
Ok(unsafe {
#[cfg(getrandom_sanitize)]
Expand Down
2 changes: 1 addition & 1 deletion src/linux_android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::mem::MaybeUninit;
#[cfg(not(any(target_os = "android", target_os = "linux")))]
compile_error!("`linux_getrandom` backend can be enabled only for Linux/Android targets!");

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
util_libc::sys_fill_exact(dest, |buf| unsafe {
libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0)
})
Expand Down
4 changes: 2 additions & 2 deletions src/linux_android_with_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ fn init() -> NonNull<c_void> {
// prevent inlining of the fallback implementation
#[inline(never)]
fn use_file_fallback(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
use_file::getrandom_inner(dest)
use_file::fill_inner(dest)
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Despite being only a single atomic variable, we still cannot always use
// Ordering::Relaxed, as we need to make sure a successful call to `init`
// is "ordered before" any data read through the returned pointer (which
Expand Down
2 changes: 1 addition & 1 deletion src/linux_rustix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustix::rand::{getrandom_uninit, GetRandomFlags};
#[cfg(not(any(target_os = "android", target_os = "linux")))]
compile_error!("`linux_rustix` backend can be enabled only for Linux/Android targets!");

pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
loop {
let res = getrandom_uninit(dest, GetRandomFlags::empty()).map(|(res, _)| res.len());
match res {
Expand Down
2 changes: 1 addition & 1 deletion src/netbsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn init() -> *mut c_void {
ptr
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Despite being only a single atomic variable, we still cannot always use
// Ordering::Relaxed, as we need to make sure a successful call to `init`
// is "ordered before" any data read through the returned pointer (which
Expand Down
2 changes: 1 addition & 1 deletion src/rdrand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn is_rdrand_good() -> bool {
unsafe { self_test() }
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
static RDRAND_GOOD: LazyBool = LazyBool::new();
if !RDRAND_GOOD.unsync_init(is_rdrand_good) {
return Err(Error::NO_RDRAND);
Expand Down
2 changes: 1 addition & 1 deletion src/rndr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn is_rndr_available() -> bool {
}
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
if is_rndr_available() {
// SAFETY: after this point, we know the `rand` target feature is enabled
unsafe { rndr_fill(dest).ok_or(Error::RNDR_FAILURE) }
Expand Down
2 changes: 1 addition & 1 deletion src/solaris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use core::{ffi::c_void, mem::MaybeUninit};

const MAX_BYTES: usize = 1024;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
for chunk in dest.chunks_mut(MAX_BYTES) {
let ptr = chunk.as_mut_ptr().cast::<c_void>();
let ret = unsafe { libc::getrandom(ptr, chunk.len(), libc::GRND_RANDOM) };
Expand Down
2 changes: 1 addition & 1 deletion src/solid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern "C" {
pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32;
}

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr().cast::<u8>(), dest.len()) };
if ret >= 0 {
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/use_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const FD_ONGOING_INIT: libc::c_int = -2;
// `Ordering::Acquire` to synchronize with it.
static FD: AtomicI32 = AtomicI32::new(FD_UNINIT);

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
let mut fd = FD.load(Ordering::Acquire);
if fd == FD_UNINIT || fd == FD_ONGOING_INIT {
fd = open_or_wait()?;
Expand Down
2 changes: 1 addition & 1 deletion src/vxworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::{
sync::atomic::{AtomicBool, Ordering::Relaxed},
};

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
static RNG_INIT: AtomicBool = AtomicBool::new(false);
while !RNG_INIT.load(Relaxed) {
let ret = unsafe { libc::randSecure() };
Expand Down
4 changes: 2 additions & 2 deletions src/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ compile_error!(
);

#[cfg(target_env = "p1")]
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// This linking is vendored from the wasi crate:
// https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2344-2350
#[link(wasm_import_module = "wasi_snapshot_preview1")]
Expand All @@ -38,7 +38,7 @@ pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
}

#[cfg(target_env = "p2")]
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
use core::ptr::copy_nonoverlapping;
use wasi::random::random::get_random_u64;

Expand Down
2 changes: 1 addition & 1 deletion src/wasm_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ thread_local!(
static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
);

pub(crate) fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub(crate) fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
RNG_SOURCE.with(|result| {
let source = result.as_ref().map_err(|&e| e)?;

Expand Down
2 changes: 1 addition & 1 deletion src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ windows_targets::link!("bcryptprimitives.dll" "system" fn ProcessPrng(pbdata: *m
pub type BOOL = i32;
pub const TRUE: BOOL = 1i32;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// ProcessPrng should always return TRUE, but we check just in case.
match unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) } {
TRUE => Ok(()),
Expand Down
2 changes: 1 addition & 1 deletion src/windows7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extern "system" {
type BOOLEAN = u8;
const TRUE: BOOLEAN = 1u8;

pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
// Prevent overflow of u32
let chunk_size = usize::try_from(i32::MAX).expect("Windows does not support 16-bit targets");
for chunk in dest.chunks_mut(chunk_size) {
Expand Down
Loading