osom_lib_entropy/std/
mod.rs

1mod fill_impl;
2
3use core::marker::PhantomData;
4
5use osom_lib_reprc::macros::reprc;
6
7use crate::traits::{EntropyConcreteGenerator, EntropyGenerator};
8
9/// An enum for handling various failures of entropy generation.
10#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
11#[reprc]
12#[repr(u8)]
13pub enum StdEntropyError {
14    GenericKernelError = 0,
15}
16
17/// The standard entropy generator. It uses various os available
18/// operations to generate entropy:
19///
20/// * `macos` <- it utilizes `getentropy` syscall
21/// * `linux` <- it utilizes `getrandom` syscall
22/// * `windows` <- it utilizes `ProcessPrng` syscall
23///
24/// Other platforms are not supported at the moment.
25#[derive(Debug, Default, Clone, Copy)]
26#[reprc]
27#[must_use]
28pub struct StdEntropyGenerator(PhantomData<()>);
29
30impl StdEntropyGenerator {
31    /// Creates a new instance of [`StdEntropyGenerator`]. This
32    /// method is basically free.
33    #[inline(always)]
34    pub const fn new() -> Self {
35        Self(PhantomData)
36    }
37}
38
39impl EntropyGenerator for StdEntropyGenerator {
40    type Error = StdEntropyError;
41
42    unsafe fn fill_raw(&self, buffer_ptr: *mut u8, buffer_len: usize) -> Result<(), Self::Error> {
43        fill_impl::fill(buffer_ptr, buffer_len)
44    }
45}
46
47macro_rules! concrete {
48    ( $t: ty ) => {
49        impl EntropyConcreteGenerator<StdEntropyGenerator> for $t {
50            #[inline(always)]
51            fn generate(generator: &StdEntropyGenerator) -> Result<Self, StdEntropyError>
52            {
53                let mut item = core::mem::MaybeUninit::<Self>::uninit();
54                let item_ptr = item.as_mut_ptr();
55                let slice = unsafe { core::slice::from_raw_parts_mut(item_ptr.cast::<u8>(), size_of::<Self>()) };
56                generator.fill(slice)?;
57                Ok(unsafe { item.assume_init() })
58            }
59        }
60    };
61    ( $t: ty, $($ts:ty),* $(,)?) => {
62        concrete!($t);
63        concrete!($($ts),*);
64    };
65}
66
67concrete!(i16, u16, i32, u32, i64, u64, usize, isize);