cfb_mode/
decrypt.rs

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/// CFB mode decryptor.
15#[derive(Clone)]
16pub struct Decryptor<C>
17where
18    C: BlockEncryptMut + BlockCipher,
19{
20    cipher: C,
21    iv: Block<C>,
22}
23
24/// CFB mode buffered decryptor.
25#[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    /// Decrypt a buffer in multiple parts.
40    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    /// Returns the current state (block and position) of the decryptor.
68    pub fn get_state(&self) -> (&Block<C>, usize) {
69        (&self.iv, self.pos)
70    }
71
72    /// Restore from the given state for resumption.
73    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}