use crate::Error;
use aes::{
cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit},
Aes128,
};
use bytes::Bytes;
use xor_name::XOR_NAME_LEN;
type Aes128CbcEnc = cbc::Encryptor<Aes128>;
type Aes128CbcDec = cbc::Decryptor<Aes128>;
pub(crate) const KEY_SIZE: usize = 16;
pub(crate) const IV_SIZE: usize = 16;
pub(crate) const HASH_SIZE: usize = XOR_NAME_LEN;
pub(crate) const PAD_SIZE: usize = (HASH_SIZE * 3) - KEY_SIZE - IV_SIZE;
pub(crate) struct Pad(pub [u8; PAD_SIZE]);
pub(crate) struct Key(pub [u8; KEY_SIZE]);
pub(crate) struct Iv(pub [u8; IV_SIZE]);
pub(crate) fn encrypt(data: Bytes, key: &Key, iv: &Iv) -> Result<Bytes, Error> {
let cipher = Aes128CbcEnc::new(key.0.as_ref().into(), iv.0.as_ref().into());
Ok(Bytes::from(cipher.encrypt_padded_vec_mut::<Pkcs7>(&data)))
}
pub(crate) fn decrypt(encrypted_data: Bytes, key: &Key, iv: &Iv) -> Result<Bytes, Error> {
let cipher = Aes128CbcDec::new(key.0.as_ref().into(), iv.0.as_ref().into());
match cipher.decrypt_padded_vec_mut::<Pkcs7>(encrypted_data.as_ref()) {
Ok(vec) => Ok(Bytes::from(vec)),
Err(err) => Err(Error::Decryption(format!(
"Decrypt failed with UnpadError({:?})",
err
))),
}
}