use crypto_core::{CryptoError, KdfAlgorithm, KdfFailureKind};
use zeroize::{Zeroize, ZeroizeOnDrop};
use crate::constants::{
ARGON2ID_DERIVED_KEY_LENGTH, ARGON2ID_SALT_MAX_LENGTH, ARGON2ID_SALT_MIN_LENGTH,
ARGON2ID_SECRET_MAX_LENGTH,
};
use crate::profile::Argon2Profile;
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Argon2Secret {
bytes: Vec<u8>,
}
impl Argon2Secret {
pub fn from_slice(input: &[u8], profile: Argon2Profile) -> Result<Self, CryptoError> {
if input.is_empty() || input.len() > ARGON2ID_SECRET_MAX_LENGTH {
return Err(CryptoError::Kdf {
algorithm: KdfAlgorithm::Argon2id,
profile: profile.to_kdf_profile(),
kind: KdfFailureKind::InvalidSecretLength,
});
}
Ok(Self {
bytes: input.to_vec(),
})
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Argon2Salt {
bytes: Vec<u8>,
}
impl Argon2Salt {
pub fn from_slice(input: &[u8], profile: Argon2Profile) -> Result<Self, CryptoError> {
let length = input.len();
if !(ARGON2ID_SALT_MIN_LENGTH..=ARGON2ID_SALT_MAX_LENGTH).contains(&length) {
return Err(CryptoError::Kdf {
algorithm: KdfAlgorithm::Argon2id,
profile: profile.to_kdf_profile(),
kind: KdfFailureKind::InvalidSaltLength,
});
}
Ok(Self {
bytes: input.to_vec(),
})
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct Argon2idDerivedKey {
bytes: [u8; ARGON2ID_DERIVED_KEY_LENGTH],
}
impl Argon2idDerivedKey {
pub fn as_bytes(&self) -> &[u8; ARGON2ID_DERIVED_KEY_LENGTH] {
&self.bytes
}
pub(crate) fn from_array(bytes: [u8; ARGON2ID_DERIVED_KEY_LENGTH]) -> Self {
Self { bytes }
}
}