use aes::cipher::{generic_array::GenericArray, KeyInit};
use aes::Aes128;
use xts_mode::{get_tweak_default, Xts128};
pub fn decrypt_units(
buffer: &mut [u8],
key1: &[u8; 16],
key2: &[u8; 16],
unit_size: usize,
first_unit_index: u128,
) {
let cipher_1 = Aes128::new(GenericArray::from_slice(key1));
let cipher_2 = Aes128::new(GenericArray::from_slice(key2));
let xts = Xts128::<Aes128>::new(cipher_1, cipher_2);
xts.decrypt_area(buffer, unit_size, first_unit_index, get_tweak_default);
}
#[cfg(test)]
pub(crate) fn encrypt_units(
buffer: &mut [u8],
key1: &[u8; 16],
key2: &[u8; 16],
unit_size: usize,
first_unit_index: u128,
) {
let cipher_1 = Aes128::new(GenericArray::from_slice(key1));
let cipher_2 = Aes128::new(GenericArray::from_slice(key2));
let xts = Xts128::<Aes128>::new(cipher_1, cipher_2);
xts.encrypt_area(buffer, unit_size, first_unit_index, get_tweak_default);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn decrypt_inverts_encrypt() {
let key1 = [0x11u8; 16];
let key2 = [0x22u8; 16];
let plaintext: Vec<u8> = (0..1024u32).map(|i| (i & 0xff) as u8).collect();
let mut buffer = plaintext.clone();
encrypt_units(&mut buffer, &key1, &key2, 512, 5);
assert_ne!(buffer, plaintext, "ciphertext must differ from plaintext");
decrypt_units(&mut buffer, &key1, &key2, 512, 5);
assert_eq!(buffer, plaintext, "decrypt(encrypt(x)) == x");
}
#[test]
fn tweak_index_matters() {
let key1 = [0x33u8; 16];
let key2 = [0x44u8; 16];
let mut a = vec![0u8; 512];
let mut b = vec![0u8; 512];
decrypt_units(&mut a, &key1, &key2, 512, 0);
decrypt_units(&mut b, &key1, &key2, 512, 1);
assert_ne!(a, b);
}
}