1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
use core::mem::transmute; use super::u64x2; mod expand; #[derive(Copy, Clone, Debug)] pub struct Aes128 { encrypt_keys: [u64x2; 11], decrypt_keys: [u64x2; 11], } impl Aes128 { #[inline] pub fn new(key: &[u8; 16]) -> Self { let (encrypt_keys, decrypt_keys) = expand::expand(key); Aes128 { encrypt_keys: encrypt_keys, decrypt_keys: decrypt_keys } } #[inline] pub fn encrypt(&self, block: &mut [u8; 16]) { assert!((block.as_ptr() as usize) % 16 == 0, "unaligned input"); let keys = self.encrypt_keys; unsafe { let mut data: &mut u64x2 = transmute(block); asm!(include_str!("encrypt.asm") : "+{xmm0}"(*data) : "{xmm1}"(keys[0]), "{xmm2}"(keys[1]), "{xmm3}"(keys[2]), "{xmm4}"(keys[3]), "{xmm5}"(keys[4]), "{xmm6}"(keys[5]), "{xmm7}"(keys[6]), "{xmm8}"(keys[7]), "{xmm9}"(keys[8]), "{xmm10}"(keys[9]), "{xmm11}"(keys[10]) : : "intel", "alignstack" ); } } #[inline] pub fn decrypt(&self, block: &mut [u8; 16]) { assert!((block.as_ptr() as usize) % 16 == 0, "unaligned input"); let keys = self.decrypt_keys; unsafe { let mut data: &mut u64x2 = transmute(block); asm!(include_str!("decrypt.asm") : "+{xmm0}"(*data) : "{xmm1}"(keys[10]), "{xmm2}"(keys[9]), "{xmm3}"(keys[8]), "{xmm4}"(keys[7]), "{xmm5}"(keys[6]), "{xmm6}"(keys[5]), "{xmm7}"(keys[4]), "{xmm8}"(keys[3]), "{xmm9}"(keys[2]), "{xmm10}"(keys[1]), "{xmm11}"(keys[0]) : : "intel", "alignstack" ); } } #[inline] pub fn encrypt8(&self, blocks: &mut [u8; 8*16]) { assert!((blocks.as_ptr() as usize) % 16 == 0, "unaligned input"); let keys = self.encrypt_keys; unsafe { let mut data: &mut [u64x2; 8] = transmute(blocks); asm!(include_str!("encrypt8_1.asm") : "+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]), "+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]), "+{xmm6}"(data[6]), "+{xmm7}"(data[7]) : "{xmm8}"(keys[0]), "{xmm9}"(keys[1]), "{xmm10}"(keys[2]), "{xmm11}"(keys[3]), "{xmm12}"(keys[4]), "{xmm13}"(keys[5]), "{xmm14}"(keys[6]), "{xmm15}"(keys[7]) : : "intel", "alignstack" ); asm!(include_str!("encrypt8_2.asm") : "+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]), "+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]), "+{xmm6}"(data[6]), "+{xmm7}"(data[7]) : "{xmm13}"(keys[8]), "{xmm14}"(keys[9]), "{xmm15}"(keys[10]) : : "intel", "alignstack" ); } } #[inline] pub fn decrypt8(&self, blocks: &mut [u8; 8*16]) { assert!((blocks.as_ptr() as usize) % 16 == 0, "unaligned input"); let keys = self.decrypt_keys; unsafe { let mut data: &mut [u64x2; 8] = transmute(blocks); asm!(include_str!("decrypt8_1.asm") : "+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]), "+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]), "+{xmm6}"(data[6]), "+{xmm7}"(data[7]) : "{xmm8}"(keys[10]), "{xmm9}"(keys[9]), "{xmm10}"(keys[8]), "{xmm11}"(keys[7]), "{xmm12}"(keys[6]), "{xmm13}"(keys[5]), "{xmm14}"(keys[4]), "{xmm15}"(keys[3]) : : "intel", "alignstack" ); asm!(include_str!("decrypt8_2.asm") : "+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]), "+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]), "+{xmm6}"(data[6]), "+{xmm7}"(data[7]) : "{xmm13}"(keys[2]), "{xmm14}"(keys[1]), "{xmm15}"(keys[0]) : : "intel", "alignstack" ); } } } #[cfg(test)] mod test_expand;