magic_crypt/ciphers/
des64.rs1use alloc::vec::Vec;
2#[cfg(feature = "std")]
3use std::io::{Read, Write};
4
5#[cfg(feature = "std")]
6use aes::cipher::{
7 array::ArraySize,
8 typenum::{IsGreaterOrEqual, PartialDiv, True, U16},
9};
10use crc_any::CRCu64;
11use des::{
12 Des,
13 cipher::{
14 BlockModeDecrypt, BlockModeEncrypt, Iv, Key, KeyIvInit, array::Array, block_padding::Pkcs7,
15 },
16};
17
18#[cfg(feature = "std")]
19use crate::functions::{
20 decrypt_reader_to_writer as decrypt_stream, encrypt_reader_to_writer as encrypt_stream,
21 to_blocks,
22};
23use crate::{MagicCryptError, MagicCryptTrait};
24
25type Des64CbcEnc = cbc::Encryptor<Des>;
26type Des64CbcDec = cbc::Decryptor<Des>;
27
28#[cfg(feature = "std")]
29const BLOCK_SIZE: usize = 8;
30
31#[derive(Clone)]
33pub struct MagicCrypt64 {
34 key: Key<Des64CbcEnc>,
35 iv: Iv<Des64CbcEnc>,
36}
37
38impl_cipher_secret_traits!(MagicCrypt64);
39
40impl MagicCryptTrait for MagicCrypt64 {
41 fn new<S: AsRef<[u8]>, V: AsRef<[u8]>>(key: S, iv: Option<V>) -> MagicCrypt64 {
42 let iv = match iv {
43 Some(s) => {
44 let mut hasher = CRCu64::crc64we();
45 hasher.digest(s.as_ref());
46
47 Array::try_from(hasher.get_crc_vec_be().as_slice()).unwrap()
48 },
49 None => Array::default(),
50 };
51
52 let key = {
53 let mut hasher = CRCu64::crc64we();
54 hasher.digest(key.as_ref());
55
56 Array::try_from(hasher.get_crc_vec_be().as_slice()).unwrap()
57 };
58
59 MagicCrypt64 {
60 key,
61 iv,
62 }
63 }
64
65 #[inline]
66 fn encrypt_to_bytes<T: ?Sized + AsRef<[u8]>>(&self, data: &T) -> Vec<u8> {
67 let data = data.as_ref();
68
69 let cipher = Des64CbcEnc::new(&self.key, &self.iv);
70
71 cipher.encrypt_padded_vec::<Pkcs7>(data)
72 }
73
74 #[cfg(feature = "std")]
75 fn encrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
76 use aes::cipher::block_padding::NoPadding;
77
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 let padding_byte = padding_length as u8;
87
88 final_result.resize(final_length, padding_byte);
89
90 let cipher = Des64CbcEnc::new(&self.key, &self.iv);
91
92 cipher.encrypt_padded::<NoPadding>(&mut final_result, final_length).unwrap();
93
94 Ok(final_result)
95 }
96
97 #[cfg(feature = "std")]
98 fn encrypt_reader_to_writer2<
99 N: ArraySize + 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 cipher = Des64CbcEnc::new(&self.key, &self.iv);
106
107 encrypt_stream::<N>(reader, writer, BLOCK_SIZE, |buffer| {
108 cipher.encrypt_blocks(to_blocks(buffer));
109 })
110 }
111
112 #[inline]
113 fn decrypt_bytes_to_bytes<T: ?Sized + AsRef<[u8]>>(
114 &self,
115 bytes: &T,
116 ) -> Result<Vec<u8>, MagicCryptError> {
117 let bytes = bytes.as_ref();
118
119 let cipher = Des64CbcDec::new(&self.key, &self.iv);
120
121 let final_result = cipher.decrypt_padded_vec::<Pkcs7>(bytes)?;
122
123 Ok(final_result)
124 }
125
126 #[cfg(feature = "std")]
127 fn decrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
128 let mut final_result = Vec::new();
129
130 reader.read_to_end(&mut final_result)?;
131
132 let cipher = Des64CbcDec::new(&self.key, &self.iv);
133
134 let data_length = cipher.decrypt_padded::<Pkcs7>(&mut final_result)?.len();
135
136 final_result.truncate(data_length);
137
138 Ok(final_result)
139 }
140
141 #[cfg(feature = "std")]
142 fn decrypt_reader_to_writer2<
143 N: ArraySize + PartialDiv<U16> + IsGreaterOrEqual<U16, Output = True>,
144 >(
145 &self,
146 reader: &mut dyn Read,
147 writer: &mut dyn Write,
148 ) -> Result<(), MagicCryptError> {
149 let mut cipher = Des64CbcDec::new(&self.key, &self.iv);
150
151 decrypt_stream::<N>(reader, writer, BLOCK_SIZE, |buffer| {
152 cipher.decrypt_blocks(to_blocks(buffer));
153 })
154 }
155}