Coverage Report

Created: 2026-03-31 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cbc-0.1.2/src/decrypt.rs
Line
Count
Source
1
use crate::xor;
2
use cipher::{
3
    crypto_common::{InnerUser, IvSizeUser},
4
    generic_array::{ArrayLength, GenericArray},
5
    inout::InOut,
6
    AlgorithmName, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecryptMut, BlockSizeUser,
7
    InnerIvInit, Iv, IvState, ParBlocks, ParBlocksSizeUser,
8
};
9
use core::fmt;
10
11
#[cfg(feature = "zeroize")]
12
use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
13
14
/// CBC mode decryptor.
15
#[derive(Clone)]
16
pub struct Decryptor<C>
17
where
18
    C: BlockDecryptMut + BlockCipher,
19
{
20
    cipher: C,
21
    iv: Block<C>,
22
}
23
24
impl<C> BlockSizeUser for Decryptor<C>
25
where
26
    C: BlockDecryptMut + BlockCipher,
27
{
28
    type BlockSize = C::BlockSize;
29
}
30
31
impl<C> BlockDecryptMut for Decryptor<C>
32
where
33
    C: BlockDecryptMut + BlockCipher,
34
{
35
0
    fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure<BlockSize = Self::BlockSize>) {
36
0
        let Self { cipher, iv } = self;
37
0
        cipher.decrypt_with_backend_mut(Closure { iv, f })
38
0
    }
39
}
40
41
impl<C> InnerUser for Decryptor<C>
42
where
43
    C: BlockDecryptMut + BlockCipher,
44
{
45
    type Inner = C;
46
}
47
48
impl<C> IvSizeUser for Decryptor<C>
49
where
50
    C: BlockDecryptMut + BlockCipher,
51
{
52
    type IvSize = C::BlockSize;
53
}
54
55
impl<C> InnerIvInit for Decryptor<C>
56
where
57
    C: BlockDecryptMut + BlockCipher,
58
{
59
    #[inline]
60
0
    fn inner_iv_init(cipher: C, iv: &Iv<Self>) -> Self {
61
0
        Self {
62
0
            cipher,
63
0
            iv: iv.clone(),
64
0
        }
65
0
    }
66
}
67
68
impl<C> IvState for Decryptor<C>
69
where
70
    C: BlockDecryptMut + BlockCipher,
71
{
72
    #[inline]
73
    fn iv_state(&self) -> Iv<Self> {
74
        self.iv.clone()
75
    }
76
}
77
78
impl<C> AlgorithmName for Decryptor<C>
79
where
80
    C: BlockDecryptMut + BlockCipher + AlgorithmName,
81
{
82
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
83
        f.write_str("cbc::Decryptor<")?;
84
        <C as AlgorithmName>::write_alg_name(f)?;
85
        f.write_str(">")
86
    }
87
}
88
89
impl<C> fmt::Debug for Decryptor<C>
90
where
91
    C: BlockDecryptMut + BlockCipher + AlgorithmName,
92
{
93
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94
        f.write_str("cbc::Decryptor<")?;
95
        <C as AlgorithmName>::write_alg_name(f)?;
96
        f.write_str("> { ... }")
97
    }
98
}
99
100
#[cfg(feature = "zeroize")]
101
#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
102
impl<C: BlockDecryptMut + BlockCipher> Drop for Decryptor<C> {
103
    fn drop(&mut self) {
104
        self.iv.zeroize();
105
    }
106
}
107
108
#[cfg(feature = "zeroize")]
109
#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
110
impl<C: BlockDecryptMut + BlockCipher + ZeroizeOnDrop> ZeroizeOnDrop for Decryptor<C> {}
111
112
struct Closure<'a, BS, BC>
113
where
114
    BS: ArrayLength<u8>,
115
    BC: BlockClosure<BlockSize = BS>,
116
{
117
    iv: &'a mut GenericArray<u8, BS>,
118
    f: BC,
119
}
120
121
impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC>
122
where
123
    BS: ArrayLength<u8>,
124
    BC: BlockClosure<BlockSize = BS>,
125
{
126
    type BlockSize = BS;
127
}
128
129
impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC>
130
where
131
    BS: ArrayLength<u8>,
132
    BC: BlockClosure<BlockSize = BS>,
133
{
134
    #[inline(always)]
135
0
    fn call<B: BlockBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
136
0
        let Self { iv, f } = self;
137
0
        f.call(&mut Backend { iv, backend });
138
0
    }
Unexecuted instantiation: <cbc::decrypt::Closure<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, cipher::block::BlockCtx<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>> as cipher::block::BlockClosure>::call::<aes::ni::Aes256BackDec>
Unexecuted instantiation: <cbc::decrypt::Closure<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, cipher::block::BlockCtx<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>> as cipher::block::BlockClosure>::call::<aes::soft::Aes256BackDec>
139
}
140
141
struct Backend<'a, BS, BK>
142
where
143
    BS: ArrayLength<u8>,
144
    BK: BlockBackend<BlockSize = BS>,
145
{
146
    iv: &'a mut GenericArray<u8, BS>,
147
    backend: &'a mut BK,
148
}
149
150
impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK>
151
where
152
    BS: ArrayLength<u8>,
153
    BK: BlockBackend<BlockSize = BS>,
154
{
155
    type BlockSize = BS;
156
}
157
158
impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK>
159
where
160
    BS: ArrayLength<u8>,
161
    BK: BlockBackend<BlockSize = BS>,
162
{
163
    type ParBlocksSize = BK::ParBlocksSize;
164
}
165
166
impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK>
167
where
168
    BS: ArrayLength<u8>,
169
    BK: BlockBackend<BlockSize = BS>,
170
{
171
    #[inline(always)]
172
0
    fn proc_block(&mut self, mut block: InOut<'_, '_, Block<Self>>) {
173
0
        let in_block = block.clone_in();
174
0
        let mut t = block.clone_in();
175
0
        self.backend.proc_block((&mut t).into());
176
0
        xor(&mut t, self.iv);
177
0
        *block.get_out() = t;
178
0
        *self.iv = in_block;
179
0
    }
Unexecuted instantiation: <cbc::decrypt::Backend<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, aes::ni::Aes256BackDec> as cipher::block::BlockBackend>::proc_block
Unexecuted instantiation: <cbc::decrypt::Backend<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, aes::soft::Aes256BackDec> as cipher::block::BlockBackend>::proc_block
180
181
    #[inline(always)]
182
    fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks<Self>>) {
183
        let in_blocks = blocks.clone_in();
184
        let mut t = blocks.clone_in();
185
186
        self.backend.proc_par_blocks((&mut t).into());
187
        let n = t.len();
188
        xor(&mut t[0], self.iv);
189
        for i in 1..n {
190
            xor(&mut t[i], &in_blocks[i - 1])
191
        }
192
        *blocks.get_out() = t;
193
        *self.iv = in_blocks[n - 1].clone();
194
    }
195
}