russh/cipher/
cbc.rs

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}