use {
crate::{
BlockCipher,
BlockDecrypt,
BlockEncrypt,
BlockMode,
Cipher,
CipherDecrypt,
CipherEncrypt,
Padding,
},
std::{convert::Infallible, fmt},
};
#[derive(Debug)]
pub struct Ecb<Cip, Pad> {
cip: Cip,
pad: Pad,
}
impl<Cip: BlockCipher, Pad: Padding> Ecb<Cip, Pad> {
pub fn new(cip: Cip, pad: Pad) -> Self {
Self { cip, pad }
}
}
impl<Cip: BlockCipher, Pad: Padding> Cipher for Ecb<Cip, Pad>
where
Cip::Block: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
Cip::Key: Clone,
{
type Key = Cip::Key;
}
impl<Cip: BlockCipher, Pad: Padding> BlockMode for Ecb<Cip, Pad>
where
Cip::Block: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
Cip::Key: Clone,
{
}
impl<Enc: BlockEncrypt, Pad: Padding> CipherEncrypt for Ecb<Enc, Pad>
where
Enc::EncryptionBlock: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
Enc::EncryptionKey: Clone,
{
type EncryptionErr = Infallible;
type EncryptionKey = Enc::EncryptionKey;
fn encrypt(
&self,
data: Vec<u8>,
key: Self::EncryptionKey,
) -> Result<Vec<u8>, Self::EncryptionErr> {
let block_size = std::mem::size_of::<Enc::EncryptionBlock>();
let mut data = self.pad.pad(data, block_size);
for chunk in data.chunks_mut(block_size) {
let block = chunk.try_into().unwrap();
chunk.copy_from_slice(self.cip.encrypt(block, key.clone()).as_ref());
}
Ok(data)
}
}
impl<Dec: BlockDecrypt, Pad: Padding> CipherDecrypt for Ecb<Dec, Pad>
where
Dec::DecryptionBlock: for<'a> TryFrom<&'a mut [u8], Error: fmt::Debug> + AsRef<[u8]>,
Dec::DecryptionKey: Clone,
{
type DecryptionErr = Pad::Err;
type DecryptionKey = Dec::DecryptionKey;
fn decrypt(
&self,
mut data: Vec<u8>,
key: Self::DecryptionKey,
) -> Result<Vec<u8>, Self::DecryptionErr> {
let block_size = std::mem::size_of::<Dec::DecryptionBlock>();
for chunk in data.chunks_mut(block_size) {
let block = chunk.try_into().unwrap();
chunk.copy_from_slice(self.cip.decrypt(block, key.clone()).as_ref());
}
self.pad.unpad(data, block_size)
}
}