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