osom_lib_entropy/std/
mod.rs1mod fill_impl;
5
6use core::{convert::Infallible, marker::PhantomData};
7
8use osom_lib_reprc::macros::reprc;
9use osom_lib_try_clone::TryClone;
10
11use crate::traits::{EntropyConcreteGenerator, EntropyGenerator};
12
13#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
15#[reprc]
16#[repr(u8)]
17pub enum StdEntropyError {
18 GenericKernelError = 0,
20
21 UnsupportedPlatform = 1,
23}
24
25impl TryClone for StdEntropyError {
26 type Error = Infallible;
27 fn try_clone(&self) -> Result<Self, Self::Error> {
28 Ok(*self)
29 }
30}
31
32osom_lib_macros::unreachable_from_infallible!(StdEntropyError);
33
34impl core::fmt::Display for StdEntropyError {
35 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36 write!(
37 f,
38 "StdEntropyError::{}",
39 match self {
40 StdEntropyError::GenericKernelError => "GenericKernelError",
41 StdEntropyError::UnsupportedPlatform => "UnsupportedPlatform",
42 }
43 )
44 }
45}
46
47#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
56#[reprc]
57#[repr(transparent)]
58#[must_use]
59pub struct StdEntropyGenerator {
60 _phantom: PhantomData<()>,
61}
62
63impl TryClone for StdEntropyGenerator {
64 type Error = Infallible;
65 fn try_clone(&self) -> Result<Self, Self::Error> {
66 Ok(*self)
67 }
68}
69
70impl StdEntropyGenerator {
71 #[inline(always)]
74 pub const fn new() -> Self {
75 Self { _phantom: PhantomData }
76 }
77}
78
79impl EntropyGenerator for StdEntropyGenerator {
80 type Error = StdEntropyError;
81
82 unsafe fn fill_raw(&mut self, buffer_ptr: *mut u8, buffer_len: usize) -> Result<(), Self::Error> {
83 fill_impl::fill(buffer_ptr, buffer_len)
84 }
85}
86
87#[inline]
88fn generate_random_t<T: Copy, TGen: EntropyGenerator>(gene: &mut TGen) -> Result<T, TGen::Error> {
89 let mut item = core::mem::MaybeUninit::<T>::uninit();
90 let item_ptr = item.as_mut_ptr();
91 let slice = unsafe { core::slice::from_raw_parts_mut(item_ptr.cast::<u8>(), size_of::<T>()) };
92 gene.fill(slice)?;
93 Ok(unsafe { item.assume_init() })
94}
95
96impl<const N: usize> EntropyConcreteGenerator<StdEntropyGenerator> for [u8; N] {
97 #[inline(always)]
98 fn generate(generator: &mut StdEntropyGenerator) -> Result<Self, StdEntropyError> {
99 if N == 0 {
100 return Ok([0u8; N]);
101 }
102 generate_random_t(generator)
103 }
104}
105
106macro_rules! concrete {
107 ( $t: ty ) => {
108 impl EntropyConcreteGenerator<StdEntropyGenerator> for $t {
109 #[inline(always)]
110 fn generate(generator: &mut StdEntropyGenerator) -> Result<Self, StdEntropyError>
111 {
112 generate_random_t(generator)
113 }
114 }
115 };
116 ( $t: ty, $($ts:ty),* $(,)?) => {
117 concrete!($t);
118 concrete!($($ts),*);
119 };
120}
121
122concrete!(i16, u16, i32, u32, i64, u64, i128, u128, usize, isize);