1use aes::cipher::{
2 BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, InnerIvInit, Iv,
3 IvSizeUser,
4};
5use cbc::{Decryptor, Encryptor};
6use digest::crypto_common::InnerUser;
7use generic_array::GenericArray;
8
9use super::block::BlockStreamCipher;
10
11pub struct CbcWrapper<C: BlockEncrypt + BlockCipher + BlockDecrypt> {
12 encryptor: Encryptor<C>,
13 decryptor: Decryptor<C>,
14}
15
16impl<C: BlockEncrypt + BlockCipher + BlockDecrypt> InnerUser for CbcWrapper<C> {
17 type Inner = C;
18}
19
20impl<C: BlockEncrypt + BlockCipher + BlockDecrypt> IvSizeUser for CbcWrapper<C> {
21 type IvSize = C::BlockSize;
22}
23
24impl<C: BlockEncrypt + BlockCipher + BlockDecrypt> BlockStreamCipher for CbcWrapper<C> {
25 fn encrypt_data(&mut self, data: &mut [u8]) {
26 for chunk in data.chunks_exact_mut(C::block_size()) {
27 let mut block: GenericArray<u8, _> = GenericArray::clone_from_slice(chunk);
28 self.encryptor.encrypt_block_mut(&mut block);
29 chunk.clone_from_slice(&block);
30 }
31 }
32
33 fn decrypt_data(&mut self, data: &mut [u8]) {
34 for chunk in data.chunks_exact_mut(C::block_size()) {
35 let mut block = GenericArray::clone_from_slice(chunk);
36 self.decryptor.decrypt_block_mut(&mut block);
37 chunk.clone_from_slice(&block);
38 }
39 }
40}
41
42impl<C: BlockEncrypt + BlockCipher + BlockDecrypt + Clone> InnerIvInit for CbcWrapper<C>
43where
44 C: BlockEncryptMut + BlockCipher,
45{
46 #[inline]
47 fn inner_iv_init(cipher: C, iv: &Iv<Self>) -> Self {
48 Self {
49 encryptor: Encryptor::inner_iv_init(cipher.clone(), iv),
50 decryptor: Decryptor::inner_iv_init(cipher, iv),
51 }
52 }
53}