getrandom/
lib.rs

1// Overwrite links to crate items with intra-crate links
2//! [`Error::UNEXPECTED`]: Error::UNEXPECTED
3//! [`fill_uninit`]: fill_uninit
4
5#![no_std]
6#![doc(
7    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
8    html_favicon_url = "https://www.rust-lang.org/favicon.ico"
9)]
10#![doc = include_str!("../README.md")]
11#![cfg_attr(docsrs, feature(doc_cfg))]
12#![cfg_attr(getrandom_backend = "efi_rng", feature(uefi_std))]
13#![cfg_attr(getrandom_backend = "extern_impl", feature(extern_item_impls))]
14
15#[macro_use]
16extern crate cfg_if;
17
18use core::mem::MaybeUninit;
19
20mod backends;
21mod error;
22mod util;
23
24#[cfg(feature = "std")]
25mod error_std_impls;
26
27/// `rand_core` adapter
28#[cfg(feature = "sys_rng")]
29mod sys_rng;
30
31#[cfg(feature = "sys_rng")]
32pub use rand_core;
33#[cfg(feature = "sys_rng")]
34pub use sys_rng::SysRng;
35
36pub use crate::error::{Error, RawOsError};
37
38/// Attribute macros for overwriting the core functionality of this crate.
39///
40/// This allows `getrandom` to provide a default implementation and a common interface
41/// for all crates to use, while giving users a safe way to override that default where required.
42///
43/// Must be enabled via the `extern_impl` opt-in backend, as this functionality
44/// is currently limited to nightly.
45///
46/// # Examples
47///
48/// ```rust
49/// # use core::mem::MaybeUninit;
50/// # #[cfg(getrandom_backend = "extern_impl")]
51/// #[getrandom::implementation::fill_uninit]
52/// fn my_fill_uninit_implementation(
53///     dest: &mut [MaybeUninit<u8>]
54/// ) -> Result<(), getrandom::Error> {
55///     // ...
56/// #   let _ = dest;
57/// #   Err(Error::UNSUPPORTED)
58/// }
59/// ```
60#[cfg(getrandom_backend = "extern_impl")]
61pub mod implementation {
62    pub use crate::backends::extern_impl::{fill_uninit, u32, u64};
63}
64
65/// Fill `dest` with random bytes from the system's preferred random number source.
66///
67/// This function returns an error on any failure, including partial reads. We
68/// make no guarantees regarding the contents of `dest` on error. If `dest` is
69/// empty, `getrandom` immediately returns success, making no calls to the
70/// underlying operating system.
71///
72/// Blocking is possible, at least during early boot; see module documentation.
73///
74/// In general, `getrandom` will be fast enough for interactive usage, though
75/// significantly slower than a user-space CSPRNG; for the latter consider
76/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
77///
78/// # Examples
79///
80/// ```
81/// # fn main() -> Result<(), getrandom::Error> {
82/// let mut buf = [0u8; 32];
83/// getrandom::fill(&mut buf)?;
84/// # Ok(()) }
85/// ```
86#[inline]
87pub fn fill(dest: &mut [u8]) -> Result<(), Error> {
88    // SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape,
89    // and `fill_uninit` guarantees it will never de-initialize
90    // any part of `dest`.
91    fill_uninit(unsafe { util::slice_as_uninit_mut(dest) })?;
92    Ok(())
93}
94
95/// Fill potentially uninitialized buffer `dest` with random bytes from
96/// the system's preferred random number source and return a mutable
97/// reference to those bytes.
98///
99/// On successful completion this function is guaranteed to return a slice
100/// which points to the same memory as `dest` and has the same length.
101/// In other words, it's safe to assume that `dest` is initialized after
102/// this function has returned `Ok`.
103///
104/// No part of `dest` will ever be de-initialized at any point, regardless
105/// of what is returned.
106///
107/// # Examples
108///
109/// ```ignore
110/// # // We ignore this test since `uninit_array` is unstable.
111/// #![feature(maybe_uninit_uninit_array)]
112/// # fn main() -> Result<(), getrandom::Error> {
113/// let mut buf = core::mem::MaybeUninit::uninit_array::<1024>();
114/// let buf: &mut [u8] = getrandom::fill_uninit(&mut buf)?;
115/// # Ok(()) }
116/// ```
117#[inline]
118pub fn fill_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
119    if !dest.is_empty() {
120        backends::fill_inner(dest)?;
121    }
122
123    #[cfg(getrandom_msan)]
124    unsafe extern "C" {
125        fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);
126    }
127
128    // SAFETY: `dest` has been fully initialized by `imp::fill_inner`
129    // since it returned `Ok`.
130    Ok(unsafe { util::slice_assume_init_mut(dest) })
131}
132
133/// Get random `u32` from the system's preferred random number source.
134///
135/// # Examples
136///
137/// ```
138/// # fn main() -> Result<(), getrandom::Error> {
139/// let rng_seed = getrandom::u32()?;
140/// # Ok(()) }
141/// ```
142#[inline]
143pub fn u32() -> Result<u32, Error> {
144    backends::inner_u32()
145}
146
147/// Get random `u64` from the system's preferred random number source.
148///
149/// # Examples
150///
151/// ```
152/// # fn main() -> Result<(), getrandom::Error> {
153/// let rng_seed = getrandom::u64()?;
154/// # Ok(()) }
155/// ```
156#[inline]
157pub fn u64() -> Result<u64, Error> {
158    backends::inner_u64()
159}