#[cfg(feature = "alloc")]
extern crate alloc;
use dcrypt_internal::constant_time::ConstantTimeEq;
use dcrypt_internal::random::{try_fill_bytes_zeroing_on_error, CryptoRng, Error as RandomError};
#[cfg(feature = "alloc")]
use dcrypt_internal::zeroing::{boxed_bytes_zeroed, Zeroizing, ZeroizingBytes};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum SecurityLevel {
L128,
L192,
L256,
Custom(u32),
}
impl SecurityLevel {
pub fn bits(&self) -> u32 {
match self {
SecurityLevel::L128 => 128,
SecurityLevel::L192 => 192,
SecurityLevel::L256 => 256,
SecurityLevel::Custom(bits) => *bits,
}
}
pub fn recommended_output_size(&self) -> usize {
(self.bits() / 4) as usize
}
pub fn meets_minimum(&self, minimum: SecurityLevel) -> bool {
self.bits() >= minimum.bits()
}
}
#[inline]
pub fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
a.ct_eq(b).into()
}
#[cfg(feature = "alloc")]
pub fn generate_salt<R: CryptoRng + ?Sized>(
rng: &mut R,
len: usize,
) -> core::result::Result<ZeroizingBytes, RandomError> {
let mut salt = Zeroizing::new(boxed_bytes_zeroed(len));
try_fill_bytes_zeroing_on_error(rng, &mut salt)?;
Ok(salt)
}