use crate::err::EncryptionError;
use aes_gcm::Aes256Gcm;
use aes_gcm::aead:: {
Aead,
generic_array::GenericArray
};
use aes_gcm::KeyInit;
use rand:: {
Rng,
thread_rng
};
use crate::pbkdf::PBKDF;
use crate::pbkdf::KeyDerivation;
use crate::NONCE_SIZE;
#[derive(Clone)]
pub struct AesEncryptor {
cipher: Aes256Gcm,
}
pub trait Encryptor {
fn new(password: &str) -> Result<Self,
EncryptionError>
where
Self: Sized;
fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>,
EncryptionError>;
fn random_nonce() -> Vec<u8>;
fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>,
EncryptionError>;
}
impl Encryptor for AesEncryptor {
fn new(password: &str) -> Result<Self,
EncryptionError> {
let kdfp = PBKDF::new(password.to_string())?;
let key = GenericArray::from_slice(&kdfp);
let cipher = Aes256Gcm::new(key);
Ok(AesEncryptor {
cipher
})
}
fn random_nonce() -> Vec<u8> {
let mut rng = thread_rng();
let mut vec = Vec::with_capacity(NONCE_SIZE);
for _ in 0..NONCE_SIZE {
vec.push(rng.gen::<u8>());
}
vec
}
fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>,
EncryptionError> {
let binding = Self::random_nonce();
let nonce = GenericArray::from_slice(&binding); let ciphertext = self.cipher.encrypt(nonce, data.as_ref())
.map_err(|err| EncryptionError::EncryptionFailed(err.to_string()));
let mut encrypted_data = Vec::with_capacity(nonce.len() + ciphertext.clone()?.len());
encrypted_data.extend_from_slice(&nonce);
encrypted_data.extend_from_slice(&ciphertext?);
Ok(encrypted_data)
}
fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>,
EncryptionError> {
let nonce = GenericArray::from_slice(&data[0..NONCE_SIZE]);
self.cipher.decrypt(nonce, data[NONCE_SIZE..].as_ref())
.map_err(|err| EncryptionError::DecryptionFailed(err.to_string()))
}
}