diff options
Diffstat (limited to 'rust/kernel/src/random.rs')
-rw-r--r-- | rust/kernel/src/random.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/rust/kernel/src/random.rs b/rust/kernel/src/random.rs new file mode 100644 index 000000000000..bd80c835749d --- /dev/null +++ b/rust/kernel/src/random.rs @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 + +use core::convert::TryInto; + +use crate::{bindings, c_types, error}; + +/// Fills `dest` with random bytes generated from the kernel's CSPRNG. Ensures +/// that the CSPRNG has been seeded before generating any random bytes, and +/// will block until it's ready. +pub fn getrandom(dest: &mut [u8]) -> error::KernelResult<()> { + let res = unsafe { bindings::wait_for_random_bytes() }; + if res != 0 { + return Err(error::Error::from_kernel_errno(res)); + } + + unsafe { + bindings::get_random_bytes( + dest.as_mut_ptr() as *mut c_types::c_void, + dest.len().try_into()?, + ); + } + Ok(()) +} + +/// Fills `dest` with random bytes generated from the kernel's CSPRNG. If the +/// CSPRNG is not yet seeded, returns an `Err(EAGAIN)` immediately. +pub fn getrandom_nonblock(dest: &mut [u8]) -> error::KernelResult<()> { + if !unsafe { bindings::rng_is_initialized() } { + return Err(error::Error::EAGAIN); + } + getrandom(dest) +} + +/// Contributes the contents of `data` to the kernel's entropy pool. Does _not_ +/// credit the kernel entropy counter though. +pub fn add_randomness(data: &[u8]) { + unsafe { + bindings::add_device_randomness( + data.as_ptr() as *const c_types::c_void, + data.len().try_into().unwrap(), + ); + } +} |