use aes::Aes256;
use block_modes::block_padding::Pkcs7;
use block_modes::{BlockMode, Cbc};
use rand::rngs::OsRng;
use rand::RngCore;
use alloc::vec::Vec;
use super::Error;
type Aes256Cbc = Cbc<Aes256, Pkcs7>;
type Password = [u8; 32];
pub(crate) fn encrypt(plaintext: &[u8], pwd: &Password) -> Result<Vec<u8>, Error> {
let mut iv = [0; 16];
let mut rng = OsRng;
rng.fill_bytes(&mut iv);
let cipher = Aes256Cbc::new_from_slices(pwd, &iv)?;
let enc = cipher.encrypt_vec(plaintext);
let ciphertext = iv.into_iter().chain(enc).collect();
Ok(ciphertext)
}
pub(crate) fn decrypt(ciphertext: &[u8], pwd: &Password) -> Result<Vec<u8>, Error> {
let iv = &ciphertext[..16];
let enc = &ciphertext[16..];
let cipher = Aes256Cbc::new_from_slices(pwd, iv)?;
let plaintext = cipher.decrypt_vec(enc)?;
Ok(plaintext)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encrypt_and_decrypt() {
let seed = b"0001020304050607000102030405060700010203040506070001020304050607";
let pwd = blake3::hash("greatpassword".as_bytes());
let pwd = pwd.as_bytes();
let enc_seed = encrypt(seed, pwd).expect("seed to encrypt ok");
let enc_seed_t = encrypt(seed, pwd).expect("seed to encrypt ok");
assert_ne!(enc_seed, enc_seed_t);
let dec_seed = decrypt(&enc_seed, pwd).expect("seed to decrypt ok");
assert_eq!(dec_seed, seed);
}
}