magic_crypt/ciphers/
aes256.rs1use 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 Aes256,
21};
22use md5::{Digest, Md5};
23use sha2::Sha256;
24
25#[cfg(feature = "std")]
26use crate::functions::to_blocks;
27use crate::{MagicCryptError, MagicCryptTrait};
28
29type Aes256CbcEnc = cbc::Encryptor<Aes256>;
30type Aes256CbcDec = cbc::Decryptor<Aes256>;
31
32#[cfg(feature = "std")]
33const BLOCK_SIZE: usize = 16;
34
35#[derive(Debug, Clone)]
37pub struct MagicCrypt256 {
38 key: Key<Aes256CbcEnc>,
39 iv: Iv<Aes256CbcEnc>,
40}
41
42impl MagicCryptTrait for MagicCrypt256 {
43 fn new<S: AsRef<[u8]>, V: AsRef<[u8]>>(key: S, iv: Option<V>) -> MagicCrypt256 {
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 = Sha256::new();
56 hasher.update(key.as_ref());
57
58 hasher.finalize()
59 };
60
61 MagicCrypt256 {
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 = Aes256CbcEnc::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 = Aes256CbcEnc::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 = Aes256CbcEnc::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 = Aes256CbcDec::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 = Aes256CbcDec::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 = Aes256CbcDec::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 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}