1 use crate::arch::*; 2 use cipher::{ 3 consts::{U16, U24, U8}, 4 generic_array::GenericArray, 5 BlockCipher, NewBlockCipher, 6 }; 7 8 use crate::utils::{Block128, Block128x8}; 9 10 mod expand; 11 #[cfg(test)] 12 mod test_expand; 13 14 /// AES-192 block cipher 15 #[derive(Copy, Clone)] 16 pub struct Aes192 { 17 encrypt_keys: [__m128i; 13], 18 decrypt_keys: [__m128i; 13], 19 } 20 21 impl Aes192 { 22 #[inline(always)] encrypt8(&self, mut blocks: [__m128i; 8]) -> [__m128i; 8]23 pub(crate) fn encrypt8(&self, mut blocks: [__m128i; 8]) -> [__m128i; 8] { 24 #[inline] 25 #[target_feature(enable = "aes")] aesni192_encrypt8(keys: &[__m128i; 13], blocks: &mut [__m128i; 8])26 unsafe fn aesni192_encrypt8(keys: &[__m128i; 13], blocks: &mut [__m128i; 8]) { 27 xor8!(blocks, keys[0]); 28 aesenc8!(blocks, keys[1]); 29 aesenc8!(blocks, keys[2]); 30 aesenc8!(blocks, keys[3]); 31 aesenc8!(blocks, keys[4]); 32 aesenc8!(blocks, keys[5]); 33 aesenc8!(blocks, keys[6]); 34 aesenc8!(blocks, keys[7]); 35 aesenc8!(blocks, keys[8]); 36 aesenc8!(blocks, keys[9]); 37 aesenc8!(blocks, keys[10]); 38 aesenc8!(blocks, keys[11]); 39 aesenclast8!(blocks, keys[12]); 40 } 41 unsafe { aesni192_encrypt8(&self.encrypt_keys, &mut blocks) }; 42 blocks 43 } 44 45 #[inline(always)] encrypt(&self, block: __m128i) -> __m128i46 pub(crate) fn encrypt(&self, block: __m128i) -> __m128i { 47 #[inline] 48 #[target_feature(enable = "aes")] 49 unsafe fn aesni192_encrypt1(keys: &[__m128i; 13], mut block: __m128i) -> __m128i { 50 block = _mm_xor_si128(block, keys[0]); 51 block = _mm_aesenc_si128(block, keys[1]); 52 block = _mm_aesenc_si128(block, keys[2]); 53 block = _mm_aesenc_si128(block, keys[3]); 54 block = _mm_aesenc_si128(block, keys[4]); 55 block = _mm_aesenc_si128(block, keys[5]); 56 block = _mm_aesenc_si128(block, keys[6]); 57 block = _mm_aesenc_si128(block, keys[7]); 58 block = _mm_aesenc_si128(block, keys[8]); 59 block = _mm_aesenc_si128(block, keys[9]); 60 block = _mm_aesenc_si128(block, keys[10]); 61 block = _mm_aesenc_si128(block, keys[11]); 62 _mm_aesenclast_si128(block, keys[12]) 63 } 64 unsafe { aesni192_encrypt1(&self.encrypt_keys, block) } 65 } 66 } 67 68 impl NewBlockCipher for Aes192 { 69 type KeySize = U24; 70 71 #[inline] new(key: &GenericArray<u8, U24>) -> Self72 fn new(key: &GenericArray<u8, U24>) -> Self { 73 let key = unsafe { &*(key as *const _ as *const [u8; 24]) }; 74 let (encrypt_keys, decrypt_keys) = expand::expand(key); 75 Self { 76 encrypt_keys, 77 decrypt_keys, 78 } 79 } 80 } 81 82 impl BlockCipher for Aes192 { 83 type BlockSize = U16; 84 type ParBlocks = U8; 85 86 #[inline] encrypt_block(&self, block: &mut Block128)87 fn encrypt_block(&self, block: &mut Block128) { 88 // Safety: `loadu` and `storeu` support unaligned access 89 #[allow(clippy::cast_ptr_alignment)] 90 unsafe { 91 let b = _mm_loadu_si128(block.as_ptr() as *const __m128i); 92 let b = self.encrypt(b); 93 _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b); 94 } 95 } 96 97 #[inline] decrypt_block(&self, block: &mut Block128)98 fn decrypt_block(&self, block: &mut Block128) { 99 #[inline] 100 #[target_feature(enable = "aes")] 101 unsafe fn aes192_decrypt1(block: &mut Block128, keys: &[__m128i; 13]) { 102 // Safety: `loadu` and `storeu` support unaligned access 103 #[allow(clippy::cast_ptr_alignment)] 104 let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i); 105 b = _mm_xor_si128(b, keys[12]); 106 b = _mm_aesdec_si128(b, keys[11]); 107 b = _mm_aesdec_si128(b, keys[10]); 108 b = _mm_aesdec_si128(b, keys[9]); 109 b = _mm_aesdec_si128(b, keys[8]); 110 b = _mm_aesdec_si128(b, keys[7]); 111 b = _mm_aesdec_si128(b, keys[6]); 112 b = _mm_aesdec_si128(b, keys[5]); 113 b = _mm_aesdec_si128(b, keys[4]); 114 b = _mm_aesdec_si128(b, keys[3]); 115 b = _mm_aesdec_si128(b, keys[2]); 116 b = _mm_aesdec_si128(b, keys[1]); 117 b = _mm_aesdeclast_si128(b, keys[0]); 118 _mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b); 119 } 120 121 unsafe { aes192_decrypt1(block, &self.decrypt_keys) } 122 } 123 124 #[inline] encrypt_blocks(&self, blocks: &mut Block128x8)125 fn encrypt_blocks(&self, blocks: &mut Block128x8) { 126 unsafe { 127 let b = self.encrypt8(load8!(blocks)); 128 store8!(blocks, b); 129 } 130 } 131 132 #[inline] decrypt_blocks(&self, blocks: &mut Block128x8)133 fn decrypt_blocks(&self, blocks: &mut Block128x8) { 134 #[inline] 135 #[target_feature(enable = "aes")] 136 unsafe fn aes192_decrypt8(blocks: &mut Block128x8, keys: &[__m128i; 13]) { 137 let mut b = load8!(blocks); 138 xor8!(b, keys[12]); 139 aesdec8!(b, keys[11]); 140 aesdec8!(b, keys[10]); 141 aesdec8!(b, keys[9]); 142 aesdec8!(b, keys[8]); 143 aesdec8!(b, keys[7]); 144 aesdec8!(b, keys[6]); 145 aesdec8!(b, keys[5]); 146 aesdec8!(b, keys[4]); 147 aesdec8!(b, keys[3]); 148 aesdec8!(b, keys[2]); 149 aesdec8!(b, keys[1]); 150 aesdeclast8!(b, keys[0]); 151 store8!(blocks, b); 152 } 153 154 unsafe { aes192_decrypt8(blocks, &self.decrypt_keys) } 155 } 156 } 157 158 opaque_debug::implement!(Aes192); 159