1use cipher::{
2 crypto_common::{InnerUser, IvSizeUser},
3 generic_array::{ArrayLength, GenericArray},
4 inout::InOut,
5 AlgorithmName, AsyncStreamCipher, Block, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt,
6 BlockDecryptMut, BlockEncryptMut, BlockSizeUser, InnerIvInit, Iv, IvState, ParBlocks,
7 ParBlocksSizeUser, Unsigned,
8};
9use core::fmt;
10
11#[cfg(feature = "zeroize")]
12use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
13
14#[derive(Clone)]
16pub struct Decryptor<C>
17where
18 C: BlockEncryptMut + BlockCipher,
19{
20 cipher: C,
21 iv: Block<C>,
22}
23
24#[derive(Clone)]
26pub struct BufDecryptor<C>
27where
28 C: BlockEncryptMut + BlockCipher,
29{
30 cipher: C,
31 iv: Block<C>,
32 pos: usize,
33}
34
35impl<C> BufDecryptor<C>
36where
37 C: BlockEncryptMut + BlockCipher,
38{
39 pub fn decrypt(&mut self, mut data: &mut [u8]) {
41 let bs = C::BlockSize::to_usize();
42 let n = data.len();
43
44 if n < bs - self.pos {
45 xor_set2(data, &mut self.iv[self.pos..self.pos + n]);
46 self.pos += n;
47 return;
48 }
49 let (left, right) = { data }.split_at_mut(bs - self.pos);
50 data = right;
51 let mut iv = self.iv.clone();
52 xor_set2(left, &mut iv[self.pos..]);
53 self.cipher.encrypt_block_mut(&mut iv);
54
55 let mut chunks = data.chunks_exact_mut(bs);
56 for chunk in &mut chunks {
57 xor_set2(chunk, iv.as_mut_slice());
58 self.cipher.encrypt_block_mut(&mut iv);
59 }
60
61 let rem = chunks.into_remainder();
62 xor_set2(rem, iv.as_mut_slice());
63 self.pos = rem.len();
64 self.iv = iv;
65 }
66
67 pub fn get_state(&self) -> (&Block<C>, usize) {
69 (&self.iv, self.pos)
70 }
71
72 pub fn from_state(cipher: C, iv: &Block<C>, pos: usize) -> Self {
74 Self {
75 cipher,
76 iv: iv.clone(),
77 pos,
78 }
79 }
80}
81
82impl<C> BlockSizeUser for Decryptor<C>
83where
84 C: BlockEncryptMut + BlockCipher,
85{
86 type BlockSize = C::BlockSize;
87}
88
89impl<C> BlockDecryptMut for Decryptor<C>
90where
91 C: BlockEncryptMut + BlockCipher,
92{
93 fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure<BlockSize = Self::BlockSize>) {
94 let Self { cipher, iv } = self;
95 cipher.encrypt_with_backend_mut(Closure { iv, f })
96 }
97}
98
99impl<C> AsyncStreamCipher for Decryptor<C> where C: BlockEncryptMut + BlockCipher {}
100
101impl<C> InnerUser for Decryptor<C>
102where
103 C: BlockEncryptMut + BlockCipher,
104{
105 type Inner = C;
106}
107
108impl<C> InnerUser for BufDecryptor<C>
109where
110 C: BlockEncryptMut + BlockCipher,
111{
112 type Inner = C;
113}
114
115impl<C> IvSizeUser for Decryptor<C>
116where
117 C: BlockEncryptMut + BlockCipher,
118{
119 type IvSize = C::BlockSize;
120}
121
122impl<C> IvSizeUser for BufDecryptor<C>
123where
124 C: BlockEncryptMut + BlockCipher,
125{
126 type IvSize = C::BlockSize;
127}
128
129impl<C> InnerIvInit for Decryptor<C>
130where
131 C: BlockEncryptMut + BlockCipher,
132{
133 #[inline]
134 fn inner_iv_init(mut cipher: C, iv: &Iv<Self>) -> Self {
135 let mut iv = iv.clone();
136 cipher.encrypt_block_mut(&mut iv);
137 Self { cipher, iv }
138 }
139}
140
141impl<C> InnerIvInit for BufDecryptor<C>
142where
143 C: BlockEncryptMut + BlockCipher,
144{
145 #[inline]
146 fn inner_iv_init(mut cipher: C, iv: &Iv<Self>) -> Self {
147 let mut iv = iv.clone();
148 cipher.encrypt_block_mut(&mut iv);
149 Self { cipher, iv, pos: 0 }
150 }
151}
152
153impl<C> IvState for Decryptor<C>
154where
155 C: BlockEncryptMut + BlockDecrypt + BlockCipher,
156{
157 #[inline]
158 fn iv_state(&self) -> Iv<Self> {
159 let mut res = self.iv.clone();
160 self.cipher.decrypt_block(&mut res);
161 res
162 }
163}
164
165impl<C> AlgorithmName for Decryptor<C>
166where
167 C: BlockEncryptMut + BlockCipher + AlgorithmName,
168{
169 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 f.write_str("cfb::Decryptor<")?;
171 <C as AlgorithmName>::write_alg_name(f)?;
172 f.write_str(">")
173 }
174}
175
176impl<C> AlgorithmName for BufDecryptor<C>
177where
178 C: BlockEncryptMut + BlockCipher + AlgorithmName,
179{
180 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 f.write_str("cfb::BufDecryptor<")?;
182 <C as AlgorithmName>::write_alg_name(f)?;
183 f.write_str(">")
184 }
185}
186
187impl<C> fmt::Debug for Decryptor<C>
188where
189 C: BlockEncryptMut + BlockCipher + AlgorithmName,
190{
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 f.write_str("cfb::Decryptor<")?;
193 <C as AlgorithmName>::write_alg_name(f)?;
194 f.write_str("> { ... }")
195 }
196}
197
198impl<C> fmt::Debug for BufDecryptor<C>
199where
200 C: BlockEncryptMut + BlockCipher + AlgorithmName,
201{
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 f.write_str("cfb::BufDecryptor<")?;
204 <C as AlgorithmName>::write_alg_name(f)?;
205 f.write_str("> { ... }")
206 }
207}
208
209#[cfg(feature = "zeroize")]
210#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
211impl<C: BlockEncryptMut + BlockCipher> Drop for Decryptor<C> {
212 fn drop(&mut self) {
213 self.iv.zeroize();
214 }
215}
216
217#[cfg(feature = "zeroize")]
218#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
219impl<C: BlockEncryptMut + BlockCipher> Drop for BufDecryptor<C> {
220 fn drop(&mut self) {
221 self.iv.zeroize();
222 }
223}
224
225#[cfg(feature = "zeroize")]
226#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
227impl<C: BlockEncryptMut + BlockCipher + ZeroizeOnDrop> ZeroizeOnDrop for Decryptor<C> {}
228
229#[cfg(feature = "zeroize")]
230#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
231impl<C: BlockEncryptMut + BlockCipher + ZeroizeOnDrop> ZeroizeOnDrop for BufDecryptor<C> {}
232
233struct Closure<'a, BS, BC>
234where
235 BS: ArrayLength<u8>,
236 BC: BlockClosure<BlockSize = BS>,
237{
238 iv: &'a mut GenericArray<u8, BS>,
239 f: BC,
240}
241
242impl<'a, BS, BC> BlockSizeUser for Closure<'a, BS, BC>
243where
244 BS: ArrayLength<u8>,
245 BC: BlockClosure<BlockSize = BS>,
246{
247 type BlockSize = BS;
248}
249
250impl<'a, BS, BC> BlockClosure for Closure<'a, BS, BC>
251where
252 BS: ArrayLength<u8>,
253 BC: BlockClosure<BlockSize = BS>,
254{
255 #[inline(always)]
256 fn call<B: BlockBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
257 let Self { iv, f } = self;
258 f.call(&mut Backend { iv, backend });
259 }
260}
261
262struct Backend<'a, BS, BK>
263where
264 BS: ArrayLength<u8>,
265 BK: BlockBackend<BlockSize = BS>,
266{
267 iv: &'a mut GenericArray<u8, BS>,
268 backend: &'a mut BK,
269}
270
271impl<'a, BS, BK> BlockSizeUser for Backend<'a, BS, BK>
272where
273 BS: ArrayLength<u8>,
274 BK: BlockBackend<BlockSize = BS>,
275{
276 type BlockSize = BS;
277}
278
279impl<'a, BS, BK> ParBlocksSizeUser for Backend<'a, BS, BK>
280where
281 BS: ArrayLength<u8>,
282 BK: BlockBackend<BlockSize = BS>,
283{
284 type ParBlocksSize = BK::ParBlocksSize;
285}
286
287impl<'a, BS, BK> BlockBackend for Backend<'a, BS, BK>
288where
289 BS: ArrayLength<u8>,
290 BK: BlockBackend<BlockSize = BS>,
291{
292 #[inline(always)]
293 fn proc_block(&mut self, mut block: InOut<'_, '_, Block<Self>>) {
294 let mut t = block.clone_in();
295 block.xor_in2out(self.iv);
296 self.backend.proc_block((&mut t).into());
297 *self.iv = t;
298 }
299
300 #[inline(always)]
301 fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks<Self>>) {
302 let mut t = ParBlocks::<Self>::default();
303 let b = (blocks.get_in(), &mut t).into();
304 self.backend.proc_par_blocks(b);
305
306 let n = t.len();
307 blocks.get(0).xor_in2out(self.iv);
308 for i in 1..n {
309 blocks.get(i).xor_in2out(&t[i - 1])
310 }
311 *self.iv = t[n - 1].clone();
312 }
313}
314
315#[inline(always)]
316fn xor_set2(buf1: &mut [u8], buf2: &mut [u8]) {
317 for (a, b) in buf1.iter_mut().zip(buf2) {
318 let t = *a;
319 *a ^= *b;
320 *b = t;
321 }
322}