2 * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
13 * @version 3.0 (December 2000)
15 * Optimised ANSI C code for the Rijndael cipher (now AES)
17 * @author Vincent Rijmen
18 * @author Antoon Bosselaers
19 * @author Paulo Barreto
21 * This code is hereby placed in the public domain.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
24 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 /* Note: rewritten a little bit to provide error control and an OpenSSL-
42 #include <openssl/crypto.h>
43 #include <openssl/aes.h>
44 #include "aes_local.h"
46 #if defined(OPENSSL_AES_CONST_TIME) && !defined(AES_ASM)
54 * Compute w := (w * x) mod (x^8 + x^4 + x^3 + x^1 + 1)
55 * Therefore the name "xtime".
57 static void XtimeWord(u32 *w)
70 static void XtimeLong(u64 *w)
75 b = a & 0x8080808080808080uLL;
78 b &= 0x1B1B1B1B1B1B1B1BuLL;
84 * This computes w := S * w ^ -1 + c, where c = {01100011}.
85 * Instead of using GF(2^8) mod (x^8+x^4+x^3+x+1} we do the inversion
86 * in GF(GF(GF(2^2)^2)^2) mod (X^2+X+8)
87 * and GF(GF(2^2)^2) mod (X^2+X+2)
88 * and GF(2^2) mod (X^2+X+1)
89 * The first part of the algorithm below transfers the coordinates
90 * {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80} =>
91 * {1,Y,Y^2,Y^3,Y^4,Y^5,Y^6,Y^7} with Y=0x41:
92 * {0x01,0x41,0x66,0x6c,0x56,0x9a,0x58,0xc4}
93 * The last part undoes the coordinate transfer and the final affine
95 * b[i] = b[i] + b[(i+4)%8] + b[(i+5)%8] + b[(i+6)%8] + b[(i+7)%8] + c[i]
97 * The multiplication in GF(2^2^2^2) is done in ordinary coords:
100 * AB = ((a0*b0 + 8*a1*b1)*1 + (a1*b0 + (a0+a1)*b1)*x^4)
101 * When A = (a0,a1) is given we want to solve AB = 1:
102 * (a) 1 = a0*b0 + 8*a1*b1
103 * (b) 0 = a1*b0 + (a0+a1)*b1
104 * => multiply (a) by a1 and (b) by a0
105 * (c) a1 = a1*a0*b0 + (8*a1*a1)*b1
106 * (d) 0 = a1*a0*b0 + (a0*a0+a1*a0)*b1
108 * (e) a1 = (a0*a0 + a1*a0 + 8*a1*a1)*b1
110 * b1 = (a0*a0 + a1*a0 + 8*a1*a1)^-1 * a1
111 * => and adding (a1*b0) to (b) we get
112 * (f) a1*b0 = (a0+a1)*b1
114 * b0 = (a0*a0 + a1*a0 + 8*a1*a1)^-1 * (a0+a1)
115 * Note this formula also works for the case
116 * (a0+a1)*a0 + 8*a1*a1 = 0
117 * if the inverse element for 0^-1 is mapped to 0.
118 * Repeat the same for GF(2^2^2) and GF(2^2).
119 * We get the following algorithm:
122 * [y0,y1] = mul4([x0,a1],[a0,a1]); (*)
125 * [b0,b1] = mul4([x0,a1],[t,t]); (*)
127 * The non-linear multiplies (*) can be done in parallel at no extra cost.
129 static void SubWord(u32 *w)
131 u32 x, y, a1, a2, a3, a4, a5, a6;
134 y = ((x & 0xFEFEFEFEu) >> 1) | ((x & 0x01010101u) << 7);
136 x ^= y & 0x57575757u;
137 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
138 x ^= y & 0x1C1C1C1Cu;
139 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
140 x ^= y & 0x4A4A4A4Au;
141 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
142 x ^= y & 0x42424242u;
143 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
144 x ^= y & 0x64646464u;
145 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
146 x ^= y & 0xE0E0E0E0u;
148 a1 ^= (x & 0xF0F0F0F0u) >> 4;
149 a2 = ((x & 0xCCCCCCCCu) >> 2) | ((x & 0x33333333u) << 2);
151 a3 ^= (a3 & 0xAAAAAAAAu) >> 1;
152 a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAu;
154 a4 ^= (a4 & 0xAAAAAAAAu) >> 1;
155 a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAu;
156 a5 = (a3 & 0xCCCCCCCCu) >> 2;
157 a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCu;
158 a4 = a5 & 0x22222222u;
160 a4 ^= (a5 << 1) & 0x22222222u;
162 a5 = a3 & 0xA0A0A0A0u;
164 a5 ^= (a3 << 1) & 0xA0A0A0A0u;
165 a4 = a5 & 0xC0C0C0C0u;
167 a4 ^= (a5 << 2) & 0xC0C0C0C0u;
168 a5 = a6 & 0x20202020u;
170 a5 ^= (a6 << 1) & 0x20202020u;
175 a2 ^= (a3 & 0x0C0C0C0Cu) >> 2;
177 a4 ^= (a4 & 0x0A0A0A0A0Au) >> 1;
178 a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0Au;
179 a5 = a4 & 0x08080808u;
181 a5 ^= (a4 << 1) & 0x08080808u;
184 a4 ^= (a4 & 0x02020202u) >> 1;
187 a3 ^= (a3 & 0x0A0A0A0Au) >> 1;
188 a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0Au;
190 a2 = ((a1 & 0xCCCCCCCCu) >> 2) | ((a1 & 0x33333333u) << 2);
192 x ^= (x & 0xAAAAAAAAu) >> 1;
193 x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAu;
195 a4 ^= (a4 & 0xAAAAAAAAu) >> 1;
196 a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAu;
197 a5 = (x & 0xCCCCCCCCu) >> 2;
198 x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCu;
199 a4 = a5 & 0x22222222u;
201 a4 ^= (a5 << 1) & 0x22222222u;
203 y = ((x & 0xFEFEFEFEu) >> 1) | ((x & 0x01010101u) << 7);
205 x ^= y & 0x3F3F3F3Fu;
206 y = ((y & 0xFCFCFCFCu) >> 2) | ((y & 0x03030303u) << 6);
207 x ^= y & 0x97979797u;
208 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
209 x ^= y & 0x9B9B9B9Bu;
210 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
211 x ^= y & 0x3C3C3C3Cu;
212 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
213 x ^= y & 0xDDDDDDDDu;
214 y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7);
215 x ^= y & 0x72727272u;
220 static void SubLong(u64 *w)
222 u64 x, y, a1, a2, a3, a4, a5, a6;
225 y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7);
226 x &= 0xDDDDDDDDDDDDDDDDuLL;
227 x ^= y & 0x5757575757575757uLL;
228 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
229 x ^= y & 0x1C1C1C1C1C1C1C1CuLL;
230 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
231 x ^= y & 0x4A4A4A4A4A4A4A4AuLL;
232 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
233 x ^= y & 0x4242424242424242uLL;
234 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
235 x ^= y & 0x6464646464646464uLL;
236 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
237 x ^= y & 0xE0E0E0E0E0E0E0E0uLL;
239 a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4;
240 a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2);
242 a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
243 a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL;
245 a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
246 a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL;
247 a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2;
248 a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL;
249 a4 = a5 & 0x2222222222222222uLL;
251 a4 ^= (a5 << 1) & 0x2222222222222222uLL;
253 a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL;
255 a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL;
256 a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL;
258 a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL;
259 a5 = a6 & 0x2020202020202020uLL;
261 a5 ^= (a6 << 1) & 0x2020202020202020uLL;
264 a3 &= 0x0F0F0F0F0F0F0F0FuLL;
266 a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2;
268 a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1;
269 a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL;
270 a5 = a4 & 0x0808080808080808uLL;
272 a5 ^= (a4 << 1) & 0x0808080808080808uLL;
274 a4 &= 0x0303030303030303uLL;
275 a4 ^= (a4 & 0x0202020202020202uLL) >> 1;
278 a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1;
279 a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL;
281 a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2);
283 x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
284 x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL;
286 a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
287 a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL;
288 a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2;
289 x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL;
290 a4 = a5 & 0x2222222222222222uLL;
292 a4 ^= (a5 << 1) & 0x2222222222222222uLL;
294 y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7);
295 x &= 0x3939393939393939uLL;
296 x ^= y & 0x3F3F3F3F3F3F3F3FuLL;
297 y = ((y & 0xFCFCFCFCFCFCFCFCuLL) >> 2) | ((y & 0x0303030303030303uLL) << 6);
298 x ^= y & 0x9797979797979797uLL;
299 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
300 x ^= y & 0x9B9B9B9B9B9B9B9BuLL;
301 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
302 x ^= y & 0x3C3C3C3C3C3C3C3CuLL;
303 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
304 x ^= y & 0xDDDDDDDDDDDDDDDDuLL;
305 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
306 x ^= y & 0x7272727272727272uLL;
307 x ^= 0x6363636363636363uLL;
312 * This computes w := (S^-1 * (w + c))^-1
314 static void InvSubLong(u64 *w)
316 u64 x, y, a1, a2, a3, a4, a5, a6;
319 x ^= 0x6363636363636363uLL;
320 y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7);
321 x &= 0xFDFDFDFDFDFDFDFDuLL;
322 x ^= y & 0x5E5E5E5E5E5E5E5EuLL;
323 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
324 x ^= y & 0xF3F3F3F3F3F3F3F3uLL;
325 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
326 x ^= y & 0xF5F5F5F5F5F5F5F5uLL;
327 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
328 x ^= y & 0x7878787878787878uLL;
329 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
330 x ^= y & 0x7777777777777777uLL;
331 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
332 x ^= y & 0x1515151515151515uLL;
333 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
334 x ^= y & 0xA5A5A5A5A5A5A5A5uLL;
336 a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4;
337 a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2);
339 a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
340 a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL;
342 a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
343 a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL;
344 a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2;
345 a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL;
346 a4 = a5 & 0x2222222222222222uLL;
348 a4 ^= (a5 << 1) & 0x2222222222222222uLL;
350 a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL;
352 a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL;
353 a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL;
355 a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL;
356 a5 = a6 & 0x2020202020202020uLL;
358 a5 ^= (a6 << 1) & 0x2020202020202020uLL;
361 a3 &= 0x0F0F0F0F0F0F0F0FuLL;
363 a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2;
365 a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1;
366 a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL;
367 a5 = a4 & 0x0808080808080808uLL;
369 a5 ^= (a4 << 1) & 0x0808080808080808uLL;
371 a4 &= 0x0303030303030303uLL;
372 a4 ^= (a4 & 0x0202020202020202uLL) >> 1;
375 a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1;
376 a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL;
378 a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2);
380 x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
381 x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL;
383 a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1;
384 a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL;
385 a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2;
386 x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL;
387 a4 = a5 & 0x2222222222222222uLL;
389 a4 ^= (a5 << 1) & 0x2222222222222222uLL;
391 y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7);
392 x &= 0xB5B5B5B5B5B5B5B5uLL;
393 x ^= y & 0x4040404040404040uLL;
394 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
395 x ^= y & 0x8080808080808080uLL;
396 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
397 x ^= y & 0x1616161616161616uLL;
398 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
399 x ^= y & 0xEBEBEBEBEBEBEBEBuLL;
400 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
401 x ^= y & 0x9797979797979797uLL;
402 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
403 x ^= y & 0xFBFBFBFBFBFBFBFBuLL;
404 y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7);
405 x ^= y & 0x7D7D7D7D7D7D7D7DuLL;
409 static void ShiftRows(u64 *state)
415 s0 = (unsigned char *)state;
416 for (r = 0; r < 4; r++) {
421 s0[0*4 + r] = s[(r+0) % 4];
422 s0[1*4 + r] = s[(r+1) % 4];
423 s0[2*4 + r] = s[(r+2) % 4];
424 s0[3*4 + r] = s[(r+3) % 4];
428 static void InvShiftRows(u64 *state)
434 s0 = (unsigned char *)state;
435 for (r = 0; r < 4; r++) {
440 s0[0*4 + r] = s[(4-r) % 4];
441 s0[1*4 + r] = s[(5-r) % 4];
442 s0[2*4 + r] = s[(6-r) % 4];
443 s0[3*4 + r] = s[(7-r) % 4];
447 static void MixColumns(u64 *state)
453 for (c = 0; c < 2; c++) {
456 s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16)
457 | ((s.d & 0x0000FFFF0000FFFFuLL) << 16);
458 s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8)
459 | ((s.d & 0x00FF00FF00FF00FFuLL) << 8);
475 static void InvMixColumns(u64 *state)
481 for (c = 0; c < 2; c++) {
484 s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16)
485 | ((s.d & 0x0000FFFF0000FFFFuLL) << 16);
486 s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8)
487 | ((s.d & 0x00FF00FF00FF00FFuLL) << 8);
500 s1.d ^= ((s1.d & 0xFFFF0000FFFF0000uLL) >> 16)
501 | ((s1.d & 0x0000FFFF0000FFFFuLL) << 16);
504 s1.d ^= ((s1.d & 0xFF00FF00FF00FF00uLL) >> 8)
505 | ((s1.d & 0x00FF00FF00FF00FFuLL) << 8);
511 static void AddRoundKey(u64 *state, const u64 *w)
517 static void Cipher(const unsigned char *in, unsigned char *out,
518 const u64 *w, int nr)
523 memcpy(state, in, 16);
525 AddRoundKey(state, w);
527 for (i = 1; i < nr; i++) {
532 AddRoundKey(state, w + i*2);
538 AddRoundKey(state, w + nr*2);
540 memcpy(out, state, 16);
543 static void InvCipher(const unsigned char *in, unsigned char *out,
544 const u64 *w, int nr)
550 memcpy(state, in, 16);
552 AddRoundKey(state, w + nr*2);
554 for (i = nr - 1; i > 0; i--) {
556 InvSubLong(&state[0]);
557 InvSubLong(&state[1]);
558 AddRoundKey(state, w + i*2);
559 InvMixColumns(state);
563 InvSubLong(&state[0]);
564 InvSubLong(&state[1]);
565 AddRoundKey(state, w);
567 memcpy(out, state, 16);
570 static void RotWord(u32 *x)
575 w0 = (unsigned char *)x;
583 static void KeyExpansion(const unsigned char *key, u64 *w,
591 memcpy(w, key, nk*4);
592 memcpy(&rcon, "\1\0\0\0", 4);
595 for (i = n; i < (nr+1)*2; i++) {
602 } else if (nk > 6 && i % n == 2) {
607 prev.w[1] ^= prev.w[0];
613 * Expand the cipher key into the encryption key schedule.
615 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
620 if (!userKey || !key)
622 if (bits != 128 && bits != 192 && bits != 256)
625 rk = (u64*)key->rd_key;
629 else if (bits == 192)
634 KeyExpansion(userKey, rk, key->rounds, bits/32);
639 * Expand the cipher key into the decryption key schedule.
641 int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
644 return AES_set_encrypt_key(userKey, bits, key);
648 * Encrypt a single block
649 * in and out can overlap
651 void AES_encrypt(const unsigned char *in, unsigned char *out,
656 assert(in && out && key);
657 rk = (u64*)key->rd_key;
659 Cipher(in, out, rk, key->rounds);
663 * Decrypt a single block
664 * in and out can overlap
666 void AES_decrypt(const unsigned char *in, unsigned char *out,
671 assert(in && out && key);
672 rk = (u64*)key->rd_key;
674 InvCipher(in, out, rk, key->rounds);
677 # ifndef OPENSSL_SMALL_FOOTPRINT
678 void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
679 size_t blocks, const AES_KEY *key,
680 const unsigned char *ivec);
682 static void RawToBits(const u8 raw[64], u64 bits[8])
688 for (i = 0; i < 8; i++) {
690 for (j = 0; j < 8; j++)
691 in |= ((u64)raw[i * 8 + j]) << (8 * j);
692 out = in & 0xF0F0F0F00F0F0F0FuLL;
693 out |= (in & 0x0F0F0F0F00000000uLL) >> 28;
694 out |= (in & 0x00000000F0F0F0F0uLL) << 28;
695 in = out & 0xCCCC3333CCCC3333uLL;
696 in |= (out & 0x3333000033330000uLL) >> 14;
697 in |= (out & 0x0000CCCC0000CCCCuLL) << 14;
698 out = in & 0xAA55AA55AA55AA55uLL;
699 out |= (in & 0x5500550055005500uLL) >> 7;
700 out |= (in & 0x00AA00AA00AA00AAuLL) << 7;
701 for (j = 0; j < 8; j++) {
702 bits[j] |= (out & 0xFFuLL) << (8 * i);
708 static void BitsToRaw(const u64 bits[8], u8 raw[64])
713 for (i = 0; i < 8; i++) {
715 for (j = 0; j < 8; j++)
716 in |= ((bits[j] >> (8 * i)) & 0xFFuLL) << (8 * j);
717 out = in & 0xF0F0F0F00F0F0F0FuLL;
718 out |= (in & 0x0F0F0F0F00000000uLL) >> 28;
719 out |= (in & 0x00000000F0F0F0F0uLL) << 28;
720 in = out & 0xCCCC3333CCCC3333uLL;
721 in |= (out & 0x3333000033330000uLL) >> 14;
722 in |= (out & 0x0000CCCC0000CCCCuLL) << 14;
723 out = in & 0xAA55AA55AA55AA55uLL;
724 out |= (in & 0x5500550055005500uLL) >> 7;
725 out |= (in & 0x00AA00AA00AA00AAuLL) << 7;
726 for (j = 0; j < 8; j++) {
727 raw[i * 8 + j] = (u8)out;
733 static void BitsXtime(u64 state[8])
741 state[4] = state[3] ^ b;
742 state[3] = state[2] ^ b;
744 state[1] = state[0] ^ b;
749 * This S-box implementation follows a circuit described in
750 * Boyar and Peralta: "A new combinational logic minimization
751 * technique with applications to cryptology."
752 * https://eprint.iacr.org/2009/191.pdf
754 * The math is similar to above, in that it uses
755 * a tower field of GF(2^2^2^2) but with a different
756 * basis representation, that is better suited to
759 static void BitsSub(u64 state[8])
761 u64 x0, x1, x2, x3, x4, x5, x6, x7;
762 u64 y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11;
763 u64 y12, y13, y14, y15, y16, y17, y18, y19, y20, y21;
764 u64 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11;
765 u64 t12, t13, t14, t15, t16, t17, t18, t19, t20, t21;
766 u64 t22, t23, t24, t25, t26, t27, t28, t29, t30, t31;
767 u64 t32, t33, t34, t35, t36, t37, t38, t39, t40, t41;
768 u64 t42, t43, t44, t45, t46, t47, t48, t49, t50, t51;
769 u64 t52, t53, t54, t55, t56, t57, t58, t59, t60, t61;
770 u64 t62, t63, t64, t65, t66, t67;
771 u64 z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11;
772 u64 z12, z13, z14, z15, z16, z17;
773 u64 s0, s1, s2, s3, s4, s5, s6, s7;
908 static void BitsShiftRows(u64 state[8])
913 for (i = 0; i < 8; i++) {
915 s0 = s & 0x1111111111111111uLL;
916 s0 |= ((s & 0x2220222022202220uLL) >> 4) | ((s & 0x0002000200020002uLL) << 12);
917 s0 |= ((s & 0x4400440044004400uLL) >> 8) | ((s & 0x0044004400440044uLL) << 8);
918 s0 |= ((s & 0x8000800080008000uLL) >> 12) | ((s & 0x0888088808880888uLL) << 4);
923 static void BitsMixColumns(u64 state[8])
929 for (i = 0; i < 8; i++) {
932 s ^= ((s & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((s & 0x3333333333333333uLL) << 2);
933 s ^= ((s & 0xAAAAAAAAAAAAAAAAuLL) >> 1) | ((s & 0x5555555555555555uLL) << 1);
938 for (i = 0; i < 8; i++) {
942 s ^= ((s1 & 0xEEEEEEEEEEEEEEEEuLL) >> 1) | ((s1 & 0x1111111111111111uLL) << 3);
947 static void BitsAddRoundKey(u64 state[8], const u64 key[8])
951 for (i = 0; i < 8; i++)
955 void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
956 size_t blocks, const AES_KEY *key,
957 const unsigned char *ivec)
962 u64 rd_key[AES_MAXNR + 1][8];
967 ctr32 = GETU32(ivec + 12);
969 && (bs = OPENSSL_malloc(sizeof(*bs)))) {
970 for (i = 0; i < key->rounds + 1; i++) {
971 memcpy(bs->cipher + 0, &key->rd_key[4 * i], 16);
972 memcpy(bs->cipher + 16, bs->cipher, 16);
973 memcpy(bs->cipher + 32, bs->cipher, 32);
974 RawToBits(bs->cipher, bs->rd_key[i]);
977 memcpy(bs->cipher, ivec, 12);
978 PUTU32(bs->cipher + 12, ctr32);
980 memcpy(bs->cipher + 16, ivec, 12);
981 PUTU32(bs->cipher + 28, ctr32);
983 memcpy(bs->cipher + 32, ivec, 12);
984 PUTU32(bs->cipher + 44, ctr32);
986 memcpy(bs->cipher + 48, ivec, 12);
987 PUTU32(bs->cipher + 60, ctr32);
989 RawToBits(bs->cipher, bs->state);
990 BitsAddRoundKey(bs->state, bs->rd_key[0]);
991 for (i = 1; i < key->rounds; i++) {
993 BitsShiftRows(bs->state);
994 BitsMixColumns(bs->state);
995 BitsAddRoundKey(bs->state, bs->rd_key[i]);
998 BitsShiftRows(bs->state);
999 BitsAddRoundKey(bs->state, bs->rd_key[key->rounds]);
1000 BitsToRaw(bs->state, bs->cipher);
1001 for (i = 0; i < 64 && blocks; i++) {
1002 out[i] = in[i] ^ bs->cipher[i];
1009 OPENSSL_clear_free(bs, sizeof(*bs));
1011 unsigned char cipher[16];
1014 memcpy(cipher, ivec, 12);
1015 PUTU32(cipher + 12, ctr32);
1016 AES_encrypt(cipher, cipher, key);
1017 for (i = 0; i < 16; i++)
1018 out[i] = in[i] ^ cipher[i];
1027 #elif !defined(AES_ASM)
1029 Te0[x] = S [x].[02, 01, 01, 03];
1030 Te1[x] = S [x].[03, 02, 01, 01];
1031 Te2[x] = S [x].[01, 03, 02, 01];
1032 Te3[x] = S [x].[01, 01, 03, 02];
1034 Td0[x] = Si[x].[0e, 09, 0d, 0b];
1035 Td1[x] = Si[x].[0b, 0e, 09, 0d];
1036 Td2[x] = Si[x].[0d, 0b, 0e, 09];
1037 Td3[x] = Si[x].[09, 0d, 0b, 0e];
1038 Td4[x] = Si[x].[01];
1041 static const u32 Te0[256] = {
1042 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1043 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1044 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1045 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1046 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1047 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1048 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1049 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1050 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1051 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1052 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1053 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1054 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1055 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1056 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1057 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1058 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1059 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1060 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1061 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1062 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1063 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1064 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1065 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1066 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1067 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1068 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1069 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1070 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1071 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1072 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1073 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1074 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1075 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1076 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1077 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1078 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1079 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1080 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1081 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1082 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1083 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1084 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1085 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1086 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1087 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1088 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1089 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1090 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1091 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1092 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1093 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1094 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1095 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1096 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1097 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1098 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1099 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1100 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1101 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1102 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1103 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1104 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1105 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1107 static const u32 Te1[256] = {
1108 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1109 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1110 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1111 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1112 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1113 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1114 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1115 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1116 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1117 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1118 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1119 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1120 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1121 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1122 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1123 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1124 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1125 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1126 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1127 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1128 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1129 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1130 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1131 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1132 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1133 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1134 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1135 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1136 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1137 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1138 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1139 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1140 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1141 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1142 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1143 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1144 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1145 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1146 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1147 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1148 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1149 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1150 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1151 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1152 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1153 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1154 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1155 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1156 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1157 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1158 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1159 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1160 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1161 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1162 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1163 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1164 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1165 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1166 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1167 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1168 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1169 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1170 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1171 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1173 static const u32 Te2[256] = {
1174 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1175 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1176 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1177 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1178 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1179 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1180 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1181 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1182 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1183 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1184 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1185 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1186 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1187 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1188 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1189 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1190 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1191 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1192 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1193 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1194 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1195 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1196 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1197 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1198 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1199 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1200 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1201 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1202 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1203 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1204 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1205 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1206 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1207 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1208 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1209 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1210 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1211 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1212 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1213 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1214 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1215 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1216 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1217 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1218 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1219 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1220 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1221 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1222 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1223 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1224 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1225 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1226 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1227 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1228 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1229 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1230 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1231 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1232 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1233 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1234 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1235 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1236 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1237 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1239 static const u32 Te3[256] = {
1240 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1241 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1242 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1243 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1244 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1245 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1246 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1247 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1248 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1249 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1250 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1251 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1252 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1253 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1254 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1255 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1256 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1257 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1258 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1259 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1260 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1261 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1262 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1263 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1264 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1265 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1266 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1267 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1268 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1269 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1270 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1271 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1272 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1273 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1274 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1275 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1276 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1277 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1278 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1279 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1280 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1281 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1282 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1283 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1284 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1285 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1286 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1287 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1288 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1289 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1290 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1291 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1292 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1293 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1294 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1295 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1296 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1297 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1298 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1299 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1300 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1301 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1302 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1303 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1306 static const u32 Td0[256] = {
1307 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1308 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1309 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1310 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1311 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1312 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1313 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1314 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1315 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1316 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1317 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1318 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1319 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1320 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1321 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1322 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1323 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1324 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1325 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1326 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1327 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1328 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1329 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1330 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1331 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1332 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1333 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1334 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1335 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1336 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1337 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1338 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1339 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1340 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1341 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1342 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1343 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1344 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1345 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1346 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1347 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1348 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1349 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1350 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1351 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1352 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1353 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1354 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1355 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1356 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1357 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1358 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1359 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1360 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1361 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1362 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1363 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1364 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1365 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1366 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1367 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1368 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1369 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1370 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1372 static const u32 Td1[256] = {
1373 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1374 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1375 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1376 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1377 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1378 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1379 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1380 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1381 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1382 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1383 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1384 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1385 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1386 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1387 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1388 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1389 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1390 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1391 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1392 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1393 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1394 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1395 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1396 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1397 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1398 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1399 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1400 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1401 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1402 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1403 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1404 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1405 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1406 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1407 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1408 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1409 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1410 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1411 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1412 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1413 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1414 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1415 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1416 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1417 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1418 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1419 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1420 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1421 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1422 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1423 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1424 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1425 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1426 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1427 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1428 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1429 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1430 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1431 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1432 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1433 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1434 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1435 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1436 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1438 static const u32 Td2[256] = {
1439 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1440 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1441 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1442 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1443 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1444 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1445 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1446 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1447 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1448 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1449 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1450 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1451 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1452 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1453 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1454 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1455 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1456 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1457 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1458 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1459 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1460 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1461 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1462 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1463 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1464 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1465 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1466 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1467 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1468 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1469 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1470 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1471 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1472 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1473 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1474 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1475 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1476 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1477 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1478 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1479 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1480 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1481 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1482 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1483 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1484 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1485 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1486 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1487 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1488 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1489 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1490 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1491 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1492 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1493 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1494 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1495 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1496 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1497 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1498 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1499 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1500 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1501 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1502 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1504 static const u32 Td3[256] = {
1505 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1506 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1507 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1508 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1509 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1510 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1511 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1512 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1513 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1514 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1515 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1516 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1517 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1518 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1519 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1520 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1521 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1522 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1523 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1524 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1525 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1526 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1527 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1528 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1529 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1530 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1531 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1532 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1533 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1534 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1535 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1536 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1537 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1538 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1539 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1540 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1541 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1542 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1543 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1544 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1545 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1546 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1547 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1548 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1549 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1550 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1551 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1552 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1553 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1554 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1555 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1556 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1557 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1558 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1559 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1560 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1561 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1562 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1563 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1564 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1565 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1566 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1567 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1568 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1570 static const u8 Td4[256] = {
1571 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1572 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1573 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1574 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1575 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1576 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1577 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1578 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1579 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1580 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1581 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1582 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1583 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1584 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1585 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1586 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1587 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1588 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1589 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1590 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1591 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1592 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1593 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1594 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1595 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1596 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1597 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1598 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1599 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1600 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1601 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1602 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1604 static const u32 rcon[] = {
1605 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1606 0x10000000, 0x20000000, 0x40000000, 0x80000000,
1607 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1611 * Expand the cipher key into the encryption key schedule.
1613 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
1621 if (!userKey || !key)
1623 if (bits != 128 && bits != 192 && bits != 256)
1630 else if (bits == 192)
1635 rk[0] = GETU32(userKey );
1636 rk[1] = GETU32(userKey + 4);
1637 rk[2] = GETU32(userKey + 8);
1638 rk[3] = GETU32(userKey + 12);
1643 (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
1644 (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
1645 (Te0[(temp ) & 0xff] & 0x0000ff00) ^
1646 (Te1[(temp >> 24) ] & 0x000000ff) ^
1648 rk[5] = rk[1] ^ rk[4];
1649 rk[6] = rk[2] ^ rk[5];
1650 rk[7] = rk[3] ^ rk[6];
1657 rk[4] = GETU32(userKey + 16);
1658 rk[5] = GETU32(userKey + 20);
1663 (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
1664 (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
1665 (Te0[(temp ) & 0xff] & 0x0000ff00) ^
1666 (Te1[(temp >> 24) ] & 0x000000ff) ^
1668 rk[ 7] = rk[ 1] ^ rk[ 6];
1669 rk[ 8] = rk[ 2] ^ rk[ 7];
1670 rk[ 9] = rk[ 3] ^ rk[ 8];
1674 rk[10] = rk[ 4] ^ rk[ 9];
1675 rk[11] = rk[ 5] ^ rk[10];
1679 rk[6] = GETU32(userKey + 24);
1680 rk[7] = GETU32(userKey + 28);
1685 (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
1686 (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
1687 (Te0[(temp ) & 0xff] & 0x0000ff00) ^
1688 (Te1[(temp >> 24) ] & 0x000000ff) ^
1690 rk[ 9] = rk[ 1] ^ rk[ 8];
1691 rk[10] = rk[ 2] ^ rk[ 9];
1692 rk[11] = rk[ 3] ^ rk[10];
1698 (Te2[(temp >> 24) ] & 0xff000000) ^
1699 (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
1700 (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
1701 (Te1[(temp ) & 0xff] & 0x000000ff);
1702 rk[13] = rk[ 5] ^ rk[12];
1703 rk[14] = rk[ 6] ^ rk[13];
1704 rk[15] = rk[ 7] ^ rk[14];
1713 * Expand the cipher key into the decryption key schedule.
1715 int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
1723 /* first, start with an encryption schedule */
1724 status = AES_set_encrypt_key(userKey, bits, key);
1730 /* invert the order of the round keys: */
1731 for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
1732 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
1733 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
1734 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
1735 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
1737 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
1738 for (i = 1; i < (key->rounds); i++) {
1741 Td0[Te1[(rk[0] >> 24) ] & 0xff] ^
1742 Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
1743 Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
1744 Td3[Te1[(rk[0] ) & 0xff] & 0xff];
1746 Td0[Te1[(rk[1] >> 24) ] & 0xff] ^
1747 Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
1748 Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
1749 Td3[Te1[(rk[1] ) & 0xff] & 0xff];
1751 Td0[Te1[(rk[2] >> 24) ] & 0xff] ^
1752 Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
1753 Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
1754 Td3[Te1[(rk[2] ) & 0xff] & 0xff];
1756 Td0[Te1[(rk[3] >> 24) ] & 0xff] ^
1757 Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
1758 Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
1759 Td3[Te1[(rk[3] ) & 0xff] & 0xff];
1765 * Encrypt a single block
1766 * in and out can overlap
1768 void AES_encrypt(const unsigned char *in, unsigned char *out,
1769 const AES_KEY *key) {
1772 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1775 #endif /* ?FULL_UNROLL */
1777 assert(in && out && key);
1781 * map byte array block to cipher state
1782 * and add initial round key:
1784 s0 = GETU32(in ) ^ rk[0];
1785 s1 = GETU32(in + 4) ^ rk[1];
1786 s2 = GETU32(in + 8) ^ rk[2];
1787 s3 = GETU32(in + 12) ^ rk[3];
1790 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
1791 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
1792 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
1793 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
1795 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
1796 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
1797 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
1798 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
1800 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
1801 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
1802 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
1803 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
1805 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
1806 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
1807 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
1808 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
1810 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
1811 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
1812 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
1813 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
1815 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
1816 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
1817 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
1818 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
1820 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
1821 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
1822 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
1823 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
1825 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
1826 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
1827 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
1828 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
1830 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
1831 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
1832 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
1833 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
1834 if (key->rounds > 10) {
1836 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
1837 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
1838 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
1839 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
1841 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
1842 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
1843 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
1844 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
1845 if (key->rounds > 12) {
1847 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
1848 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
1849 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
1850 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
1852 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
1853 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
1854 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
1855 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
1858 rk += key->rounds << 2;
1859 #else /* !FULL_UNROLL */
1861 * Nr - 1 full rounds:
1863 r = key->rounds >> 1;
1867 Te1[(s1 >> 16) & 0xff] ^
1868 Te2[(s2 >> 8) & 0xff] ^
1873 Te1[(s2 >> 16) & 0xff] ^
1874 Te2[(s3 >> 8) & 0xff] ^
1879 Te1[(s3 >> 16) & 0xff] ^
1880 Te2[(s0 >> 8) & 0xff] ^
1885 Te1[(s0 >> 16) & 0xff] ^
1886 Te2[(s1 >> 8) & 0xff] ^
1897 Te1[(t1 >> 16) & 0xff] ^
1898 Te2[(t2 >> 8) & 0xff] ^
1903 Te1[(t2 >> 16) & 0xff] ^
1904 Te2[(t3 >> 8) & 0xff] ^
1909 Te1[(t3 >> 16) & 0xff] ^
1910 Te2[(t0 >> 8) & 0xff] ^
1915 Te1[(t0 >> 16) & 0xff] ^
1916 Te2[(t1 >> 8) & 0xff] ^
1920 #endif /* ?FULL_UNROLL */
1922 * apply last round and
1923 * map cipher state to byte array block:
1926 (Te2[(t0 >> 24) ] & 0xff000000) ^
1927 (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1928 (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
1929 (Te1[(t3 ) & 0xff] & 0x000000ff) ^
1933 (Te2[(t1 >> 24) ] & 0xff000000) ^
1934 (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1935 (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
1936 (Te1[(t0 ) & 0xff] & 0x000000ff) ^
1938 PUTU32(out + 4, s1);
1940 (Te2[(t2 >> 24) ] & 0xff000000) ^
1941 (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1942 (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
1943 (Te1[(t1 ) & 0xff] & 0x000000ff) ^
1945 PUTU32(out + 8, s2);
1947 (Te2[(t3 >> 24) ] & 0xff000000) ^
1948 (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1949 (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
1950 (Te1[(t2 ) & 0xff] & 0x000000ff) ^
1952 PUTU32(out + 12, s3);
1956 * Decrypt a single block
1957 * in and out can overlap
1959 void AES_decrypt(const unsigned char *in, unsigned char *out,
1964 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1967 #endif /* ?FULL_UNROLL */
1969 assert(in && out && key);
1973 * map byte array block to cipher state
1974 * and add initial round key:
1976 s0 = GETU32(in ) ^ rk[0];
1977 s1 = GETU32(in + 4) ^ rk[1];
1978 s2 = GETU32(in + 8) ^ rk[2];
1979 s3 = GETU32(in + 12) ^ rk[3];
1982 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
1983 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
1984 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
1985 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
1987 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
1988 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
1989 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
1990 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
1992 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
1993 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
1994 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
1995 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
1997 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
1998 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
1999 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
2000 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
2002 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
2003 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
2004 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
2005 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
2007 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
2008 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
2009 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
2010 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
2012 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
2013 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
2014 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
2015 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
2017 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
2018 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
2019 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
2020 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
2022 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
2023 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
2024 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
2025 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
2026 if (key->rounds > 10) {
2028 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
2029 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
2030 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
2031 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
2033 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
2034 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
2035 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
2036 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
2037 if (key->rounds > 12) {
2039 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
2040 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
2041 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
2042 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
2044 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
2045 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
2046 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
2047 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
2050 rk += key->rounds << 2;
2051 #else /* !FULL_UNROLL */
2053 * Nr - 1 full rounds:
2055 r = key->rounds >> 1;
2059 Td1[(s3 >> 16) & 0xff] ^
2060 Td2[(s2 >> 8) & 0xff] ^
2065 Td1[(s0 >> 16) & 0xff] ^
2066 Td2[(s3 >> 8) & 0xff] ^
2071 Td1[(s1 >> 16) & 0xff] ^
2072 Td2[(s0 >> 8) & 0xff] ^
2077 Td1[(s2 >> 16) & 0xff] ^
2078 Td2[(s1 >> 8) & 0xff] ^
2089 Td1[(t3 >> 16) & 0xff] ^
2090 Td2[(t2 >> 8) & 0xff] ^
2095 Td1[(t0 >> 16) & 0xff] ^
2096 Td2[(t3 >> 8) & 0xff] ^
2101 Td1[(t1 >> 16) & 0xff] ^
2102 Td2[(t0 >> 8) & 0xff] ^
2107 Td1[(t2 >> 16) & 0xff] ^
2108 Td2[(t1 >> 8) & 0xff] ^
2112 #endif /* ?FULL_UNROLL */
2114 * apply last round and
2115 * map cipher state to byte array block:
2118 ((u32)Td4[(t0 >> 24) ] << 24) ^
2119 ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^
2120 ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^
2121 ((u32)Td4[(t1 ) & 0xff]) ^
2125 ((u32)Td4[(t1 >> 24) ] << 24) ^
2126 ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^
2127 ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^
2128 ((u32)Td4[(t2 ) & 0xff]) ^
2130 PUTU32(out + 4, s1);
2132 ((u32)Td4[(t2 >> 24) ] << 24) ^
2133 ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^
2134 ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^
2135 ((u32)Td4[(t3 ) & 0xff]) ^
2137 PUTU32(out + 8, s2);
2139 ((u32)Td4[(t3 >> 24) ] << 24) ^
2140 ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^
2141 ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^
2142 ((u32)Td4[(t0 ) & 0xff]) ^
2144 PUTU32(out + 12, s3);
2149 static const u8 Te4[256] = {
2150 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
2151 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
2152 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
2153 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
2154 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
2155 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
2156 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
2157 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
2158 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
2159 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
2160 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
2161 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
2162 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
2163 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
2164 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
2165 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
2166 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
2167 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
2168 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
2169 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
2170 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
2171 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
2172 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
2173 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
2174 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
2175 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
2176 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
2177 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
2178 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
2179 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
2180 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
2181 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
2183 static const u32 rcon[] = {
2184 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2185 0x10000000, 0x20000000, 0x40000000, 0x80000000,
2186 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2190 * Expand the cipher key into the encryption key schedule.
2192 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
2199 if (!userKey || !key)
2201 if (bits != 128 && bits != 192 && bits != 256)
2208 else if (bits == 192)
2213 rk[0] = GETU32(userKey );
2214 rk[1] = GETU32(userKey + 4);
2215 rk[2] = GETU32(userKey + 8);
2216 rk[3] = GETU32(userKey + 12);
2221 ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
2222 ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
2223 ((u32)Te4[(temp ) & 0xff] << 8) ^
2224 ((u32)Te4[(temp >> 24) ]) ^
2226 rk[5] = rk[1] ^ rk[4];
2227 rk[6] = rk[2] ^ rk[5];
2228 rk[7] = rk[3] ^ rk[6];
2235 rk[4] = GETU32(userKey + 16);
2236 rk[5] = GETU32(userKey + 20);
2241 ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
2242 ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
2243 ((u32)Te4[(temp ) & 0xff] << 8) ^
2244 ((u32)Te4[(temp >> 24) ]) ^
2246 rk[ 7] = rk[ 1] ^ rk[ 6];
2247 rk[ 8] = rk[ 2] ^ rk[ 7];
2248 rk[ 9] = rk[ 3] ^ rk[ 8];
2252 rk[10] = rk[ 4] ^ rk[ 9];
2253 rk[11] = rk[ 5] ^ rk[10];
2257 rk[6] = GETU32(userKey + 24);
2258 rk[7] = GETU32(userKey + 28);
2263 ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
2264 ((u32)Te4[(temp >> 8) & 0xff] << 16) ^
2265 ((u32)Te4[(temp ) & 0xff] << 8) ^
2266 ((u32)Te4[(temp >> 24) ]) ^
2268 rk[ 9] = rk[ 1] ^ rk[ 8];
2269 rk[10] = rk[ 2] ^ rk[ 9];
2270 rk[11] = rk[ 3] ^ rk[10];
2276 ((u32)Te4[(temp >> 24) ] << 24) ^
2277 ((u32)Te4[(temp >> 16) & 0xff] << 16) ^
2278 ((u32)Te4[(temp >> 8) & 0xff] << 8) ^
2279 ((u32)Te4[(temp ) & 0xff]);
2280 rk[13] = rk[ 5] ^ rk[12];
2281 rk[14] = rk[ 6] ^ rk[13];
2282 rk[15] = rk[ 7] ^ rk[14];
2291 * Expand the cipher key into the decryption key schedule.
2293 int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
2301 /* first, start with an encryption schedule */
2302 status = AES_set_encrypt_key(userKey, bits, key);
2308 /* invert the order of the round keys: */
2309 for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
2310 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
2311 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
2312 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
2313 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
2315 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
2316 for (i = 1; i < (key->rounds); i++) {
2318 for (j = 0; j < 4; j++) {
2319 u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
2322 m = tp1 & 0x80808080;
2323 tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
2324 ((m - (m >> 7)) & 0x1b1b1b1b);
2325 m = tp2 & 0x80808080;
2326 tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
2327 ((m - (m >> 7)) & 0x1b1b1b1b);
2328 m = tp4 & 0x80808080;
2329 tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
2330 ((m - (m >> 7)) & 0x1b1b1b1b);
2334 tpe = tp8 ^ tp4 ^ tp2;
2336 rk[j] = tpe ^ ROTATE(tpd,16) ^
2337 ROTATE(tp9,24) ^ ROTATE(tpb,8);
2339 rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
2340 (tp9 >> 8) ^ (tp9 << 24) ^
2341 (tpb >> 24) ^ (tpb << 8);
2348 #endif /* AES_ASM */