130 lines
3.3 KiB
Rust
130 lines
3.3 KiB
Rust
//! 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())
|
|
}
|
|
}
|