dcrypt_algorithms/block/aes/
mod.rs1use super::BlockCipher;
18use super::CipherAlgorithm;
19use crate::error::{validate, Result};
20use crate::types::SecretBytes;
21use dcrypt_common::security::SecretBuffer;
22use dcrypt_params::utils::symmetric::{
23 AES128_KEY_SIZE, AES192_KEY_SIZE, AES256_KEY_SIZE, AES_BLOCK_SIZE,
24};
25#[cfg(not(feature = "std"))]
26use portable_atomic::{compiler_fence, Ordering};
27use rand::{CryptoRng, RngCore};
28#[cfg(feature = "std")]
29use std::sync::atomic::{compiler_fence, Ordering};
30use zeroize::{Zeroize, ZeroizeOnDrop};
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 = u32_to_bytes(word);
129 let sub_bytes = [
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, Zeroize, ZeroizeOnDrop)]
176pub struct Aes128 {
177 round_keys: SecretBuffer<176>, }
179
180#[derive(Clone, Zeroize, ZeroizeOnDrop)]
182pub struct Aes192 {
183 round_keys: SecretBuffer<208>, }
185
186#[derive(Clone, Zeroize, ZeroizeOnDrop)]
188pub struct Aes256 {
189 round_keys: SecretBuffer<240>, }
191
192impl CipherAlgorithm for Aes128 {
194 const KEY_SIZE: usize = AES128_KEY_SIZE;
195 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
196
197 fn name() -> &'static str {
198 "AES-128"
199 }
200}
201
202impl CipherAlgorithm for Aes192 {
203 const KEY_SIZE: usize = AES192_KEY_SIZE;
204 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
205
206 fn name() -> &'static str {
207 "AES-192"
208 }
209}
210
211impl CipherAlgorithm for Aes256 {
212 const KEY_SIZE: usize = AES256_KEY_SIZE;
213 const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
214
215 fn name() -> &'static str {
216 "AES-256"
217 }
218}
219
220impl Aes128 {
221 fn expand_key(key: &[u8]) -> Result<SecretBuffer<176>> {
223 validate::length("AES-128 key", key.len(), AES128_KEY_SIZE)?;
224
225 let mut round_keys_u32 = [0u32; 44];
226
227 for i in 0..4 {
229 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
230 }
231
232 for i in 4..44 {
234 let mut temp = round_keys_u32[i - 1];
235 if i % 4 == 0 {
236 temp = sub_word(rotate_word(temp)) ^ RCON[i / 4];
237 }
238 round_keys_u32[i] = round_keys_u32[i - 4] ^ temp;
239 }
240
241 let mut round_key_bytes = [0u8; 176];
243 for i in 0..44 {
244 let bytes = u32_to_bytes(round_keys_u32[i]);
245 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes);
246 }
247
248 Ok(SecretBuffer::new(round_key_bytes))
249 }
250
251 fn sub_bytes(state: &mut [u8; 16]) {
253 for byte in state.iter_mut() {
254 *byte = bitsliced_sbox(*byte);
255 }
256 compiler_fence(Ordering::SeqCst);
258 }
259
260 fn shift_rows(state: &mut [u8; 16]) {
262 let mut temp = [0u8; 16];
263 temp.copy_from_slice(state);
264 state[0] = temp[0];
265 state[4] = temp[4];
266 state[8] = temp[8];
267 state[12] = temp[12];
268 state[1] = temp[5];
269 state[5] = temp[9];
270 state[9] = temp[13];
271 state[13] = temp[1];
272 state[2] = temp[10];
273 state[6] = temp[14];
274 state[10] = temp[2];
275 state[14] = temp[6];
276 state[3] = temp[15];
277 state[7] = temp[3];
278 state[11] = temp[7];
279 state[15] = temp[11];
280 }
281
282 #[inline(always)]
284 fn mul2(byte: u8) -> u8 {
285 let high = byte >> 7;
286 (byte << 1) ^ (high * 0x1B)
287 }
288
289 fn mix_columns(state: &mut [u8; 16]) {
291 for c in 0..4 {
292 let i = c * 4;
293 let s0 = state[i];
294 let s1 = state[i + 1];
295 let s2 = state[i + 2];
296 let s3 = state[i + 3];
297 state[i] = Self::mul2(s0) ^ Self::mul2(s1) ^ s1 ^ s2 ^ s3;
298 state[i + 1] = s0 ^ Self::mul2(s1) ^ Self::mul2(s2) ^ s2 ^ s3;
299 state[i + 2] = s0 ^ s1 ^ Self::mul2(s2) ^ Self::mul2(s3) ^ s3;
300 state[i + 3] = Self::mul2(s0) ^ s0 ^ s1 ^ s2 ^ Self::mul2(s3);
301 }
302 }
303
304 fn add_round_key(state: &mut [u8; 16], round_key_bytes: &[u8]) -> Result<()> {
306 validate::min_length("AES round key", round_key_bytes.len(), 16)?;
308
309 for i in 0..16 {
310 state[i] ^= round_key_bytes[i];
311 }
312 Ok(())
313 }
314
315 fn inv_sub_bytes(state: &mut [u8; 16]) {
317 for byte in state.iter_mut() {
318 *byte = bitsliced_inv_sbox(*byte);
319 }
320 compiler_fence(Ordering::SeqCst);
321 }
322
323 fn inv_shift_rows(state: &mut [u8; 16]) {
325 let mut temp = [0u8; 16];
326 temp.copy_from_slice(state);
327 state[0] = temp[0];
328 state[4] = temp[4];
329 state[8] = temp[8];
330 state[12] = temp[12];
331 state[1] = temp[13];
332 state[5] = temp[1];
333 state[9] = temp[5];
334 state[13] = temp[9];
335 state[2] = temp[10];
336 state[6] = temp[14];
337 state[10] = temp[2];
338 state[14] = temp[6];
339 state[3] = temp[7];
340 state[7] = temp[11];
341 state[11] = temp[15];
342 state[15] = temp[3];
343 }
344
345 #[inline(always)]
347 fn mul14(byte: u8) -> u8 {
348 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(Self::mul2(byte)) ^ Self::mul2(byte)
349 }
350 #[inline(always)]
351 fn mul13(byte: u8) -> u8 {
352 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(Self::mul2(byte)) ^ byte
353 }
354 #[inline(always)]
355 fn mul11(byte: u8) -> u8 {
356 Self::mul2(Self::mul2(Self::mul2(byte))) ^ Self::mul2(byte) ^ byte
357 }
358 #[inline(always)]
359 fn mul9(byte: u8) -> u8 {
360 Self::mul2(Self::mul2(Self::mul2(byte))) ^ byte
361 }
362
363 fn inv_mix_columns(state: &mut [u8; 16]) {
365 for c in 0..4 {
366 let i = c * 4;
367 let s0 = state[i];
368 let s1 = state[i + 1];
369 let s2 = state[i + 2];
370 let s3 = state[i + 3];
371 state[i] = Self::mul14(s0) ^ Self::mul11(s1) ^ Self::mul13(s2) ^ Self::mul9(s3);
372 state[i + 1] = Self::mul9(s0) ^ Self::mul14(s1) ^ Self::mul11(s2) ^ Self::mul13(s3);
373 state[i + 2] = Self::mul13(s0) ^ Self::mul9(s1) ^ Self::mul14(s2) ^ Self::mul11(s3);
374 state[i + 3] = Self::mul11(s0) ^ Self::mul13(s1) ^ Self::mul9(s2) ^ Self::mul14(s3);
375 }
376 }
377}
378
379impl BlockCipher for Aes128 {
380 type Algorithm = Aes128Algorithm;
381 type Key = SecretBytes<16>;
382
383 fn new(key: &Self::Key) -> Self {
384 let round_keys =
385 Self::expand_key(key.as_ref()).expect("AES-128 key expansion should not fail");
386
387 Aes128 { round_keys }
388 }
389
390 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
391 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
393
394 let round_key_bytes = self.round_keys.as_ref();
396
397 let mut _warm: u8 = 0;
399 for &b in round_key_bytes {
400 _warm = _warm.wrapping_add(b);
401 }
402 compiler_fence(Ordering::SeqCst);
403
404 let mut state = [0u8; 16];
406 state.copy_from_slice(block);
407
408 Self::add_round_key(&mut state, &round_key_bytes[0..16])?;
410
411 for round in 1..10 {
413 Self::sub_bytes(&mut state);
414 Self::shift_rows(&mut state);
415 Self::mix_columns(&mut state);
416
417 let offset = round * 16;
418 Self::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
419 }
420
421 Self::sub_bytes(&mut state);
423 Self::shift_rows(&mut state);
424 Self::add_round_key(&mut state, &round_key_bytes[160..176])?;
425
426 block.copy_from_slice(&state);
428 Ok(())
429 }
430
431 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
432 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
434
435 let round_key_bytes = self.round_keys.as_ref();
437
438 let mut _warm: u8 = 0;
440 for &b in round_key_bytes {
441 _warm = _warm.wrapping_add(b);
442 }
443 compiler_fence(Ordering::SeqCst);
444
445 let mut state = [0u8; 16];
447 state.copy_from_slice(block);
448
449 Self::add_round_key(&mut state, &round_key_bytes[160..176])?;
451
452 for round in (1..10).rev() {
454 Self::inv_shift_rows(&mut state);
455 Self::inv_sub_bytes(&mut state);
456
457 let offset = round * 16;
458 Self::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
459 Self::inv_mix_columns(&mut state);
460 }
461
462 Self::inv_shift_rows(&mut state);
464 Self::inv_sub_bytes(&mut state);
465 Self::add_round_key(&mut state, &round_key_bytes[0..16])?;
466
467 block.copy_from_slice(&state);
469 Ok(())
470 }
471
472 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Key {
473 let mut key_data = [0u8; AES128_KEY_SIZE];
474 rng.fill_bytes(&mut key_data);
475 SecretBytes::new(key_data)
476 }
477}
478
479impl Aes192 {
482 fn expand_key(key: &[u8]) -> Result<SecretBuffer<208>> {
484 validate::length("AES-192 key", key.len(), AES192_KEY_SIZE)?;
485
486 let mut round_keys_u32 = [0u32; 52];
487
488 for i in 0..6 {
490 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
491 }
492
493 for i in 6..52 {
495 let mut temp = round_keys_u32[i - 1];
496 if i % 6 == 0 {
497 temp = sub_word(rotate_word(temp)) ^ RCON[i / 6];
498 }
499 round_keys_u32[i] = round_keys_u32[i - 6] ^ temp;
500 }
501
502 let mut round_key_bytes = [0u8; 208];
504 for i in 0..52 {
505 let bytes = u32_to_bytes(round_keys_u32[i]);
506 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes);
507 }
508
509 Ok(SecretBuffer::new(round_key_bytes))
510 }
511}
512
513impl BlockCipher for Aes192 {
514 type Algorithm = Aes192Algorithm;
515 type Key = SecretBytes<24>;
516
517 fn new(key: &Self::Key) -> Self {
518 let round_keys =
519 Self::expand_key(key.as_ref()).expect("AES-192 key expansion should not fail");
520
521 Aes192 { round_keys }
522 }
523
524 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
525 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
527
528 let round_key_bytes = self.round_keys.as_ref();
530
531 let mut _warm: u8 = 0;
533 for &b in round_key_bytes {
534 _warm = _warm.wrapping_add(b);
535 }
536 compiler_fence(Ordering::SeqCst);
537
538 let mut state = [0u8; 16];
540 state.copy_from_slice(block);
541
542 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
544
545 for round in 1..12 {
547 Aes128::sub_bytes(&mut state);
548 Aes128::shift_rows(&mut state);
549 Aes128::mix_columns(&mut state);
550
551 let offset = round * 16;
552 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
553 }
554
555 Aes128::sub_bytes(&mut state);
557 Aes128::shift_rows(&mut state);
558 Aes128::add_round_key(&mut state, &round_key_bytes[192..208])?;
559
560 block.copy_from_slice(&state);
562 Ok(())
563 }
564
565 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
566 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
568
569 let round_key_bytes = self.round_keys.as_ref();
571
572 let mut _warm: u8 = 0;
574 for &b in round_key_bytes {
575 _warm = _warm.wrapping_add(b);
576 }
577 compiler_fence(Ordering::SeqCst);
578
579 let mut state = [0u8; 16];
581 state.copy_from_slice(block);
582
583 Aes128::add_round_key(&mut state, &round_key_bytes[192..208])?;
585
586 for round in (1..12).rev() {
588 Aes128::inv_shift_rows(&mut state);
589 Aes128::inv_sub_bytes(&mut state);
590
591 let offset = round * 16;
592 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
593 Aes128::inv_mix_columns(&mut state);
594 }
595
596 Aes128::inv_shift_rows(&mut state);
598 Aes128::inv_sub_bytes(&mut state);
599 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
600
601 block.copy_from_slice(&state);
603 Ok(())
604 }
605
606 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Key {
607 let mut key_data = [0u8; AES192_KEY_SIZE];
608 rng.fill_bytes(&mut key_data);
609 SecretBytes::new(key_data)
610 }
611}
612
613impl Aes256 {
616 fn expand_key(key: &[u8]) -> Result<SecretBuffer<240>> {
618 validate::length("AES-256 key", key.len(), AES256_KEY_SIZE)?;
619
620 let mut round_keys_u32 = [0u32; 60];
621
622 for i in 0..8 {
624 round_keys_u32[i] = bytes_to_u32(&key[i * 4..(i + 1) * 4]);
625 }
626
627 for i in 8..60 {
629 let mut temp = round_keys_u32[i - 1];
630 if i % 8 == 0 {
631 temp = sub_word(rotate_word(temp)) ^ RCON[i / 8];
632 } else if i % 8 == 4 {
633 temp = sub_word(temp);
634 }
635 round_keys_u32[i] = round_keys_u32[i - 8] ^ temp;
636 }
637
638 let mut round_key_bytes = [0u8; 240];
640 for i in 0..60 {
641 let bytes = u32_to_bytes(round_keys_u32[i]);
642 round_key_bytes[i * 4..(i + 1) * 4].copy_from_slice(&bytes);
643 }
644
645 Ok(SecretBuffer::new(round_key_bytes))
646 }
647}
648
649impl BlockCipher for Aes256 {
650 type Algorithm = Aes256Algorithm;
651 type Key = SecretBytes<32>;
652
653 fn new(key: &Self::Key) -> Self {
654 let round_keys =
655 Self::expand_key(key.as_ref()).expect("AES-256 key expansion should not fail");
656
657 Aes256 { round_keys }
658 }
659
660 fn encrypt_block(&self, block: &mut [u8]) -> Result<()> {
661 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
663
664 let round_key_bytes = self.round_keys.as_ref();
666
667 let mut _warm: u8 = 0;
669 for &b in round_key_bytes {
670 _warm = _warm.wrapping_add(b);
671 }
672 compiler_fence(Ordering::SeqCst);
673
674 let mut state = [0u8; 16];
676 state.copy_from_slice(block);
677
678 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
680
681 for round in 1..14 {
683 Aes128::sub_bytes(&mut state);
684 Aes128::shift_rows(&mut state);
685 Aes128::mix_columns(&mut state);
686
687 let offset = round * 16;
688 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
689 }
690
691 Aes128::sub_bytes(&mut state);
693 Aes128::shift_rows(&mut state);
694 Aes128::add_round_key(&mut state, &round_key_bytes[224..240])?;
695
696 block.copy_from_slice(&state);
698 Ok(())
699 }
700
701 fn decrypt_block(&self, block: &mut [u8]) -> Result<()> {
702 validate::length("AES block", block.len(), AES_BLOCK_SIZE)?;
704
705 let round_key_bytes = self.round_keys.as_ref();
707
708 let mut _warm: u8 = 0;
710 for &b in round_key_bytes {
711 _warm = _warm.wrapping_add(b);
712 }
713 compiler_fence(Ordering::SeqCst);
714
715 let mut state = [0u8; 16];
717 state.copy_from_slice(block);
718
719 Aes128::add_round_key(&mut state, &round_key_bytes[224..240])?;
721
722 for round in (1..14).rev() {
724 Aes128::inv_shift_rows(&mut state);
725 Aes128::inv_sub_bytes(&mut state);
726
727 let offset = round * 16;
728 Aes128::add_round_key(&mut state, &round_key_bytes[offset..offset + 16])?;
729 Aes128::inv_mix_columns(&mut state);
730 }
731
732 Aes128::inv_shift_rows(&mut state);
734 Aes128::inv_sub_bytes(&mut state);
735 Aes128::add_round_key(&mut state, &round_key_bytes[0..16])?;
736
737 block.copy_from_slice(&state);
739 Ok(())
740 }
741
742 fn generate_key<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Key {
743 let mut key_data = [0u8; AES256_KEY_SIZE];
744 rng.fill_bytes(&mut key_data);
745 SecretBytes::new(key_data)
746 }
747}
748
749#[cfg(test)]
750mod tests;