/rust/registry/src/index.crates.io-6f17d22bba15001f/aes-0.8.4/src/ni/aes192.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use super::{arch::*, utils::*}; |
2 | | use crate::{Block, Block8}; |
3 | | use cipher::inout::InOut; |
4 | | use core::{mem, ptr}; |
5 | | |
6 | | /// AES-192 round keys |
7 | | pub(super) type RoundKeys = [__m128i; 13]; |
8 | | |
9 | | #[inline] |
10 | | #[target_feature(enable = "aes")] |
11 | 0 | pub(super) unsafe fn encrypt1(keys: &RoundKeys, block: InOut<'_, '_, Block>) { |
12 | 0 | let (in_ptr, out_ptr) = block.into_raw(); |
13 | 0 | let mut b = _mm_loadu_si128(in_ptr as *const __m128i); |
14 | 0 | b = _mm_xor_si128(b, keys[0]); |
15 | 0 | b = _mm_aesenc_si128(b, keys[1]); |
16 | 0 | b = _mm_aesenc_si128(b, keys[2]); |
17 | 0 | b = _mm_aesenc_si128(b, keys[3]); |
18 | 0 | b = _mm_aesenc_si128(b, keys[4]); |
19 | 0 | b = _mm_aesenc_si128(b, keys[5]); |
20 | 0 | b = _mm_aesenc_si128(b, keys[6]); |
21 | 0 | b = _mm_aesenc_si128(b, keys[7]); |
22 | 0 | b = _mm_aesenc_si128(b, keys[8]); |
23 | 0 | b = _mm_aesenc_si128(b, keys[9]); |
24 | 0 | b = _mm_aesenc_si128(b, keys[10]); |
25 | 0 | b = _mm_aesenc_si128(b, keys[11]); |
26 | 0 | b = _mm_aesenclast_si128(b, keys[12]); |
27 | 0 | _mm_storeu_si128(out_ptr as *mut __m128i, b); |
28 | 0 | } |
29 | | |
30 | | #[inline] |
31 | | #[target_feature(enable = "aes")] |
32 | 0 | pub(super) unsafe fn encrypt8(keys: &RoundKeys, blocks: InOut<'_, '_, Block8>) { |
33 | 0 | let (in_ptr, out_ptr) = blocks.into_raw(); |
34 | 0 | let mut b = load8(in_ptr); |
35 | 0 | xor8(&mut b, keys[0]); |
36 | 0 | aesenc8(&mut b, keys[1]); |
37 | 0 | aesenc8(&mut b, keys[2]); |
38 | 0 | aesenc8(&mut b, keys[3]); |
39 | 0 | aesenc8(&mut b, keys[4]); |
40 | 0 | aesenc8(&mut b, keys[5]); |
41 | 0 | aesenc8(&mut b, keys[6]); |
42 | 0 | aesenc8(&mut b, keys[7]); |
43 | 0 | aesenc8(&mut b, keys[8]); |
44 | 0 | aesenc8(&mut b, keys[9]); |
45 | 0 | aesenc8(&mut b, keys[10]); |
46 | 0 | aesenc8(&mut b, keys[11]); |
47 | 0 | aesenclast8(&mut b, keys[12]); |
48 | 0 | store8(out_ptr, b); |
49 | 0 | } |
50 | | |
51 | | #[inline] |
52 | | #[target_feature(enable = "aes")] |
53 | 0 | pub(super) unsafe fn decrypt1(keys: &RoundKeys, block: InOut<'_, '_, Block>) { |
54 | 0 | let (in_ptr, out_ptr) = block.into_raw(); |
55 | 0 | let mut b = _mm_loadu_si128(in_ptr as *const __m128i); |
56 | 0 | b = _mm_xor_si128(b, keys[12]); |
57 | 0 | b = _mm_aesdec_si128(b, keys[11]); |
58 | 0 | b = _mm_aesdec_si128(b, keys[10]); |
59 | 0 | b = _mm_aesdec_si128(b, keys[9]); |
60 | 0 | b = _mm_aesdec_si128(b, keys[8]); |
61 | 0 | b = _mm_aesdec_si128(b, keys[7]); |
62 | 0 | b = _mm_aesdec_si128(b, keys[6]); |
63 | 0 | b = _mm_aesdec_si128(b, keys[5]); |
64 | 0 | b = _mm_aesdec_si128(b, keys[4]); |
65 | 0 | b = _mm_aesdec_si128(b, keys[3]); |
66 | 0 | b = _mm_aesdec_si128(b, keys[2]); |
67 | 0 | b = _mm_aesdec_si128(b, keys[1]); |
68 | 0 | b = _mm_aesdeclast_si128(b, keys[0]); |
69 | 0 | _mm_storeu_si128(out_ptr as *mut __m128i, b); |
70 | 0 | } |
71 | | |
72 | | #[inline] |
73 | | #[target_feature(enable = "aes")] |
74 | 0 | pub(super) unsafe fn decrypt8(keys: &RoundKeys, blocks: InOut<'_, '_, Block8>) { |
75 | 0 | let (in_ptr, out_ptr) = blocks.into_raw(); |
76 | 0 | let mut b = load8(in_ptr); |
77 | 0 | xor8(&mut b, keys[12]); |
78 | 0 | aesdec8(&mut b, keys[11]); |
79 | 0 | aesdec8(&mut b, keys[10]); |
80 | 0 | aesdec8(&mut b, keys[9]); |
81 | 0 | aesdec8(&mut b, keys[8]); |
82 | 0 | aesdec8(&mut b, keys[7]); |
83 | 0 | aesdec8(&mut b, keys[6]); |
84 | 0 | aesdec8(&mut b, keys[5]); |
85 | 0 | aesdec8(&mut b, keys[4]); |
86 | 0 | aesdec8(&mut b, keys[3]); |
87 | 0 | aesdec8(&mut b, keys[2]); |
88 | 0 | aesdec8(&mut b, keys[1]); |
89 | 0 | aesdeclast8(&mut b, keys[0]); |
90 | 0 | store8(out_ptr, b); |
91 | 0 | } |
92 | | |
93 | | macro_rules! expand_round { |
94 | | ($t1:expr, $t3:expr, $round:expr) => {{ |
95 | | let mut t1 = $t1; |
96 | | let mut t2; |
97 | | let mut t3 = $t3; |
98 | | let mut t4; |
99 | | |
100 | | t2 = _mm_aeskeygenassist_si128(t3, $round); |
101 | | t2 = _mm_shuffle_epi32(t2, 0x55); |
102 | | t4 = _mm_slli_si128(t1, 0x4); |
103 | | t1 = _mm_xor_si128(t1, t4); |
104 | | t4 = _mm_slli_si128(t4, 0x4); |
105 | | t1 = _mm_xor_si128(t1, t4); |
106 | | t4 = _mm_slli_si128(t4, 0x4); |
107 | | t1 = _mm_xor_si128(t1, t4); |
108 | | t1 = _mm_xor_si128(t1, t2); |
109 | | t2 = _mm_shuffle_epi32(t1, 0xff); |
110 | | t4 = _mm_slli_si128(t3, 0x4); |
111 | | t3 = _mm_xor_si128(t3, t4); |
112 | | t3 = _mm_xor_si128(t3, t2); |
113 | | |
114 | | (t1, t3) |
115 | | }}; |
116 | | } |
117 | | |
118 | | macro_rules! shuffle { |
119 | | ($a:expr, $b:expr, $imm:expr) => { |
120 | | mem::transmute::<_, __m128i>(_mm_shuffle_pd(mem::transmute($a), mem::transmute($b), $imm)) |
121 | | }; |
122 | | } |
123 | | |
124 | | #[inline] |
125 | | #[target_feature(enable = "aes")] |
126 | 0 | pub(super) unsafe fn expand_key(key: &[u8; 24]) -> RoundKeys { |
127 | 0 | // SAFETY: `RoundKeys` is a `[__m128i; 13]` which can be initialized |
128 | 0 | // with all zeroes. |
129 | 0 | let mut keys: RoundKeys = mem::zeroed(); |
130 | 0 | // we are being extra pedantic here to remove out-of-bound access. |
131 | 0 | // this should be optimized out into movups, movsd sequence |
132 | 0 | // note that unaligned load MUST be used here, even though we read |
133 | 0 | // from the array (compiler missoptimizes aligned load) |
134 | 0 | let (k0, k1l) = { |
135 | 0 | let mut t = [0u8; 32]; |
136 | 0 | ptr::write(t.as_mut_ptr() as *mut [u8; 24], *key); |
137 | 0 |
|
138 | 0 | ( |
139 | 0 | _mm_loadu_si128(t.as_ptr() as *const __m128i), |
140 | 0 | _mm_loadu_si128(t.as_ptr().offset(16) as *const __m128i), |
141 | 0 | ) |
142 | 0 | }; |
143 | 0 |
|
144 | 0 | keys[0] = k0; |
145 | 0 |
|
146 | 0 | let (k1_2, k2r) = expand_round!(k0, k1l, 0x01); |
147 | 0 | keys[1] = shuffle!(k1l, k1_2, 0); |
148 | 0 | keys[2] = shuffle!(k1_2, k2r, 1); |
149 | 0 |
|
150 | 0 | let (k3, k4l) = expand_round!(k1_2, k2r, 0x02); |
151 | 0 | keys[3] = k3; |
152 | 0 |
|
153 | 0 | let (k4_5, k5r) = expand_round!(k3, k4l, 0x04); |
154 | 0 | let k4 = shuffle!(k4l, k4_5, 0); |
155 | 0 | let k5 = shuffle!(k4_5, k5r, 1); |
156 | 0 | keys[4] = k4; |
157 | 0 | keys[5] = k5; |
158 | 0 |
|
159 | 0 | let (k6, k7l) = expand_round!(k4_5, k5r, 0x08); |
160 | 0 | keys[6] = k6; |
161 | 0 |
|
162 | 0 | let (k7_8, k8r) = expand_round!(k6, k7l, 0x10); |
163 | 0 | keys[7] = shuffle!(k7l, k7_8, 0); |
164 | 0 | keys[8] = shuffle!(k7_8, k8r, 1); |
165 | 0 |
|
166 | 0 | let (k9, k10l) = expand_round!(k7_8, k8r, 0x20); |
167 | 0 | keys[9] = k9; |
168 | 0 |
|
169 | 0 | let (k10_11, k11r) = expand_round!(k9, k10l, 0x40); |
170 | 0 | keys[10] = shuffle!(k10l, k10_11, 0); |
171 | 0 | keys[11] = shuffle!(k10_11, k11r, 1); |
172 | 0 |
|
173 | 0 | let (k12, _) = expand_round!(k10_11, k11r, 0x80); |
174 | 0 | keys[12] = k12; |
175 | 0 |
|
176 | 0 | keys |
177 | 0 | } |
178 | | |
179 | | #[inline] |
180 | | #[target_feature(enable = "aes")] |
181 | 0 | pub(super) unsafe fn inv_expanded_keys(keys: &RoundKeys) -> RoundKeys { |
182 | 0 | [ |
183 | 0 | keys[0], |
184 | 0 | _mm_aesimc_si128(keys[1]), |
185 | 0 | _mm_aesimc_si128(keys[2]), |
186 | 0 | _mm_aesimc_si128(keys[3]), |
187 | 0 | _mm_aesimc_si128(keys[4]), |
188 | 0 | _mm_aesimc_si128(keys[5]), |
189 | 0 | _mm_aesimc_si128(keys[6]), |
190 | 0 | _mm_aesimc_si128(keys[7]), |
191 | 0 | _mm_aesimc_si128(keys[8]), |
192 | 0 | _mm_aesimc_si128(keys[9]), |
193 | 0 | _mm_aesimc_si128(keys[10]), |
194 | 0 | _mm_aesimc_si128(keys[11]), |
195 | 0 | keys[12], |
196 | 0 | ] |
197 | 0 | } |