1use std::{any::TypeId, marker::PhantomData, mem};
117
118use err::XRCResult;
119use rayon::iter::{IntoParallelIterator, ParallelIterator};
120
121mod cipher;
122mod test;
123mod v2;
124
125pub mod err;
126
127pub trait XrcVersion {}
128pub struct V1;
129impl XrcVersion for V1 {}
130pub struct V2;
131impl XrcVersion for V2 {}
132
133#[cfg(target_pointer_width = "64")]
134pub struct XORCryptor<T> {
135 cipher: cipher::Cipher,
136 e_table: Vec<u16>,
137 d_table: Vec<u16>,
138 raw_seed: usize,
139 _marker: PhantomData<T>,
140}
141
142#[cfg(target_pointer_width = "64")]
143impl<T: XrcVersion> XORCryptor<T> {
144 fn generate_table(e_table: &mut Vec<u16>, d_table: &mut Vec<u16>) {
145 let (mut count, mut shift, mut value, mut bit_mask): (u16, u16, u16, u16);
146 let (mut mask, mut mode) = (0u16, 0u16);
147
148 for i in 0..=255 as u16 {
149 (count, shift, value) = (4, 0, i);
150 while count != 0 {
151 bit_mask = value & 3;
152 let mask_shift: u16 = (bit_mask > 1).into();
153 let mode_shift: u16 = (bit_mask == 0 || bit_mask == 3).into();
154 mask |= mask_shift << shift;
155 mode |= mode_shift << shift;
156
157 count -= 1;
158 shift += 1;
159 value >>= 2;
160 }
161 mask = (mode << 8) | mask;
162 e_table[i as usize] = mask;
163 d_table[mask as usize] = i;
164 (mask, mode) = (0, 0);
165 }
166 }
167
168 #[inline]
169 fn encrypt_byte(&self, val: usize) -> usize {
170 self.e_table[val & 0xFF] as usize
171 | (self.e_table[(val >> 0x8) & 0xFF] as usize) << 0x4
172 | (self.e_table[(val >> 0x10) & 0xFF] as usize) << 0x10
173 | (self.e_table[(val >> 0x18) & 0xFF] as usize) << 0x14
174 | (self.e_table[(val >> 0x20) & 0xFF] as usize) << 0x20
175 | (self.e_table[(val >> 0x28) & 0xFF] as usize) << 0x24
176 | (self.e_table[(val >> 0x30) & 0xFF] as usize) << 0x30
177 | (self.e_table[(val >> 0x38) & 0xFF] as usize) << 0x34
178 }
179
180 #[inline]
181 fn decrypt_byte(&self, val: usize) -> usize {
182 self.d_table[val & 0x0F0F] as usize
183 | (self.d_table[(val >> 0x4) & 0x0F0F] as usize) << 0x8
184 | (self.d_table[(val >> 0x10) & 0x0F0F] as usize) << 0x10
185 | (self.d_table[(val >> 0x14) & 0x0F0F] as usize) << 0x18
186 | (self.d_table[(val >> 0x20) & 0x0F0F] as usize) << 0x20
187 | (self.d_table[(val >> 0x24) & 0x0F0F] as usize) << 0x28
188 | (self.d_table[(val >> 0x30) & 0x0F0F] as usize) << 0x30
189 | (self.d_table[(val >> 0x34) & 0x0F0F] as usize) << 0x38
190 }
191
192 pub fn get_cipher(&self) -> &[usize] {
193 self.cipher.get_cipher()
194 }
195}
196
197#[cfg(target_pointer_width = "64")]
198impl XORCryptor<V1> {
199 pub fn new(key: &str) -> XRCResult<Self> {
201 let cipher = cipher::Cipher::from(key)?;
202 Ok(XORCryptor::init(cipher))
203 }
204
205 pub fn new_bytes(key: &[u8]) -> XRCResult<Self> {
206 let cipher = cipher::Cipher::from_bytes(key)?;
207 Ok(XORCryptor::init(cipher))
208 }
209
210 fn init(cipher: cipher::Cipher) -> Self {
211 let (mut e_table, mut d_table) = (vec![0u16; 256], vec![0u16; 0xF10]);
212 Self::generate_table(&mut e_table, &mut d_table);
213 XORCryptor {
214 cipher,
215 e_table,
216 d_table,
217 raw_seed: 0,
218 _marker: PhantomData,
219 }
220 }
221
222 fn encrypt_buffer(&self, src: &mut Vec<usize>, b_len: usize) {
223 let mut byte_count = b_len;
224 let odd = b_len % 8 != 0;
225 let length = src.len() - if odd { 1 } else { 0 };
226 let src_ptr = Ptr(src.as_mut_ptr());
227
228 byte_count -= 8 * length;
229
230 (0..length).into_par_iter().for_each(move |i| unsafe {
231 let val = *{ src_ptr }.0.add(i);
232 let mut lxi = self.encrypt_byte(val);
233
234 lxi = ((lxi & 0x00FF_00FF_00FF_00FF) << 8) ^ lxi;
235 *{ src_ptr }.0.add(i) = lxi ^ self.cipher.get_cipher_byte(i);
236 });
237
238 if odd {
239 let (val, mut shift) = (src[length], 0usize);
240 let mut lxi = 0usize;
241 while byte_count > 1 {
242 lxi |= (self.e_table[(val >> shift) & 0xFF] as usize) << shift
243 | ((self.e_table[((val >> 8) >> shift) & 0xFF] as usize) << 4) << shift;
244 shift += 16;
245 byte_count -= 2;
246 }
247 let mut mm = self.e_table[(val >> shift) & 0xFF] as usize;
248 mm = ((mm & 0xF00) >> 8) | ((mm & 0xF) << 4);
249 mm ^= mm >> 4;
250 lxi |= mm << shift;
251 lxi = ((lxi & 0x00FF_00FF_00FF_00FF) << 8) ^ lxi;
252 src[length] = lxi ^ self.cipher.get_cipher_byte(length);
253 }
254 }
255
256 fn decrypt_buffer(&self, src: &mut Vec<usize>, b_len: usize) {
257 let mut byte_count = b_len;
258 let odd = b_len % 8 != 0;
259 let length = src.len() - if odd { 1 } else { 0 };
260 let src_ptr = Ptr(src.as_mut_ptr());
261
262 byte_count -= 8 * length;
263
264 (0..length).into_par_iter().for_each(move |i| unsafe {
265 *{ src_ptr }.0.add(i) ^= self.cipher.get_cipher_byte(i);
266 let val = *{ src_ptr }.0.add(i);
267 let xi = ((val & 0x00FF_00FF_00FF_00FF) << 8) ^ val;
268
269 *{ src_ptr }.0.add(i) = self.decrypt_byte(xi);
270 });
271
272 if odd {
273 src[length] ^= self.cipher.get_cipher_byte(length);
274 let xi = ((src[length] & 0x00FF_00FF_00FF_00FF) << 8) ^ src[length];
275 let (mut lxi, mut shift) = (0usize, 0usize);
276 while byte_count > 1 {
277 lxi |= (self.d_table[(xi >> shift) & 0x0F0F] as usize) << shift
278 | (self.d_table[(xi >> shift >> 4) & 0x0F0F] as usize) << 8 << shift;
279 shift += 0x10;
280 byte_count -= 2;
281 }
282 let mut mm = (xi >> shift) & 0xFF;
283 mm ^= mm >> 4;
284 mm = ((mm & 0xF0) >> 4) | ((mm & 0xF) << 8);
285 lxi |= (self.d_table[mm] as usize) << shift;
286 src[length] = lxi;
287 }
288 }
289
290 #[deprecated]
300 pub fn encrypt_vec(&self, buffer: Vec<u8>) -> Vec<u8> {
301 if buffer.is_empty() {
302 return vec![];
303 }
304 let b_len = buffer.len();
305 let mut src = transmute_buffer::<u8, usize>(buffer, 0, 0, Version::V1);
306 self.encrypt_buffer(&mut src, b_len);
307 transmute_buffer(src, b_len, 0, Version::V1)
308 }
309
310 #[deprecated]
318 pub fn decrypt_vec(&self, buffer: Vec<u8>) -> Vec<u8> {
319 if buffer.is_empty() {
320 return vec![];
321 }
322 let b_len = buffer.len();
323 let mut src = transmute_buffer::<u8, usize>(buffer, 0, 0, Version::V1);
324 self.decrypt_buffer(&mut src, b_len);
325 transmute_buffer(src, b_len, 0, Version::V1)
326 }
327}
328
329#[derive(Copy, Clone)]
330struct Ptr<T>(*mut T);
331unsafe impl<T> Send for Ptr<T> {}
332unsafe impl<T> Sync for Ptr<T> {}
333
334enum Version {
335 V1,
336 V2,
337}
338
339fn transmute_buffer<T, R>(mut buffer: Vec<T>, b_len: usize, default: T, version: Version) -> Vec<R>
341where
342 T: Sized + Clone + 'static,
343 R: Sized + 'static,
344{
345 let (t, r) = (TypeId::of::<T>(), TypeId::of::<R>());
346 let (t8, t_usize) = (TypeId::of::<u8>(), TypeId::of::<usize>());
347
348 if (t != t8 || r != t_usize) && (t != t_usize || r != t8) {
349 return vec![];
350 }
351
352 let from_u8_usize = t == t8 && r == t_usize;
353 let len = buffer.len();
354 let (upper, rem) = (len + 8, len % 8);
355 let rem_a = upper % 8;
356
357 let length = if from_u8_usize {
358 let rz: usize = (rem == 0).into();
359 ((len * rz) + (upper * (1 - rz))) / 8
360 } else {
361 len * 8
362 };
363
364 if from_u8_usize {
365 let addition = if rem == 0 { 0 } else { upper - rem_a - len };
366 buffer.resize(
367 buffer.len()
368 + addition
369 + match version {
370 Version::V1 => 0,
371 Version::V2 => 2,
372 },
373 default,
374 );
375 }
376
377 let mut data: Vec<R>;
378 unsafe {
384 let mutptr = buffer.as_ptr() as *mut R;
385 mem::forget(buffer);
386 data = Vec::from_raw_parts(mutptr, length, length)
387 }
388 if !from_u8_usize && b_len != 0 {
389 data.truncate(b_len);
391 }
392 data
393}