summaryrefslogtreecommitdiffstats
path: root/rust/kernel/src/random.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/src/random.rs')
-rw-r--r--rust/kernel/src/random.rs43
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(),
+ );
+ }
+}