1 //! `Rng` protocol. 2 3 use crate::proto::unsafe_protocol; 4 use crate::{Result, Status, StatusExt}; 5 use core::{mem, ptr}; 6 7 pub use uefi_raw::protocol::rng::RngAlgorithmType; 8 9 /// Rng protocol 10 #[derive(Debug)] 11 #[repr(transparent)] 12 #[unsafe_protocol(uefi_raw::protocol::rng::RngProtocol::GUID)] 13 pub struct Rng(uefi_raw::protocol::rng::RngProtocol); 14 15 impl Rng { 16 /// Returns information about the random number generation implementation. get_info<'buf>( &mut self, algorithm_list: &'buf mut [RngAlgorithmType], ) -> Result<&'buf [RngAlgorithmType], Option<usize>>17 pub fn get_info<'buf>( 18 &mut self, 19 algorithm_list: &'buf mut [RngAlgorithmType], 20 ) -> Result<&'buf [RngAlgorithmType], Option<usize>> { 21 let mut algorithm_list_size = mem::size_of_val(algorithm_list); 22 23 unsafe { 24 (self.0.get_info)( 25 &mut self.0, 26 &mut algorithm_list_size, 27 algorithm_list.as_mut_ptr(), 28 ) 29 .to_result_with( 30 || { 31 let len = algorithm_list_size / mem::size_of::<RngAlgorithmType>(); 32 &algorithm_list[..len] 33 }, 34 |status| { 35 if status == Status::BUFFER_TOO_SMALL { 36 Some(algorithm_list_size) 37 } else { 38 None 39 } 40 }, 41 ) 42 } 43 } 44 45 /// Returns the next set of random numbers get_rng(&mut self, algorithm: Option<RngAlgorithmType>, buffer: &mut [u8]) -> Result46 pub fn get_rng(&mut self, algorithm: Option<RngAlgorithmType>, buffer: &mut [u8]) -> Result { 47 let buffer_length = buffer.len(); 48 49 let algo = match algorithm.as_ref() { 50 None => ptr::null(), 51 Some(algo) => algo as *const RngAlgorithmType, 52 }; 53 54 unsafe { 55 (self.0.get_rng)(&mut self.0, algo, buffer_length, buffer.as_mut_ptr()).to_result() 56 } 57 } 58 } 59