use alloc::boxed::Box;
use generic_array::{ArrayLength, GenericArray};
use hkdf::Hkdf;
use sha2::Sha256;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[derive(Clone)] pub struct SecretBox<T>(Box<T>)
where
T: Zeroize + Clone;
impl<T: PartialEq + Zeroize + Clone> PartialEq<SecretBox<T>> for SecretBox<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> SecretBox<T>
where
T: Zeroize + Clone,
{
pub(crate) fn new(val: T) -> Self {
Self(Box::new(val))
}
pub fn as_secret(&self) -> &T {
self.0.as_ref()
}
pub fn as_mut_secret(&mut self) -> &mut T {
self.0.as_mut()
}
}
impl<T> Drop for SecretBox<T>
where
T: Zeroize + Clone,
{
fn drop(&mut self) {
self.0.zeroize()
}
}
impl<T> ZeroizeOnDrop for SecretBox<T> where T: Zeroize + Clone {}
pub fn kdf<S: ArrayLength<u8>>(seed: &[u8], info: Option<&[u8]>) -> SecretBox<GenericArray<u8, S>> {
let hk = Hkdf::<Sha256>::new(None, seed);
let mut okm = SecretBox::new(GenericArray::<u8, S>::default());
let def_info = info.unwrap_or_default();
hk.expand(def_info, okm.as_mut_secret()).unwrap();
okm
}