dcrypt_algorithms/block/aes/
mod.rs1use super::BlockCipher;
21use super::CipherAlgorithm;
22use crate::error::{validate, Result};
23use crate::types::SecretBytes;
24use core::sync::atomic::{compiler_fence, Ordering};
25use dcrypt_common::security::SecretBuffer;
26use dcrypt_internal::random::{try_fill_bytes_zeroing_on_error, CryptoRng, RngCore};
27use dcrypt_internal::zeroing::{Zeroize, ZeroizeOnDrop, Zeroizing};
28use dcrypt_params::utils::symmetric::{
29 AES128_KEY_SIZE, AES192_KEY_SIZE, AES256_KEY_SIZE, AES_BLOCK_SIZE,
30};
31
32const RCON: [u32; 11] = [
34 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000,
35 0x80000000, 0x1b000000, 0x36000000,
36];
37
38#[inline(always)]
40fn gf_mul(a: u8, b: u8) -> u8 {
41 let mut p = 0u8;
42 let mut a = a;
43 let mut b = b;
44 for _ in 0..8 {
45 let mask = (b & 1).wrapping_neg();
47 p ^= a & mask;
48 let hi = a & 0x80;
49 a <<= 1;
50 a ^= ((hi != 0) as u8) * 0x1B;
52 b >>= 1;
53 }
54 p
55}
56
57#[inline(always)]
59fn gf_inv(x: u8) -> u8 {
60 let x2 = gf_mul(x, x);
62 let x4 = gf_mul(x2, x2);
63 let x8 = gf_mul(x4, x4);
64 let x16 = gf_mul(x8, x8);
65 let x32 = gf_mul(x16, x16);
66 let x64 = gf_mul(x32, x32);
67 let x128 = gf_mul(x64, x64);
68 let mut y = gf_mul(x128, x64);
70 y = gf_mul(y, x32);
71 y = gf_mul(y, x16);
72 y = gf_mul(y, x8);
73 y = gf_mul(y, x4);
74 y = gf_mul(y, x2);
75
76 let mask = ((x != 0) as u8).wrapping_neg();
79 y & mask
80}
81
82#[inline(always)]
84fn bitsliced_sbox(x: u8) -> u8 {
85 let i = gf_inv(x);
86 i ^ i.rotate_left(1) ^ i.rotate_left(2) ^ i.rotate_left(3) ^ i.rotate_left(4) ^ 0x63
87}
88
89#[inline(always)]
91fn bitsliced_inv_sbox(x: u8) -> u8 {
92 let y = x ^ 0x63;
94 let u = y.rotate_left(1) ^ y.rotate_left(3) ^ y.rotate_left(6);
96 gf_inv(u)
97}
98
99#[inline(always)]
101fn bytes_to_u32(bytes: &[u8]) -> u32 {
102 ((bytes[0] as u32) << 24)
103 | ((bytes[1] as u32) << 16)
104 | ((bytes[2] as u32) << 8)
105 | (bytes[3] as u32)
106}
107
108#[inline(always)]
110fn u32_to_bytes(word: u32) -> [u8; 4] {
111 [
112 (word >> 24) as u8,
113 (word >> 16) as u8,
114 (word >> 8) as u8,
115 word as u8,
116 ]
117}
118
119#[inline(always)]
121fn rotate_word(word: u32) -> u32 {
122 word.rotate_left(8)
123}
124
125#[inline(always)]
127fn sub_word(word: u32) -> u32 {
128 let bytes = Zeroizing::new(u32_to_bytes(word));
129 let sub_bytes = Zeroizing::new([
130 bitsliced_sbox(bytes[0]),
131 bitsliced_sbox(bytes[1]),
132 bitsliced_sbox(bytes[2]),
133 bitsliced_sbox(bytes[3]),
134 ]);
135 bytes_to_u32(&sub_bytes[..])
136}
137
138pub enum Aes128Algorithm {}
140
141impl CipherAlgorithm for Aes128Algorithm {
142 const KEY_SIZE: usize = AES128_KEY_SIZE;
143 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
144
145 fn name() -> &'static str {
146 "AES-128"
147 }
148}
149
150pub enum Aes192Algorithm {}
152
153impl CipherAlgorithm for Aes192Algorithm {
154 const KEY_SIZE: usize = AES192_KEY_SIZE;
155 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
156
157 fn name() -> &'static str {
158 "AES-192"
159 }
160}
161
162pub enum Aes256Algorithm {}
164
165impl CipherAlgorithm for Aes256Algorithm {
166 const KEY_SIZE: usize = AES256_KEY_SIZE;
167 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
168
169 fn name() -> &'static str {
170 "AES-256"
171 }
172}
173
174#[derive(Clone)]
176pub struct Aes128 {
177 round_keys: SecretBuffer<176>, }
179
180#[derive(Clone)]
182pub struct Aes192 {
183 round_keys: SecretBuffer<208>, }
185
186#[derive(Clone)]
188pub struct Aes256 {
189 round_keys: SecretBuffer<240>, }
191
192macro_rules! impl_aes_zeroize {
193 ($name:ident) => {
194 impl Zeroize for $name {
195 fn zeroize(&mut self) {
196 self.round_keys.zeroize();
197 }
198 }
199
200 impl Drop for $name {
201 fn drop(&mut self) {
202 self.zeroize();
203 }
204 }
205
206 impl ZeroizeOnDrop for $name {}
207 };
208}
209
210impl_aes_zeroize!(Aes128);
211impl_aes_zeroize!(Aes192);
212impl_aes_zeroize!(Aes256);
213
214impl CipherAlgorithm for Aes128 {
216 const KEY_SIZE: usize = AES128_KEY_SIZE;
217 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
218
219 fn name() -> &'static str {
220 "AES-128"
221 }
222}
223
224impl CipherAlgorithm for Aes192 {
225 const KEY_SIZE: usize = AES192_KEY_SIZE;
226 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
227
228 fn name() -> &'static str {
229 "AES-192"
230 }
231}
232
233impl CipherAlgorithm for Aes256 {
234 const KEY_SIZE: usize = AES256_KEY_SIZE;
235 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
236
237 fn name() -> &'static str {
238 "AES-256"
239 }
240}
241
242impl Aes128 {
243 fn expand_key(key: &[u8]) -> Result<SecretBuffer<176>> {
245 validate::length("AES-128 key", key.len(), AES128_KEY_SIZE)?;
246
247 let mut round_keys_u32 = Zeroizing::new([0u32; 44]);
248
249 for i in 0..4 {
251 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
252 }
253
254 for i in 4..44 {
256 let mut temp = Zeroizing::new(round_keys_u32[i - 1]);
257 if i % 4 == 0 {
258 *temp = sub_word(rotate_word(*temp)) ^ RCON[i / 4];
259 }
260 round_keys_u32[i] = round_keys_u32[i - 4] ^ *temp;
261 }
262
263 let mut round_key_bytes = Zeroizing::new([0u8; 176]);
265 for i in 0..44 {
266 let bytes = Zeroizing::new(u32_to_bytes(round_keys_u32[i]));
267 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes[..]);
268 }
269
270 Ok(SecretBuffer::new(*round_key_bytes))
271 }
272
273 fn sub_bytes(state: &mut [u8; 16]) {
275 for byte in state.iter_mut() {
276 *byte = bitsliced_sbox(*byte);
277 }
278 compiler_fence(Ordering::SeqCst);
280 }
281
282 fn shift_rows(state: &mut [u8; 16]) {
284 let mut temp = Zeroizing::new([0u8; 16]);
285 temp.copy_from_slice(state);
286 state[0] = temp[0];
287 state[4] = temp[4];
288 state[8] = temp[8];
289 state[12] = temp[12];
290 state[1] = temp[5];
291 state[5] = temp[9];
292 state[9] = temp[13];
293 state[13] = temp[1];
294 state[2] = temp[10];
295 state[6] = temp[14];
296 state[10] = temp[2];
297 state[14] = temp[6];
298 state[3] = temp[15];
299 state[7] = temp[3];
300 state[11] = temp[7];
301 state[15] = temp[11];
302 }
303
304 #[inline(always)]
306 fn mul2(byte: u8) -> u8 {
307 let high = byte >> 7;
308 (byte << 1) ^ (high * 0x1B)
309 }
310
311 fn mix_columns(state: &mut [u8; 16]) {
313 for c in 0..4 {
314 let i = c * 4;
315 let s0 = state[i];
316 let s1 = state[i + 1];
317 let s2 = state[i + 2];
318 let s3 = state[i + 3];
319 state[i] = Self::mul2(s0) ^ Self::mul2(s1) ^ s1 ^ s2 ^ s3;
320 state[i + 1] = s0 ^ Self::mul2(s1) ^ Self::mul2(s2) ^ s2 ^ s3;
321 state[i + 2] = s0 ^ s1 ^ Self::mul2(s2) ^ Self::mul2(s3) ^ s3;
322 state[i + 3] = Self::mul2(s0) ^ s0 ^ s1 ^ s2 ^ Self::mul2(s3);
323 }
324 }
325
326 fn add_round_key(state: &mut [u8; 16], round_key_bytes: &[u8]) -> Result<()> {
328 validate::min_length("AES round key", round_key_bytes.len(), 16)?;
330
331 for i in 0..16 {
332 state[i] ^= round_key_bytes[i];
333 }
334 Ok(())
335 }
336
337 fn inv_sub_bytes(state: &mut [u8; 16]) {
339 for byte in state.iter_mut() {
340 *byte = bitsliced_inv_sbox(*byte);
341 }
342 compiler_fence(Ordering::SeqCst);
343 }
344
345 fn inv_shift_rows(state: &mut [u8; 16]) {
347 let mut temp = Zeroizing::new([0u8; 16]);
348 temp.copy_from_slice(state);
349 state[0] = temp[0];
350 state[4] = temp[4];
351 state[8] = temp[8];
352 state[12] = temp[12];
353 state[1] = temp[13];
354 state[5] = temp[1];
355 state[9] = temp[5];
356 state[13] = temp[9];
357 state[2] = temp[10];
358 state[6] = temp[14];
359 state[10] = temp[2];
360 state[14] = temp[6];
361 state[3] = temp[7];
362 state[7] = temp[11];
363 state[11] = temp[15];
364 state[15] = temp[3];
365 }
366
367 #[inline(always)]
369 fn mul14(byte: u8) -> u8 {
370 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(Self::mul2(byte)) ^ Self::mul2(byte)
371 }
372 #[inline(always)]
373 fn mul13(byte: u8) -> u8 {
374 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(Self::mul2(byte)) ^ byte
375 }
376 #[inline(always)]
377 fn mul11(byte: u8) -> u8 {
378 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(byte) ^ byte
379 }
380 #[inline(always)]
381 fn mul9(byte: u8) -> u8 {
382 Self::mul2(Self::mul2(Self::mul2(byte))) ^ byte
383 }
384
385 fn inv_mix_columns(state: &mut [u8; 16]) {
387 for c in 0..4 {
388 let i = c * 4;
389 let s0 = state[i];
390 let s1 = state[i + 1];
391 let s2 = state[i + 2];
392 let s3 = state[i + 3];
393 state[i] = Self::mul14(s0) ^ Self::mul11(s1) ^ Self::mul13(s2) ^ Self::mul9(s3);
394 state[i + 1] = Self::mul9(s0) ^ Self::mul14(s1) ^ Self::mul11(s2) ^ Self::mul13(s3);
395 state[i + 2] = Self::mul13(s0) ^ Self::mul9(s1) ^ Self::mul14(s2) ^ Self::mul11(s3);
396 state[i + 3] = Self::mul11(s0) ^ Self::mul13(s1) ^ Self::mul9(s2) ^ Self::mul14(s3);
397 }
398 }
399}
400
401impl BlockCipher for Aes128 {
402 type Algorithm = Aes128Algorithm;
403 type Key = SecretBytes<16>;
404
405 fn new(key: &Self::Key) -> Self {
406 let round_keys =
407 Self::expand_key(key.as_ref()).expect("AES-128 key expansion should not fail");
408
409 Aes128 { round_keys }
410 }
411
412 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
413 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
415
416 let round_key_bytes = self.round_keys.as_ref();
418
419 let mut _warm: u8 = 0;
421 for &b in round_key_bytes {
422 _warm = _warm.wrapping_add(b);
423 }
424 compiler_fence(Ordering::SeqCst);
425
426 let mut state = Zeroizing::new([0u8; 16]);
428 state.copy_from_slice(block);
429
430 Self::add_round_key(&mut state, &round_key_bytes[0..16])?;
432
433 for round in 1..10 {
435 Self::sub_bytes(&mut state);
436 Self::shift_rows(&mut state);
437 Self::mix_columns(&mut state);
438
439 let offset = round * 16;
440 Self::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
441 }
442
443 Self::sub_bytes(&mut state);
445 Self::shift_rows(&mut state);
446 Self::add_round_key(&mut state, &round_key_bytes[160..176])?;
447
448 block.copy_from_slice(&state[..]);
450 Ok(())
451 }
452
453 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
454 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
456
457 let round_key_bytes = self.round_keys.as_ref();
459
460 let mut _warm: u8 = 0;
462 for &b in round_key_bytes {
463 _warm = _warm.wrapping_add(b);
464 }
465 compiler_fence(Ordering::SeqCst);
466
467 let mut state = Zeroizing::new([0u8; 16]);
469 state.copy_from_slice(block);
470
471 Self::add_round_key(&mut state, &round_key_bytes[160..176])?;
473
474 for round in (1..10).rev() {
476 Self::inv_shift_rows(&mut state);
477 Self::inv_sub_bytes(&mut state);
478
479 let offset = round * 16;
480 Self::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
481 Self::inv_mix_columns(&mut state);
482 }
483
484 Self::inv_shift_rows(&mut state);
486 Self::inv_sub_bytes(&mut state);
487 Self::add_round_key(&mut state, &round_key_bytes[0..16])?;
488
489 block.copy_from_slice(&state[..]);
491 Ok(())
492 }
493
494 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Result<Self::Key> {
495 let mut key_data = Zeroizing::new([0u8; AES128_KEY_SIZE]);
496 try_fill_bytes_zeroing_on_error(rng, &mut key_data[..])?;
497 Ok(SecretBytes::new(*key_data))
498 }
499}
500
501impl Aes192 {
504 fn expand_key(key: &[u8]) -> Result<SecretBuffer<208>> {
506 validate::length("AES-192 key", key.len(), AES192_KEY_SIZE)?;
507
508 let mut round_keys_u32 = Zeroizing::new([0u32; 52]);
509
510 for i in 0..6 {
512 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
513 }
514
515 for i in 6..52 {
517 let mut temp = Zeroizing::new(round_keys_u32[i - 1]);
518 if i % 6 == 0 {
519 *temp = sub_word(rotate_word(*temp)) ^ RCON[i / 6];
520 }
521 round_keys_u32[i] = round_keys_u32[i - 6] ^ *temp;
522 }
523
524 let mut round_key_bytes = Zeroizing::new([0u8; 208]);
526 for i in 0..52 {
527 let bytes = Zeroizing::new(u32_to_bytes(round_keys_u32[i]));
528 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes[..]);
529 }
530
531 Ok(SecretBuffer::new(*round_key_bytes))
532 }
533}
534
535impl BlockCipher for Aes192 {
536 type Algorithm = Aes192Algorithm;
537 type Key = SecretBytes<24>;
538
539 fn new(key: &Self::Key) -> Self {
540 let round_keys =
541 Self::expand_key(key.as_ref()).expect("AES-192 key expansion should not fail");
542
543 Aes192 { round_keys }
544 }
545
546 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
547 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
549
550 let round_key_bytes = self.round_keys.as_ref();
552
553 let mut _warm: u8 = 0;
555 for &b in round_key_bytes {
556 _warm = _warm.wrapping_add(b);
557 }
558 compiler_fence(Ordering::SeqCst);
559
560 let mut state = Zeroizing::new([0u8; 16]);
562 state.copy_from_slice(block);
563
564 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
566
567 for round in 1..12 {
569 Aes128::sub_bytes(&mut state);
570 Aes128::shift_rows(&mut state);
571 Aes128::mix_columns(&mut state);
572
573 let offset = round * 16;
574 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
575 }
576
577 Aes128::sub_bytes(&mut state);
579 Aes128::shift_rows(&mut state);
580 Aes128::add_round_key(&mut state, &round_key_bytes[192..208])?;
581
582 block.copy_from_slice(&state[..]);
584 Ok(())
585 }
586
587 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
588 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
590
591 let round_key_bytes = self.round_keys.as_ref();
593
594 let mut _warm: u8 = 0;
596 for &b in round_key_bytes {
597 _warm = _warm.wrapping_add(b);
598 }
599 compiler_fence(Ordering::SeqCst);
600
601 let mut state = Zeroizing::new([0u8; 16]);
603 state.copy_from_slice(block);
604
605 Aes128::add_round_key(&mut state, &round_key_bytes[192..208])?;
607
608 for round in (1..12).rev() {
610 Aes128::inv_shift_rows(&mut state);
611 Aes128::inv_sub_bytes(&mut state);
612
613 let offset = round * 16;
614 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
615 Aes128::inv_mix_columns(&mut state);
616 }
617
618 Aes128::inv_shift_rows(&mut state);
620 Aes128::inv_sub_bytes(&mut state);
621 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
622
623 block.copy_from_slice(&state[..]);
625 Ok(())
626 }
627
628 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Result<Self::Key> {
629 let mut key_data = Zeroizing::new([0u8; AES192_KEY_SIZE]);
630 try_fill_bytes_zeroing_on_error(rng, &mut key_data[..])?;
631 Ok(SecretBytes::new(*key_data))
632 }
633}
634
635impl Aes256 {
638 fn expand_key(key: &[u8]) -> Result<SecretBuffer<240>> {
640 validate::length("AES-256 key", key.len(), AES256_KEY_SIZE)?;
641
642 let mut round_keys_u32 = Zeroizing::new([0u32; 60]);
643
644 for i in 0..8 {
646 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
647 }
648
649 for i in 8..60 {
651 let mut temp = Zeroizing::new(round_keys_u32[i - 1]);
652 if i % 8 == 0 {
653 *temp = sub_word(rotate_word(*temp)) ^ RCON[i / 8];
654 } else if i % 8 == 4 {
655 *temp = sub_word(*temp);
656 }
657 round_keys_u32[i] = round_keys_u32[i - 8] ^ *temp;
658 }
659
660 let mut round_key_bytes = Zeroizing::new([0u8; 240]);
662 for i in 0..60 {
663 let bytes = Zeroizing::new(u32_to_bytes(round_keys_u32[i]));
664 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes[..]);
665 }
666
667 Ok(SecretBuffer::new(*round_key_bytes))
668 }
669}
670
671impl BlockCipher for Aes256 {
672 type Algorithm = Aes256Algorithm;
673 type Key = SecretBytes<32>;
674
675 fn new(key: &Self::Key) -> Self {
676 let round_keys =
677 Self::expand_key(key.as_ref()).expect("AES-256 key expansion should not fail");
678
679 Aes256 { round_keys }
680 }
681
682 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
683 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
685
686 let round_key_bytes = self.round_keys.as_ref();
688
689 let mut _warm: u8 = 0;
691 for &b in round_key_bytes {
692 _warm = _warm.wrapping_add(b);
693 }
694 compiler_fence(Ordering::SeqCst);
695
696 let mut state = Zeroizing::new([0u8; 16]);
698 state.copy_from_slice(block);
699
700 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
702
703 for round in 1..14 {
705 Aes128::sub_bytes(&mut state);
706 Aes128::shift_rows(&mut state);
707 Aes128::mix_columns(&mut state);
708
709 let offset = round * 16;
710 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
711 }
712
713 Aes128::sub_bytes(&mut state);
715 Aes128::shift_rows(&mut state);
716 Aes128::add_round_key(&mut state, &round_key_bytes[224..240])?;
717
718 block.copy_from_slice(&state[..]);
720 Ok(())
721 }
722
723 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
724 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
726
727 let round_key_bytes = self.round_keys.as_ref();
729
730 let mut _warm: u8 = 0;
732 for &b in round_key_bytes {
733 _warm = _warm.wrapping_add(b);
734 }
735 compiler_fence(Ordering::SeqCst);
736
737 let mut state = Zeroizing::new([0u8; 16]);
739 state.copy_from_slice(block);
740
741 Aes128::add_round_key(&mut state, &round_key_bytes[224..240])?;
743
744 for round in (1..14).rev() {
746 Aes128::inv_shift_rows(&mut state);
747 Aes128::inv_sub_bytes(&mut state);
748
749 let offset = round * 16;
750 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
751 Aes128::inv_mix_columns(&mut state);
752 }
753
754 Aes128::inv_shift_rows(&mut state);
756 Aes128::inv_sub_bytes(&mut state);
757 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
758
759 block.copy_from_slice(&state[..]);
761 Ok(())
762 }
763
764 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Result<Self::Key> {
765 let mut key_data = Zeroizing::new([0u8; AES256_KEY_SIZE]);
766 try_fill_bytes_zeroing_on_error(rng, &mut key_data[..])?;
767 Ok(SecretBytes::new(*key_data))
768 }
769}
770
771#[cfg(test)]
772mod tests;