//! Public or symmetric key wrappers, nonces and all that magic stuff pub mod asym; mod errors; pub mod hkdf; pub mod sym; #[cfg(test)] mod tests; pub use errors::Error; use ::ring::rand::SecureRandom; use ::zeroize::Zeroize; /// wrapper where we implement whatever random traint stuff each library needs pub struct Random { /// actual source of randomness rnd: ::ring::rand::SystemRandom, } impl Random { /// Build a nre Random source pub fn new() -> Self { Self { rnd: ::ring::rand::SystemRandom::new(), } } /// Fill a buffer with randomness pub fn fill(&self, out: &mut [u8]) { let _ = self.rnd.fill(out); } /// return the underlying ring SystemRandom pub fn ring_rnd(&self) -> &::ring::rand::SystemRandom { &self.rnd } } // Fake debug implementation to avoid leaking secrets impl ::core::fmt::Debug for Random { fn fmt( &self, f: &mut core::fmt::Formatter<'_>, ) -> Result<(), ::std::fmt::Error> { ::core::fmt::Debug::fmt("[hidden randomness]", f) } } // ::rand_core::{RngCore, CryptoRng} needed for ::x25519::dalek impl ::rand_core::RngCore for &Random { fn next_u32(&mut self) -> u32 { use ::core::mem::MaybeUninit; let mut out: MaybeUninit<[u8; 4]> = MaybeUninit::uninit(); #[allow(unsafe_code)] unsafe { let _ = self.rnd.fill(out.assume_init_mut()); u32::from_le_bytes(out.assume_init()) } } fn next_u64(&mut self) -> u64 { use ::core::mem::MaybeUninit; let mut out: MaybeUninit<[u8; 8]> = MaybeUninit::uninit(); #[allow(unsafe_code)] unsafe { let _ = self.rnd.fill(out.assume_init_mut()); u64::from_le_bytes(out.assume_init()) } } fn fill_bytes(&mut self, dest: &mut [u8]) { let _ = self.rnd.fill(dest); } fn try_fill_bytes( &mut self, dest: &mut [u8], ) -> Result<(), ::rand_core::Error> { match self.rnd.fill(dest) { Ok(()) => Ok(()), Err(e) => Err(::rand_core::Error::new(e)), } } } impl ::rand_core::CryptoRng for &Random {} /// Secret, used for keys. /// Grants that on drop() we will zero out memory #[derive(Zeroize, Clone, PartialEq)] #[zeroize(drop)] pub struct Secret([u8; 32]); // Fake debug implementation to avoid leaking secrets impl ::core::fmt::Debug for Secret { fn fmt( &self, f: &mut core::fmt::Formatter<'_>, ) -> Result<(), ::std::fmt::Error> { ::core::fmt::Debug::fmt("[hidden secret]", f) } } impl Secret { /// return the length of the serialized secret pub const fn len() -> usize { 32 } /// New randomly generated secret pub fn new_rand(rand: &Random) -> Self { let mut ret = Self([0; 32]); rand.fill(&mut ret.0); ret } /// return a reference to the secret pub fn as_ref(&self) -> &[u8; 32] { &self.0 } } impl From<[u8; 32]> for Secret { fn from(shared_secret: [u8; 32]) -> Self { Self(shared_secret) } } impl From<&[u8; 32]> for Secret { fn from(shared_secret: &[u8; 32]) -> Self { Self(*shared_secret) } } impl From<::x25519_dalek::SharedSecret> for Secret { fn from(shared_secret: ::x25519_dalek::SharedSecret) -> Self { Self(shared_secret.to_bytes()) } }