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