use crate::IV_LEN;
use aes::cipher::{
Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend,
BlockCipherEncClosure, BlockSizeUser, typenum::U16,
};
pub(crate) struct Ctx<'a> {
pub(crate) blocks_len: usize,
pub(crate) block: &'a mut Block<Self>,
pub(crate) buf: &'a mut [u8],
}
impl BlockSizeUser for Ctx<'_> {
type BlockSize = U16;
}
impl BlockCipherEncClosure for Ctx<'_> {
#[inline(always)]
fn call<B: BlockCipherEncBackend<BlockSize = U16>>(self, backend: &B) {
for j in 0..=5 {
for (i, chunk) in self.buf.chunks_mut(IV_LEN).skip(1).enumerate() {
self.block[IV_LEN..].copy_from_slice(chunk);
backend.encrypt_block(self.block.into());
let t = (self.blocks_len * j + (i + 1)) as u64;
for (ai, ti) in self.block[..IV_LEN].iter_mut().zip(&t.to_be_bytes()) {
*ai ^= ti;
}
chunk.copy_from_slice(&self.block[IV_LEN..]);
}
}
}
}
impl BlockCipherDecClosure for Ctx<'_> {
#[inline(always)]
fn call<B: BlockCipherDecBackend<BlockSize = U16>>(self, backend: &B) {
for j in (0..=5).rev() {
for (i, chunk) in self.buf.chunks_mut(IV_LEN).enumerate().rev() {
let t = (self.blocks_len * j + (i + 1)) as u64;
for (ai, ti) in self.block[..IV_LEN].iter_mut().zip(&t.to_be_bytes()) {
*ai ^= ti;
}
self.block[IV_LEN..].copy_from_slice(chunk);
backend.decrypt_block(self.block.into());
chunk.copy_from_slice(&self.block[IV_LEN..]);
}
}
}
}