1use crate::{
2 errors::InvalidKeyIvLength,
3 traits::BlockMode,
4 utils::{get_par_blocks, Block},
5};
6use block_padding::Padding;
7use cipher::{
8 generic_array::{
9 typenum::{Unsigned, U0},
10 GenericArray,
11 },
12 BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
13};
14use core::marker::PhantomData;
15
16#[derive(Clone)]
23pub struct Ecb<C: BlockCipher + BlockEncrypt + BlockDecrypt, P: Padding> {
24 cipher: C,
25 _p: PhantomData<P>,
26}
27
28impl<C, P> BlockMode<C, P> for Ecb<C, P>
29where
30 C: BlockCipher + BlockEncrypt + BlockDecrypt,
31 P: Padding,
32{
33 type IvSize = U0;
34
35 fn new(cipher: C, _iv: &GenericArray<u8, U0>) -> Self {
36 Self {
37 cipher,
38 _p: Default::default(),
39 }
40 }
41
42 fn new_from_slices(key: &[u8], _iv: &[u8]) -> Result<Self, InvalidKeyIvLength>
43 where
44 C: NewBlockCipher,
45 {
46 let cipher = C::new_from_slice(key).map_err(|_| InvalidKeyIvLength)?;
47 Ok(Self {
48 cipher,
49 _p: Default::default(),
50 })
51 }
52
53 fn encrypt_blocks(&mut self, blocks: &mut [Block<C>]) {
54 if C::ParBlocks::to_usize() != 1 {
55 let (par_blocks, blocks) = get_par_blocks::<C>(blocks);
56 par_blocks
57 .iter_mut()
58 .for_each(|pb| self.cipher.encrypt_blocks(pb));
59 blocks
60 .iter_mut()
61 .for_each(|pb| self.cipher.encrypt_block(pb));
62 } else {
63 blocks
64 .iter_mut()
65 .for_each(|pb| self.cipher.encrypt_block(pb));
66 }
67 }
68
69 fn decrypt_blocks(&mut self, blocks: &mut [Block<C>]) {
70 if C::ParBlocks::to_usize() != 1 {
71 let (par_blocks, blocks) = get_par_blocks::<C>(blocks);
72 par_blocks
73 .iter_mut()
74 .for_each(|pb| self.cipher.decrypt_blocks(pb));
75 blocks
76 .iter_mut()
77 .for_each(|pb| self.cipher.decrypt_block(pb));
78 } else {
79 blocks
80 .iter_mut()
81 .for_each(|pb| self.cipher.decrypt_block(pb));
82 }
83 }
84}