magic_crypt/ciphers/
aes192.rs

1use alloc::vec::Vec;
2#[cfg(feature = "std")]
3use std::intrinsics::copy;
4#[cfg(feature = "std")]
5use std::io::{ErrorKind, Read, Write};
6#[cfg(feature = "std")]
7use std::ops::Add;
8
9#[cfg(feature = "std")]
10use aes::cipher::{
11    block_padding::RawPadding,
12    generic_array::typenum::{IsGreaterOrEqual, PartialDiv, True, B1, U16},
13    ArrayLength,
14};
15use aes::{
16    cipher::{
17        block_padding::Pkcs7, generic_array::GenericArray, BlockDecryptMut, BlockEncryptMut, Iv,
18        Key, KeyIvInit,
19    },
20    Aes192,
21};
22use md5::{Digest, Md5};
23use tiger::Tiger;
24
25#[cfg(feature = "std")]
26use crate::functions::to_blocks;
27use crate::{MagicCryptError, MagicCryptTrait};
28
29type Aes192CbcEnc = cbc::Encryptor<Aes192>;
30type Aes192CbcDec = cbc::Decryptor<Aes192>;
31
32#[cfg(feature = "std")]
33const BLOCK_SIZE: usize = 16;
34
35/// This struct can help you encrypt or decrypt data via AES-192 in a quick way.
36#[derive(Debug, Clone)]
37pub struct MagicCrypt192 {
38    key: Key<Aes192CbcEnc>,
39    iv:  Iv<Aes192CbcEnc>,
40}
41
42impl MagicCryptTrait for MagicCrypt192 {
43    fn new<S: AsRef<[u8]>, V: AsRef<[u8]>>(key: S, iv: Option<V>) -> MagicCrypt192 {
44        let iv = match iv {
45            Some(s) => {
46                let mut hasher = Md5::new();
47                hasher.update(s.as_ref());
48
49                hasher.finalize()
50            },
51            None => GenericArray::default(),
52        };
53
54        let key = {
55            let mut hasher = Tiger::default();
56            hasher.update(key.as_ref());
57
58            hasher.finalize()
59        };
60
61        MagicCrypt192 {
62            key,
63            iv,
64        }
65    }
66
67    #[inline]
68    fn encrypt_to_bytes<T: ?Sized + AsRef<[u8]>>(&self, data: &T) -> Vec<u8> {
69        let data = data.as_ref();
70
71        let cipher = Aes192CbcEnc::new(&self.key, &self.iv);
72
73        cipher.encrypt_padded_vec_mut::<Pkcs7>(data)
74    }
75
76    #[cfg(feature = "std")]
77    fn encrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
78        let mut final_result = Vec::new();
79
80        let data_length = reader.read_to_end(&mut final_result)?;
81
82        let padding_length = BLOCK_SIZE - (data_length % BLOCK_SIZE);
83        let final_length = data_length + padding_length;
84
85        final_result.reserve_exact(padding_length);
86
87        unsafe {
88            final_result.set_len(final_length);
89        }
90
91        let cipher = Aes192CbcEnc::new(&self.key, &self.iv);
92
93        cipher.encrypt_padded_mut::<Pkcs7>(&mut final_result, data_length).unwrap();
94
95        Ok(final_result)
96    }
97
98    #[cfg(feature = "std")]
99    fn encrypt_reader_to_writer2<
100        N: ArrayLength<u8> + PartialDiv<U16> + IsGreaterOrEqual<U16, Output = True>,
101    >(
102        &self,
103        reader: &mut dyn Read,
104        writer: &mut dyn Write,
105    ) -> Result<(), MagicCryptError> {
106        let mut buffer: GenericArray<u8, N> = GenericArray::default();
107
108        let mut cipher = Aes192CbcEnc::new(&self.key, &self.iv);
109
110        let mut l = 0;
111
112        loop {
113            match reader.read(&mut buffer[l..]) {
114                Ok(c) => {
115                    if c == 0 {
116                        break;
117                    }
118
119                    l += c;
120
121                    if l < BLOCK_SIZE {
122                        continue;
123                    }
124
125                    let r = l % BLOCK_SIZE;
126                    let e = l - r;
127
128                    cipher.encrypt_blocks_mut(to_blocks(&mut buffer[..e]));
129
130                    writer.write_all(&buffer[..e])?;
131
132                    unsafe {
133                        copy(buffer.as_ptr().add(e), buffer.as_mut_ptr(), r);
134                    }
135
136                    l = r;
137                },
138                Err(error) if error.kind() == ErrorKind::Interrupted => {},
139                Err(error) => return Err(MagicCryptError::IOError(error)),
140            }
141        }
142
143        let raw_block = &mut buffer[..BLOCK_SIZE];
144
145        Pkcs7::raw_pad(raw_block, l);
146        cipher.encrypt_blocks_mut(to_blocks(raw_block));
147
148        writer.write_all(raw_block)?;
149
150        Ok(writer.flush()?)
151    }
152
153    #[inline]
154    fn decrypt_bytes_to_bytes<T: ?Sized + AsRef<[u8]>>(
155        &self,
156        bytes: &T,
157    ) -> Result<Vec<u8>, MagicCryptError> {
158        let bytes = bytes.as_ref();
159
160        let cipher = Aes192CbcDec::new(&self.key, &self.iv);
161
162        let final_result = cipher.decrypt_padded_vec_mut::<Pkcs7>(bytes)?;
163
164        Ok(final_result)
165    }
166
167    #[cfg(feature = "std")]
168    fn decrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
169        let mut final_result = Vec::new();
170
171        reader.read_to_end(&mut final_result)?;
172
173        let cipher = Aes192CbcDec::new(&self.key, &self.iv);
174
175        let data_length = cipher.decrypt_padded_mut::<Pkcs7>(&mut final_result)?.len();
176
177        final_result.truncate(data_length);
178
179        Ok(final_result)
180    }
181
182    #[cfg(feature = "std")]
183    #[allow(clippy::many_single_char_names)]
184    fn decrypt_reader_to_writer2<
185        N: ArrayLength<u8> + PartialDiv<U16> + IsGreaterOrEqual<U16, Output = True> + Add<B1>,
186    >(
187        &self,
188        reader: &mut dyn Read,
189        writer: &mut dyn Write,
190    ) -> Result<(), MagicCryptError>
191    where
192        <N as Add<B1>>::Output: ArrayLength<u8>, {
193        let mut buffer: GenericArray<u8, N> = GenericArray::default();
194
195        let mut cipher = Aes192CbcDec::new(&self.key, &self.iv);
196        let mut l = 0;
197
198        loop {
199            match reader.read(&mut buffer[l..]) {
200                Ok(c) => {
201                    if c == 0 {
202                        break;
203                    }
204
205                    l += c;
206
207                    if l < BLOCK_SIZE {
208                        continue;
209                    }
210
211                    let r = l % BLOCK_SIZE;
212                    let e = if r > 0 { l + BLOCK_SIZE - r } else { l };
213
214                    // fill the last block
215                    reader.read_exact(&mut buffer[l..e])?;
216
217                    match reader.read_exact(&mut buffer[e..(e + 1)]) {
218                        Ok(()) => {
219                            cipher.decrypt_blocks_mut(to_blocks(&mut buffer[..e]));
220
221                            writer.write_all(&buffer[..e])?;
222
223                            buffer[0] = buffer[e];
224
225                            l = 1;
226                        },
227                        Err(error) if error.kind() == ErrorKind::UnexpectedEof => {
228                            cipher.decrypt_blocks_mut(to_blocks(&mut buffer[..e]));
229
230                            writer.write_all(Pkcs7::raw_unpad(&buffer[..e])?)?;
231
232                            break;
233                        },
234                        Err(error) => return Err(MagicCryptError::IOError(error)),
235                    }
236                },
237                Err(error) if error.kind() == ErrorKind::Interrupted => {},
238                Err(error) => return Err(MagicCryptError::IOError(error)),
239            }
240        }
241
242        Ok(writer.flush()?)
243    }
244}