// Overwrite links to crate items with intra-crate links //! [`Error::UNEXPECTED`]: Error::UNEXPECTED //! [`fill_uninit`]: fill_uninit #![no_std] #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico" )] #![doc = include_str!("../README.md")] #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(getrandom_backend = "efi_rng", feature(uefi_std))] #![deny( clippy::cast_lossless, clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_precision_loss, clippy::cast_ptr_alignment, clippy::cast_sign_loss, clippy::char_lit_as_u8, clippy::checked_conversions, clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation, clippy::ptr_as_ptr, clippy::unnecessary_cast, clippy::useless_conversion )] #[macro_use] extern crate cfg_if; use core::mem::MaybeUninit; mod backends; mod error; mod util; #[cfg(feature = "std")] mod error_std_impls; pub use crate::error::Error; /// 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 /// empty, `getrandom` immediately returns success, making no calls to the /// underlying operating system. /// /// Blocking is possible, at least during early boot; see module documentation. /// /// 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 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 { util::slice_as_uninit_mut(dest) })?; Ok(()) } /// 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. /// In other words, it's safe to assume that `dest` is initialized after /// this function has returned `Ok`. /// /// No part of `dest` will ever be de-initialized at any point, regardless /// of what is returned. /// /// # Examples /// /// ```ignore /// # // We ignore this test since `uninit_array` is unstable. /// #![feature(maybe_uninit_uninit_array)] /// # fn main() -> Result<(), getrandom::Error> { /// let mut buf = core::mem::MaybeUninit::uninit_array::<1024>(); /// let buf: &mut [u8] = getrandom::fill_uninit(&mut buf)?; /// # Ok(()) } /// ``` #[inline] pub fn fill_uninit(dest: &mut [MaybeUninit]) -> Result<&mut [u8], Error> { if !dest.is_empty() { backends::fill_inner(dest)?; } #[cfg(getrandom_msan)] extern "C" { fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize); } // SAFETY: `dest` has been fully initialized by `imp::fill_inner` // since it returned `Ok`. Ok(unsafe { #[cfg(getrandom_msan)] __msan_unpoison(dest.as_mut_ptr().cast(), dest.len()); util::slice_assume_init_mut(dest) }) } /// Get random `u32` from the system's preferred random number source. /// /// # Examples /// /// ``` /// # fn main() -> Result<(), getrandom::Error> { /// let rng_seed = getrandom::u32()?; /// # Ok(()) } /// ``` #[inline] pub fn u32() -> Result { backends::inner_u32() } /// Get random `u64` from the system's preferred random number source. /// /// # Examples /// /// ``` /// # fn main() -> Result<(), getrandom::Error> { /// let rng_seed = getrandom::u64()?; /// # Ok(()) } /// ``` #[inline] pub fn u64() -> Result { backends::inner_u64() }