blob: a973f9844c90a82d598954267352e46882217b29 [file] [log] [blame] [edit]
//! `Rng` protocol.
use crate::proto::unsafe_protocol;
use crate::{Result, Status, StatusExt};
use core::{mem, ptr};
pub use uefi_raw::protocol::rng::RngAlgorithmType;
/// Rng protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(uefi_raw::protocol::rng::RngProtocol::GUID)]
pub struct Rng(uefi_raw::protocol::rng::RngProtocol);
impl Rng {
/// Returns information about the random number generation implementation.
pub fn get_info<'buf>(
&mut self,
algorithm_list: &'buf mut [RngAlgorithmType],
) -> Result<&'buf [RngAlgorithmType], Option<usize>> {
let mut algorithm_list_size = mem::size_of_val(algorithm_list);
unsafe {
(self.0.get_info)(
&mut self.0,
&mut algorithm_list_size,
algorithm_list.as_mut_ptr(),
)
.to_result_with(
|| {
let len = algorithm_list_size / mem::size_of::<RngAlgorithmType>();
&algorithm_list[..len]
},
|status| {
if status == Status::BUFFER_TOO_SMALL {
Some(algorithm_list_size)
} else {
None
}
},
)
}
}
/// Returns the next set of random numbers
pub fn get_rng(&mut self, algorithm: Option<RngAlgorithmType>, buffer: &mut [u8]) -> Result {
let buffer_length = buffer.len();
let algo = match algorithm.as_ref() {
None => ptr::null(),
Some(algo) => algo as *const RngAlgorithmType,
};
unsafe {
(self.0.get_rng)(&mut self.0, algo, buffer_length, buffer.as_mut_ptr()).to_result()
}
}
}