1use aes_gcm::{
2 aead::{Aead, KeyInit},
3 Aes256Gcm, Nonce,
4};
5use hkdf::Hkdf;
6use rand::{Rng, RngCore};
7use secrecy::{ExposeSecret, SecretVec};
8use sha2::Sha256;
9use std::collections::HashMap;
10use std::sync::atomic::{AtomicU64, Ordering};
11use std::time::{SystemTime, UNIX_EPOCH};
12use zeroize::{Zeroize, Zeroizing};
13
14pub const DEFAULT_KEY_LEN: usize = 32;
15pub const DEFAULT_NONCE_LEN: usize = 12;
16pub const MAX_STACK_SECRET_LEN: usize = 256;
17
18static SESSION_COUNTER: AtomicU64 = AtomicU64::new(0);
19
20const OBFUSCATION_ROUNDS: usize = 16;
21const KEY_DERIVATION_ROUNDS: usize = 32;
22const FRAGMENT_SPACE_SIZE: usize = 4096;
23const JUNK_DATA_SIZE: usize = 1024;
24
25#[derive(Debug)]
26pub enum RustcryptError {
27 MalformedInput,
28 Encrypt,
29 Decrypt,
30 InvalidKey,
31 HardwareKey,
32 StackTooLarge,
33}
34
35impl std::fmt::Display for RustcryptError {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 RustcryptError::MalformedInput => write!(f, "malformed input"),
39 RustcryptError::Encrypt => write!(f, "encryption failure"),
40 RustcryptError::Decrypt => write!(f, "decryption failure"),
41 RustcryptError::InvalidKey => write!(f, "invalid key length"),
42 RustcryptError::HardwareKey => write!(f, "hardware key failure"),
43 RustcryptError::StackTooLarge => write!(f, "stack allocation too large"),
44 }
45 }
46}
47
48impl std::error::Error for RustcryptError {}
49
50#[derive(Clone, Copy, Default)]
51pub enum EncryptionLayers {
52 Single,
53 #[default]
54 Double,
55 Triple,
56 Military,
57}
58
59fn to_key(key: &SecretVec<u8>) -> Result<aes_gcm::Key<aes_gcm::aes::Aes256>, RustcryptError> {
60 if key.expose_secret().len() != DEFAULT_KEY_LEN {
61 return Err(RustcryptError::InvalidKey);
62 }
63 Ok(aes_gcm::Key::<aes_gcm::aes::Aes256>::from_slice(key.expose_secret()).to_owned())
64}
65
66fn gen_nonce() -> [u8; DEFAULT_NONCE_LEN] {
67 let mut nonce = [0u8; DEFAULT_NONCE_LEN];
68 rand::thread_rng().fill_bytes(&mut nonce);
69 nonce
70}
71
72fn obfuscate_control_flow(mut value: u8, rounds: usize) -> u8 {
73 for r in 0..rounds {
74 let mask = 0xA5u8.rotate_left((r % 8) as u32);
75 value ^= mask;
76 }
77 value
78}
79
80fn derive_military_key(base_key: &[u8], context: &[u8]) -> [u8; 32] {
81 let mut derived = [0u8; 32];
82 let mut rng = rand::thread_rng();
83
84 let timestamp = SystemTime::now()
85 .duration_since(UNIX_EPOCH)
86 .unwrap()
87 .as_nanos() as u64;
88 for round in 0..KEY_DERIVATION_ROUNDS {
89 let mut round_key = [0u8; 32];
90 for (i, slot) in round_key.iter_mut().enumerate() {
91 let base_byte = base_key[i % base_key.len()];
92 let context_byte = context[i % context.len()];
93 let round_byte = (round as u8).wrapping_add(i as u8);
94 let time_byte = ((timestamp >> (i % 8)) & 0xFF) as u8;
95
96 *slot = base_byte
97 .wrapping_add(context_byte)
98 .wrapping_add(round_byte)
99 .wrapping_add(time_byte);
100 }
101 for byte in &mut round_key {
102 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS);
103 }
104 for (d, rk) in derived.iter_mut().zip(round_key.iter()) {
105 *d ^= *rk;
106 }
107 let mut entropy = [0u8; 4];
108 rng.fill_bytes(&mut entropy);
109 let entropy_val = u32::from_le_bytes(entropy);
110 for (i, d) in derived.iter_mut().enumerate() {
111 *d = d.wrapping_add(((entropy_val >> (i % 4)) & 0xFF) as u8);
112 }
113 }
114
115 derived
116}
117
118fn generate_junk_data() -> Vec<u8> {
119 let mut junk = vec![0u8; JUNK_DATA_SIZE];
120 rand::thread_rng().fill_bytes(&mut junk);
121 for i in (0..junk.len()).step_by(16) {
122 if i + 15 < junk.len() {
123 junk[i] = 0x2B;
124 junk[i + 1] = 0x7E;
125 junk[i + 2] = 0x15;
126 junk[i + 3] = 0x16;
127 }
128 }
129
130 junk
131}
132
133#[derive(Clone)]
134pub struct ObfuscatedKey {
135 fragments: HashMap<usize, u8>,
136 masks: HashMap<usize, u8>,
137 key_len: usize,
138 #[allow(dead_code)]
139 seed: u64,
140 junk_data: Vec<u8>,
141 obfuscation_level: usize,
142}
143
144impl ObfuscatedKey {
145 pub fn new(key: &[u8]) -> Self {
146 let mut rng = rand::thread_rng();
147 let mut fragments = HashMap::new();
148 let mut masks = HashMap::new();
149 let junk_data = generate_junk_data();
150 let derived_key = derive_military_key(key, b"military_grade_context");
151 for &byte in derived_key.iter() {
152 for bit_idx in 0..8 {
153 let bit = (byte >> bit_idx) & 1;
154 let fragment_pos = rng.gen_range(0..FRAGMENT_SPACE_SIZE);
155 let mask = rng.gen::<u8>();
156 let mut obfuscated_bit = bit;
157 for _ in 0..OBFUSCATION_ROUNDS {
158 obfuscated_bit = obfuscate_control_flow(obfuscated_bit, 1);
159 }
160 fragments.insert(fragment_pos, obfuscated_bit ^ (mask & 1));
161 masks.insert(fragment_pos, mask);
162 }
163 }
164 Self {
165 fragments,
166 masks,
167 key_len: key.len(),
168 seed: rng.gen(),
169 junk_data,
170 obfuscation_level: OBFUSCATION_ROUNDS,
171 }
172 }
173 pub fn reconstruct(&self) -> Result<Vec<u8>, RustcryptError> {
174 let mut key = vec![0u8; self.key_len];
175 let mut bit_positions = Vec::new();
176 for &pos in self.fragments.keys() {
177 bit_positions.push(pos);
178 }
179 bit_positions.sort();
180 let mut current_byte = 0u8;
181 let mut bit_count = 0;
182 let mut byte_idx = 0;
183 for &pos in &bit_positions {
184 if let (Some(&fragment), Some(&mask)) = (self.fragments.get(&pos), self.masks.get(&pos))
185 {
186 let mut deobfuscated_bit = fragment ^ (mask & 1);
187 for _ in 0..self.obfuscation_level {
188 deobfuscated_bit = obfuscate_control_flow(deobfuscated_bit, 1);
189 }
190 current_byte |= deobfuscated_bit << (bit_count % 8);
191 bit_count += 1;
192 if bit_count % 8 == 0 {
193 if byte_idx < self.key_len {
194 key[byte_idx] = current_byte;
195 byte_idx += 1;
196 }
197 current_byte = 0;
198 }
199 }
200 }
201 if byte_idx != self.key_len {
202 return Err(RustcryptError::MalformedInput);
203 }
204 for (i, k) in key.iter_mut().enumerate() {
205 let junk_idx = i % self.junk_data.len();
206 *k = k.wrapping_sub(self.junk_data[junk_idx]);
207 }
208 Ok(key)
209 }
210 pub fn fragments(&self) -> &HashMap<usize, u8> {
211 &self.fragments
212 }
213}
214
215impl Drop for ObfuscatedKey {
216 fn drop(&mut self) {
217 self.fragments.clear();
218 self.masks.clear();
219 self.junk_data.zeroize();
220 }
221}
222
223fn gen_ephemeral_key() -> SecretVec<u8> {
224 let session_id = SESSION_COUNTER.fetch_add(1, Ordering::SeqCst);
225 let mut key = [0u8; DEFAULT_KEY_LEN];
226 rand::thread_rng().fill_bytes(&mut key);
227 for (i, byte) in key.iter_mut().enumerate() {
228 *byte ^= ((session_id >> (i % 8)) & 0xFF) as u8;
229 }
230 SecretVec::new(key.to_vec())
231}
232
233fn gen_obfuscated_ephemeral_key() -> ObfuscatedKey {
234 let session_id = SESSION_COUNTER.fetch_add(1, Ordering::SeqCst);
235 let mut key = [0u8; DEFAULT_KEY_LEN];
236 rand::thread_rng().fill_bytes(&mut key);
237 for (i, byte) in key.iter_mut().enumerate() {
238 *byte ^= ((session_id >> (i % 8)) & 0xFF) as u8;
239 }
240 ObfuscatedKey::new(&key)
241}
242
243fn gen_hardware_key() -> Result<SecretVec<u8>, RustcryptError> {
244 Err(RustcryptError::HardwareKey)
245}
246
247pub struct StackSecret<const N: usize> {
248 data: [u8; N],
249 len: usize,
250}
251
252impl<const N: usize> StackSecret<N> {
253 pub fn new(data: &[u8]) -> Result<Self, RustcryptError> {
254 if data.len() > N {
255 return Err(RustcryptError::StackTooLarge);
256 }
257 let mut secret = Self {
258 data: [0u8; N],
259 len: data.len(),
260 };
261 secret.data[..data.len()].copy_from_slice(data);
262 Ok(secret)
263 }
264
265 pub fn as_slice(&self) -> &[u8] {
266 &self.data[..self.len]
267 }
268}
269
270impl<const N: usize> Drop for StackSecret<N> {
271 fn drop(&mut self) {
272 self.data.zeroize();
273 }
274}
275
276pub fn hide_layered(
277 input: &[u8],
278 key: &SecretVec<u8>,
279 layers: EncryptionLayers,
280) -> Result<Vec<u8>, RustcryptError> {
281 match layers {
282 EncryptionLayers::Single => hide_single(input, key),
283 EncryptionLayers::Double => hide_double(input, key),
284 EncryptionLayers::Triple => hide_triple(input, key),
285 EncryptionLayers::Military => hide_military(input, key),
286 }
287}
288
289pub fn hide(input: &[u8], key: &SecretVec<u8>) -> Result<Vec<u8>, RustcryptError> {
290 hide_layered(input, key, EncryptionLayers::default())
291}
292
293fn hide_single(input: &[u8], key: &SecretVec<u8>) -> Result<Vec<u8>, RustcryptError> {
294 let key = to_key(key)?;
295 let cipher = Aes256Gcm::new(&key);
296 let nonce_bytes = gen_nonce();
297 let nonce = Nonce::from_slice(&nonce_bytes);
298
299 let mut obfuscated_input = input.to_vec();
300 for byte in &mut obfuscated_input {
301 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS);
302 }
303 let ct = cipher
304 .encrypt(nonce, obfuscated_input.as_slice())
305 .map_err(|_| RustcryptError::Encrypt)?;
306 let mut obfuscated_ct = ct;
307 for byte in &mut obfuscated_ct {
308 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS);
309 }
310 let mut out = Vec::with_capacity(DEFAULT_NONCE_LEN + obfuscated_ct.len());
311 out.extend_from_slice(&nonce_bytes);
312 out.extend_from_slice(&obfuscated_ct);
313 Ok(out)
314}
315
316fn hide_double(input: &[u8], key: &SecretVec<u8>) -> Result<Vec<u8>, RustcryptError> {
317 use chacha20poly1305::{XChaCha20Poly1305, XNonce};
318
319 let stage1 = hide_single(input, key)?;
320
321 let mut salt = [0u8; 16];
322 rand::thread_rng().fill_bytes(&mut salt);
323 let hk = Hkdf::<Sha256>::new(Some(&salt), key.expose_secret());
324 let mut xkey = [0u8; 32];
325 hk.expand(b"double/xchacha", &mut xkey)
326 .map_err(|_| RustcryptError::Encrypt)?;
327
328 let xchacha = XChaCha20Poly1305::new_from_slice(&xkey).map_err(|_| RustcryptError::Encrypt)?;
329 let mut xnonce_bytes = [0u8; 24];
330 rand::thread_rng().fill_bytes(&mut xnonce_bytes);
331 let xnonce = XNonce::from_slice(&xnonce_bytes);
332 let xct = xchacha
333 .encrypt(xnonce, stage1.as_ref())
334 .map_err(|_| RustcryptError::Encrypt)?;
335
336 let mut out = Vec::with_capacity(16 + 24 + xct.len());
337 out.extend_from_slice(&salt);
338 out.extend_from_slice(&xnonce_bytes);
339 out.extend_from_slice(&xct);
340 Ok(out)
341}
342
343fn hide_triple(input: &[u8], key: &SecretVec<u8>) -> Result<Vec<u8>, RustcryptError> {
344 let stage2 = hide_double(input, key)?;
345 let mut salt = [0u8; 16];
346 rand::thread_rng().fill_bytes(&mut salt);
347 let hk = Hkdf::<Sha256>::new(Some(&salt), key.expose_secret());
348 let mut stream_mask = vec![0u8; stage2.len()];
349 hk.expand(b"triple/mask", &mut stream_mask)
350 .map_err(|_| RustcryptError::Encrypt)?;
351
352 let mut obfuscated = stage2.clone();
353 for (byte, mask) in obfuscated.iter_mut().zip(stream_mask.iter()) {
354 *byte ^= *mask;
355 }
356
357 let mut out = Vec::with_capacity(16 + obfuscated.len());
358 out.extend_from_slice(&salt);
359 out.extend_from_slice(&obfuscated);
360 Ok(out)
361}
362
363pub fn reveal_layered(
364 input: &[u8],
365 key: &SecretVec<u8>,
366 layers: EncryptionLayers,
367) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
368 match layers {
369 EncryptionLayers::Single => reveal_single(input, key),
370 EncryptionLayers::Double => reveal_double(input, key),
371 EncryptionLayers::Triple => reveal_triple(input, key),
372 EncryptionLayers::Military => reveal_military(input, key),
373 }
374}
375
376pub fn reveal(input: &[u8], key: &SecretVec<u8>) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
377 reveal_layered(input, key, EncryptionLayers::default())
378}
379
380fn reveal_single(input: &[u8], key: &SecretVec<u8>) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
381 if input.len() < DEFAULT_NONCE_LEN {
382 return Err(RustcryptError::MalformedInput);
383 }
384 let key = to_key(key)?;
385 let cipher = Aes256Gcm::new(&key);
386 let (nonce_part, ct) = input.split_at(DEFAULT_NONCE_LEN);
387 let nonce = Nonce::from_slice(nonce_part);
388
389 let mut deobfuscated_ct = ct.to_vec();
390 for byte in &mut deobfuscated_ct {
391 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS);
392 }
393 let mut pt = cipher
394 .decrypt(nonce, deobfuscated_ct.as_slice())
395 .map_err(|_| RustcryptError::Decrypt)?;
396 for byte in &mut pt {
397 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS);
398 }
399 Ok(Zeroizing::new(pt))
400}
401
402fn reveal_double(input: &[u8], key: &SecretVec<u8>) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
403 use chacha20poly1305::{XChaCha20Poly1305, XNonce};
404
405 if input.len() < 16 + 24 {
406 return Err(RustcryptError::MalformedInput);
407 }
408
409 let (salt_part, rest) = input.split_at(16);
410 let (xnonce_part, xct) = rest.split_at(24);
411 let hk = Hkdf::<Sha256>::new(Some(salt_part), key.expose_secret());
412 let mut xkey = [0u8; 32];
413 hk.expand(b"double/xchacha", &mut xkey)
414 .map_err(|_| RustcryptError::Decrypt)?;
415 let xchacha = XChaCha20Poly1305::new_from_slice(&xkey).map_err(|_| RustcryptError::Decrypt)?;
416 let xnonce = XNonce::from_slice(xnonce_part);
417 let stage1 = xchacha
418 .decrypt(xnonce, xct)
419 .map_err(|_| RustcryptError::Decrypt)?;
420 reveal_single(&stage1, key)
421}
422
423fn reveal_triple(input: &[u8], key: &SecretVec<u8>) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
424 if input.len() < 16 {
425 return Err(RustcryptError::MalformedInput);
426 }
427 let (salt_part, obfuscated) = input.split_at(16);
428 let hk = Hkdf::<Sha256>::new(Some(salt_part), key.expose_secret());
429 let mut stream_mask = vec![0u8; obfuscated.len()];
430 hk.expand(b"triple/mask", &mut stream_mask)
431 .map_err(|_| RustcryptError::Decrypt)?;
432 let mut deobfuscated = obfuscated.to_vec();
433 for (byte, mask) in deobfuscated.iter_mut().zip(stream_mask.iter()) {
434 *byte ^= *mask;
435 }
436 reveal_double(&deobfuscated, key)
437}
438
439fn hide_military(input: &[u8], key: &SecretVec<u8>) -> Result<Vec<u8>, RustcryptError> {
440 let triple_encrypted = hide_triple(input, key)?;
441 let mut salt = [0u8; 16];
442 rand::thread_rng().fill_bytes(&mut salt);
443 let hk = Hkdf::<Sha256>::new(Some(&salt), key.expose_secret());
444 let mut military_key = [0u8; 32];
445 hk.expand(b"military_encryption", &mut military_key)
446 .map_err(|_| RustcryptError::Encrypt)?;
447 let military_secret = SecretVec::new(military_key.to_vec());
448 let military_encrypted = hide_triple(&triple_encrypted, &military_secret)?;
449 let mut final_obfuscated = military_encrypted;
450 for byte in &mut final_obfuscated {
451 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS * 2);
452 }
453 let junk_data = generate_junk_data();
454 let mut output = Vec::with_capacity(final_obfuscated.len() + junk_data.len() + 4 + 16);
455 output.extend_from_slice(&(junk_data.len() as u32).to_le_bytes());
456 output.extend_from_slice(&junk_data);
457 output.extend_from_slice(&salt);
458 output.extend_from_slice(&final_obfuscated);
459 Ok(output)
460}
461
462fn reveal_military(
463 input: &[u8],
464 key: &SecretVec<u8>,
465) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
466 if input.len() < 4 {
467 return Err(RustcryptError::MalformedInput);
468 }
469 let junk_len = u32::from_le_bytes([input[0], input[1], input[2], input[3]]) as usize;
470 if input.len() < 4 + junk_len + 16 {
471 return Err(RustcryptError::MalformedInput);
472 }
473 let after_junk = &input[4 + junk_len..];
474 let (salt_part, encrypted_data) = after_junk.split_at(16);
475 let mut deobfuscated = encrypted_data.to_vec();
476 for byte in &mut deobfuscated {
477 *byte = obfuscate_control_flow(*byte, OBFUSCATION_ROUNDS * 2);
478 }
479 let hk = Hkdf::<Sha256>::new(Some(salt_part), key.expose_secret());
480 let mut military_key = [0u8; 32];
481 hk.expand(b"military_encryption", &mut military_key)
482 .map_err(|_| RustcryptError::Decrypt)?;
483 let military_secret = SecretVec::new(military_key.to_vec());
484 let triple_decrypted = reveal_triple(&deobfuscated, &military_secret)?;
485 reveal_triple(&triple_decrypted, key)
486}
487
488pub struct Rustcrypt {
489 key: SecretVec<u8>,
490 layers: EncryptionLayers,
491 use_ephemeral: bool,
492}
493
494pub struct ObfuscatedRustcrypt {
495 obfuscated_key: ObfuscatedKey,
496 layers: EncryptionLayers,
497}
498
499impl Rustcrypt {
500 pub fn new(option: Option<&[u8]>) -> Result<Self, RustcryptError> {
501 Self::with_config(option, EncryptionLayers::default(), false)
502 }
503 pub fn with_config(
504 key_option: Option<&[u8]>,
505 layers: EncryptionLayers,
506 use_ephemeral: bool,
507 ) -> Result<Self, RustcryptError> {
508 let key_vec = match key_option {
509 Some(k) if k.len() == DEFAULT_KEY_LEN => SecretVec::new(k.to_vec()),
510 Some(_) => return Err(RustcryptError::InvalidKey),
511 None => {
512 if use_ephemeral {
513 gen_ephemeral_key()
514 } else {
515 let mut tmp = vec![0u8; DEFAULT_KEY_LEN];
516 rand::thread_rng().fill_bytes(&mut tmp);
517 SecretVec::new(tmp)
518 }
519 }
520 };
521 Ok(Self {
522 key: key_vec,
523 layers,
524 use_ephemeral,
525 })
526 }
527
528 pub fn with_hardware_key(layers: EncryptionLayers) -> Result<Self, RustcryptError> {
529 let key = gen_hardware_key()?;
530 Ok(Self {
531 key,
532 layers,
533 use_ephemeral: false,
534 })
535 }
536
537 pub fn hide(&self, input: &str) -> Result<Vec<u8>, RustcryptError> {
538 hide_layered(input.as_bytes(), &self.key, self.layers)
539 }
540 pub fn hide_bytes(&self, input: &[u8]) -> Result<Vec<u8>, RustcryptError> {
541 hide_layered(input, &self.key, self.layers)
542 }
543
544 pub fn reveal(&self, input: &[u8]) -> Result<String, RustcryptError> {
545 let out = reveal_layered(input, &self.key, self.layers)?;
546 String::from_utf8(out.to_vec()).map_err(|_| RustcryptError::MalformedInput)
547 }
548 pub fn reveal_bytes(&self, input: &[u8]) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
549 reveal_layered(input, &self.key, self.layers)
550 }
551 pub fn hide_stack<const N: usize>(
552 &self,
553 input: &[u8],
554 ) -> Result<StackSecret<N>, RustcryptError> {
555 if input.len() > N {
556 return Err(RustcryptError::StackTooLarge);
557 }
558 let encrypted = self.hide_bytes(input)?;
559 StackSecret::new(&encrypted)
560 }
561 pub fn layers(&self) -> EncryptionLayers {
562 self.layers
563 }
564 pub fn is_ephemeral(&self) -> bool {
565 self.use_ephemeral
566 }
567}
568
569impl Drop for Rustcrypt {
570 fn drop(&mut self) {}
571}
572
573impl ObfuscatedRustcrypt {
574 pub fn new(layers: EncryptionLayers) -> Self {
575 let obfuscated_key = gen_obfuscated_ephemeral_key();
576 Self {
577 obfuscated_key,
578 layers,
579 }
580 }
581 pub fn from_obfuscated_key(obfuscated_key: ObfuscatedKey, layers: EncryptionLayers) -> Self {
582 Self {
583 obfuscated_key,
584 layers,
585 }
586 }
587 pub fn hide(&self, input: &str) -> Result<Vec<u8>, RustcryptError> {
588 let key_bytes = self.obfuscated_key.reconstruct()?;
589 let key = SecretVec::new(key_bytes);
590 hide_layered(input.as_bytes(), &key, self.layers)
591 }
592 pub fn hide_bytes(&self, input: &[u8]) -> Result<Vec<u8>, RustcryptError> {
593 let key_bytes = self.obfuscated_key.reconstruct()?;
594 let key = SecretVec::new(key_bytes);
595 hide_layered(input, &key, self.layers)
596 }
597 pub fn reveal(&self, input: &[u8]) -> Result<String, RustcryptError> {
598 let key_bytes = self.obfuscated_key.reconstruct()?;
599 let key = SecretVec::new(key_bytes);
600 let out = reveal_layered(input, &key, self.layers)?;
601 String::from_utf8(out.to_vec()).map_err(|_| RustcryptError::MalformedInput)
602 }
603 pub fn reveal_bytes(&self, input: &[u8]) -> Result<Zeroizing<Vec<u8>>, RustcryptError> {
604 let key_bytes = self.obfuscated_key.reconstruct()?;
605 let key = SecretVec::new(key_bytes);
606 reveal_layered(input, &key, self.layers)
607 }
608 pub fn key_fragments(&self) -> &HashMap<usize, u8> {
609 self.obfuscated_key.fragments()
610 }
611 pub fn layers(&self) -> EncryptionLayers {
612 self.layers
613 }
614}
615
616impl Drop for ObfuscatedRustcrypt {
617 fn drop(&mut self) {}
618}
619
620pub use secrecy::SecretVec as SecretVecAlias;
621
622use aes_gcm::Key;
623
624pub const DEFAULT_KEY: [u8; 32] = [
625 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
626 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
627 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
628 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
629];
630
631pub fn encrypt_string(input: &str, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
632 let cipher = Aes256Gcm::new(Key::<aes_gcm::aes::Aes256>::from_slice(key));
633 let nonce_bytes = gen_nonce();
634 let nonce = Nonce::from_slice(&nonce_bytes);
635
636 let encrypted = cipher.encrypt(nonce, input.as_bytes())
637 .expect("Encryption should not fail");
638
639 (encrypted, nonce_bytes)
640}
641
642pub fn decrypt_string(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> String {
643 let cipher = Aes256Gcm::new(Key::<aes_gcm::aes::Aes256>::from_slice(key));
644 let nonce = Nonce::from_slice(nonce);
645
646 let decrypted = cipher.decrypt(nonce, encrypted)
647 .expect("Decryption should not fail");
648
649 String::from_utf8(decrypted)
650 .expect("Decrypted data should be valid UTF-8")
651}
652
653pub fn encrypt_u32(input: u32, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
654 encrypt_string(&input.to_string(), key)
655}
656
657pub fn decrypt_u32(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> u32 {
658 let decrypted = decrypt_string(encrypted, nonce, key);
659 decrypted.parse().expect("Should be valid u32")
660}
661
662pub fn encrypt_u64(input: u64, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
663 encrypt_string(&input.to_string(), key)
664}
665
666pub fn decrypt_u64(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> u64 {
667 let decrypted = decrypt_string(encrypted, nonce, key);
668 decrypted.parse().expect("Should be valid u64")
669}
670
671pub fn encrypt_i32(input: i32, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
672 encrypt_string(&input.to_string(), key)
673}
674
675pub fn decrypt_i32(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> i32 {
676 let decrypted = decrypt_string(encrypted, nonce, key);
677 decrypted.parse().expect("Should be valid i32")
678}
679
680pub fn encrypt_i64(input: i64, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
681 encrypt_string(&input.to_string(), key)
682}
683
684pub fn decrypt_i64(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> i64 {
685 let decrypted = decrypt_string(encrypted, nonce, key);
686 decrypted.parse().expect("Should be valid i64")
687}
688
689pub fn encrypt_bool(input: bool, key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
690 encrypt_string(&input.to_string(), key)
691}
692
693pub fn decrypt_bool(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> bool {
694 let decrypted = decrypt_string(encrypted, nonce, key);
695 decrypted.parse().expect("Should be valid bool")
696}
697
698pub fn encrypt_bytes(input: &[u8], key: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
699 let cipher = Aes256Gcm::new(Key::<aes_gcm::aes::Aes256>::from_slice(key));
700 let nonce_bytes = gen_nonce();
701 let nonce = Nonce::from_slice(&nonce_bytes);
702
703 let encrypted = cipher.encrypt(nonce, input)
704 .expect("Encryption should not fail");
705
706 (encrypted, nonce_bytes)
707}
708
709pub fn decrypt_bytes(encrypted: &[u8], nonce: &[u8; 12], key: &[u8; 32]) -> Vec<u8> {
710 let cipher = Aes256Gcm::new(Key::<aes_gcm::aes::Aes256>::from_slice(key));
711 let nonce = Nonce::from_slice(nonce);
712
713 cipher.decrypt(nonce, encrypted)
714 .expect("Decryption should not fail")
715}