Update Tor Project copyright years
[tor/rransom.git] / src / common / aes.c
blob5a6bab242de73bcab1d05365bfc801fa586b2d3e
1 /* Copyright (c) 2001, Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2010, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file aes.c
9 * \brief Implements the AES cipher (with 128-bit keys and blocks),
10 * and a counter-mode stream cipher on top of AES. This code is
11 * taken from the main Rijndael distribution. (We include this
12 * because many people are running older versions of OpenSSL without
13 * AES support.)
14 **/
16 #include "orconfig.h"
17 #include <openssl/opensslv.h>
18 #include <assert.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "compat.h"
22 #include "aes.h"
23 #include "util.h"
24 #include "log.h"
26 /* We have 3 strategies for getting AES: Via OpenSSL's AES_encrypt function,
27 * via OpenSSL's EVP_EncryptUpdate function, or via the built-in AES
28 * implementation below. */
30 /** Defined iff we're using OpenSSL's AES functions for AES. */
31 #undef USE_OPENSSL_AES
32 /** Defined iff we're using OpenSSL's EVP code for AES. */
33 #undef USE_OPENSSL_EVP
34 /** Defined iff we're using Tor's internal AES implementation, defined
35 * below. */
36 #undef USE_BUILTIN_AES
38 /* Figure out our CPU type. We use this to pick an AES implementation.
39 * Macros are as listed at http://predef.sourceforge.net/prearch.html
41 #if (defined(i386) || defined(__i386__) || defined(__i386) || defined(_X86_) \
42 || defined(_M_IX86) || defined(__THW_INTEL__) || defined(__I86__))
43 # define CPU_IS_X86
44 #elif (defined(__amd64__) || defined(__amd64) || \
45 defined(__x86_64__) || defined(__x86_64) || \
46 defined(_M_X64))
47 # define CPU_IS_X86_64
48 #elif (defined(__ia64__) || defined(__ia64) || defined(_IA64) || \
49 defined(_M_IA64))
50 # define CPU_IS_IA64
51 #elif (defined(__sparc__) || defined(__sparc))
52 # define CPU_IS_SPARC
53 #elif (defined(__arm__) || defined (__TARGET_ARCH_ARM))
54 # define CPU_IS_ARM
55 #endif
57 /* Here we pick which to use, if none is force-defined. See
58 * http://archives.seul.org/or/dev/Feb-2007/msg00045.html
59 * for a summary of the most recent benchmarking results that led to this
60 * nutty decision tree.
62 #if (!defined(USE_BUILTIN_AES) && \
63 !defined(USE_OPENSSL_AES) && \
64 !defined(USE_OPENSSL_EVP))
66 /* OpenSSL 0.9.7 was the first to support AES. It was slower than our
67 * built-in implementation.
68 * OpenSSL 0.9.8 added assembly implementations for i386 and ia64.
69 * Either the i386 stuff isn't used for x86-64, or it isn't faster.
70 * OpenSSL 0.9.9 (not yet out) has added assembly implementations for
71 * x86_64 (aka amd64), sparc9, and arm
73 * Note: the "f" at the end of OpenSSL version numbers below means
74 * "release". */
75 # if defined(CPU_IS_X86) || defined(CPU_IS_IA64)
76 # if OPENSSL_VERSION_NUMBER >= 0x0090800fL
77 # define USE_OPENSSL_AES
78 # endif
79 # endif
81 # if defined(CPU_IS_X86_64) || defined(CPU_IS_ARM) || defined(CPU_IS_SPARC)
82 # if OPENSSL_VERSION_NUMBER >= 0x0090900fL
83 # define USE_OPENSSL_AES
84 # endif
85 # endif
87 /* Otherwise, use the built-in implementation below. */
88 # ifndef USE_OPENSSL_AES
89 # define USE_BUILTIN_AES
90 # endif
91 #endif /* endif need to pick a method */
93 /* Include OpenSSL headers as needed. */
94 #ifdef USE_OPENSSL_AES
95 # include <openssl/aes.h>
96 #endif
97 #ifdef USE_OPENSSL_EVP
98 # include <openssl/evp.h>
99 #endif
101 /* Figure out which AES optimizations to use. */
102 #ifdef USE_BUILTIN_AES
103 # define USE_RIJNDAEL_COUNTER_OPTIMIZATION
104 # if 0 && (defined(__powerpc__) || defined(__powerpc64__))
105 /* XXXX do more experimentation before concluding this is actually
106 * a good idea. */
107 # define FULL_UNROLL
108 # endif
109 #endif
111 /*======================================================================*/
112 /* From rijndael-alg-fst.h */
114 typedef uint64_t u64;
115 typedef uint32_t u32;
116 typedef uint8_t u8;
118 #ifdef USE_BUILTIN_AES
119 #define MAXNR 14
121 static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/],
122 const u8 cipherKey[], int keyBits);
123 #ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
124 static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr,
125 u32 ctr3, u32 ctr2,
126 u32 ctr1, u32 ctr0, u8 ct[16]);
127 #else
128 static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr,
129 const u8 pt[16], u8 ct[16]);
130 #endif
131 #endif
133 /*======================================================================*/
134 /* Interface to AES code, and counter implementation */
136 /** Implements an AES counter-mode cipher. */
137 struct aes_cnt_cipher {
138 /** This next element (however it's defined) is the AES key. */
139 #if defined(USE_OPENSSL_EVP)
140 EVP_CIPHER_CTX key;
141 #elif defined(USE_OPENSSL_AES)
142 AES_KEY key;
143 #else
144 u32 rk[4*(MAXNR+1)];
145 int nr;
146 #endif
148 #if !defined(WORDS_BIGENDIAN) || defined(USE_RIJNDAEL_COUNTER_OPTIMIZATION)
149 #define USING_COUNTER_VARS
150 /** These four values, together, implement a 128-bit counter, with
151 * counter0 as the low-order word and counter3 as the high-order word. */
152 u32 counter3;
153 u32 counter2;
154 u32 counter1;
155 u32 counter0;
156 #endif
158 #ifndef USE_RIJNDAEL_COUNTER_OPTIMIZATION
159 #define USING_COUNTER_BUFS
160 union {
161 /** The counter, in big-endian order, as bytes. */
162 u8 buf[16];
163 /** The counter, in big-endian order, as big-endian words. Note that
164 * on big-endian platforms, this is redundant with counter3...0,
165 * so we just use these values instead. */
166 u32 buf32[4];
167 } ctr_buf;
168 #endif
169 /** The encrypted value of ctr_buf. */
170 u8 buf[16];
171 /** Our current stream position within buf. */
172 u8 pos;
175 #if !defined(USING_COUNTER_VARS)
176 #define COUNTER(c, n) ((c)->ctr_buf.buf32[3-(n)])
177 #else
178 #define COUNTER(c, n) ((c)->counter ## n)
179 #endif
182 * Helper function: set <b>cipher</b>'s internal buffer to the encrypted
183 * value of the current counter.
185 static INLINE void
186 _aes_fill_buf(aes_cnt_cipher_t *cipher)
188 /* We don't currently use OpenSSL's counter mode implementation because:
189 * 1) some versions have known bugs
190 * 2) its attitude towards IVs is not our own
191 * 3) changing the counter position was not trivial, last time I looked.
192 * None of these issues are insurmountable in principle.
194 #if defined(USE_BUILTIN_AES) && defined(USE_RIJNDAEL_COUNTER_OPTIMIZATION)
195 rijndaelEncrypt(cipher->rk, cipher->nr,
196 cipher->counter3, cipher->counter2,
197 cipher->counter1, cipher->counter0, cipher->buf);
198 #else
200 #if defined(USE_OPENSSL_EVP)
202 int outl=16, inl=16;
203 EVP_EncryptUpdate(&cipher->key, cipher->buf, &outl,
204 cipher->ctr_buf.buf, inl);
206 #elif defined(USE_OPENSSL_AES)
207 AES_encrypt(cipher->ctr_buf.buf, cipher->buf, &cipher->key);
208 #else
209 rijndaelEncrypt(cipher->rk, cipher->nr, cipher->ctr_buf.buf, cipher->buf);
210 #endif
211 #endif
215 * Return a newly allocated counter-mode AES128 cipher implementation.
217 aes_cnt_cipher_t*
218 aes_new_cipher(void)
220 aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
222 return result;
225 /** Set the key of <b>cipher</b> to <b>key</b>, which is
226 * <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets
227 * the counter to 0.
229 void
230 aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
232 #if defined(USE_OPENSSL_EVP)
233 const EVP_CIPHER *c;
234 switch (key_bits) {
235 case 128: c = EVP_aes_128_ecb(); break;
236 case 192: c = EVP_aes_192_ecb(); break;
237 case 256: c = EVP_aes_256_ecb(); break;
238 default: tor_assert(0);
240 EVP_EncryptInit(&cipher->key, c, (const unsigned char*)key, NULL);
241 #elif defined(USE_OPENSSL_AES)
242 AES_set_encrypt_key((const unsigned char *)key, key_bits, &(cipher->key));
243 #else
244 cipher->nr = rijndaelKeySetupEnc(cipher->rk, (const unsigned char*)key,
245 key_bits);
246 #endif
247 #ifdef USING_COUNTER_VARS
248 cipher->counter0 = 0;
249 cipher->counter1 = 0;
250 cipher->counter2 = 0;
251 cipher->counter3 = 0;
252 #endif
253 #ifdef USING_COUNTER_BUFS
254 memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
255 #endif
257 cipher->pos = 0;
258 _aes_fill_buf(cipher);
261 /** Release storage held by <b>cipher</b>
263 void
264 aes_free_cipher(aes_cnt_cipher_t *cipher)
266 tor_assert(cipher);
267 #ifdef USE_OPENSSL_EVP
268 EVP_CIPHER_CTX_cleanup(&cipher->key);
269 #endif
270 memset(cipher, 0, sizeof(aes_cnt_cipher_t));
271 tor_free(cipher);
274 #if defined(USING_COUNTER_VARS) && defined(USING_COUNTER_BUFS)
275 #define UPDATE_CTR_BUF(c, n) STMT_BEGIN \
276 (c)->ctr_buf.buf32[3-(n)] = htonl((c)->counter ## n); \
277 STMT_END
278 #else
279 #define UPDATE_CTR_BUF(c, n)
280 #endif
282 /** Encrypt <b>len</b> bytes from <b>input</b>, storing the result in
283 * <b>output</b>. Uses the key in <b>cipher</b>, and advances the counter
284 * by <b>len</b> bytes as it encrypts.
286 void
287 aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
288 char *output)
291 /* XXXX This function is up to 5% of our runtime in some profiles;
292 * we should look into unrolling some of the loops; taking advantage
293 * of alignment, using a bigger buffer, and so on. Not till after 0.1.2.x,
294 * though. */
295 int c = cipher->pos;
296 if (PREDICT_UNLIKELY(!len)) return;
298 while (1) {
299 do {
300 if (len-- == 0) { cipher->pos = c; return; }
301 *(output++) = *(input++) ^ cipher->buf[c];
302 } while (++c != 16);
303 cipher->pos = c = 0;
304 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
305 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
306 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
307 ++COUNTER(cipher, 3);
308 UPDATE_CTR_BUF(cipher, 3);
310 UPDATE_CTR_BUF(cipher, 2);
312 UPDATE_CTR_BUF(cipher, 1);
314 UPDATE_CTR_BUF(cipher, 0);
315 _aes_fill_buf(cipher);
319 /** Encrypt <b>len</b> bytes from <b>input</b>, storing the results in place.
320 * Uses the key in <b>cipher</b>, and advances the counter by <b>len</b> bytes
321 * as it encrypts.
323 void
324 aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
327 /* XXXX This function is up to 5% of our runtime in some profiles;
328 * we should look into unrolling some of the loops; taking advantage
329 * of alignment, using a bigger buffer, and so on. Not till after 0.1.2.x,
330 * though. */
331 int c = cipher->pos;
332 if (PREDICT_UNLIKELY(!len)) return;
334 while (1) {
335 do {
336 if (len-- == 0) { cipher->pos = c; return; }
337 *(data++) ^= cipher->buf[c];
338 } while (++c != 16);
339 cipher->pos = c = 0;
340 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
341 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
342 if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
343 ++COUNTER(cipher, 3);
344 UPDATE_CTR_BUF(cipher, 3);
346 UPDATE_CTR_BUF(cipher, 2);
348 UPDATE_CTR_BUF(cipher, 1);
350 UPDATE_CTR_BUF(cipher, 0);
351 _aes_fill_buf(cipher);
355 /** Reset the 128-bit counter of <b>cipher</b> to the 16-bit big-endian value
356 * in <b>iv</b>. */
357 void
358 aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv)
360 #ifdef USING_COUNTER_VARS
361 cipher->counter3 = ntohl(get_uint32(iv));
362 cipher->counter2 = ntohl(get_uint32(iv+4));
363 cipher->counter1 = ntohl(get_uint32(iv+8));
364 cipher->counter0 = ntohl(get_uint32(iv+12));
365 #endif
366 cipher->pos = 0;
367 #ifndef USE_RIJNDAEL_COUNTER_OPTIMIZATION
368 memcpy(cipher->ctr_buf.buf, iv, 16);
369 #endif
371 _aes_fill_buf(cipher);
374 #ifdef USE_BUILTIN_AES
375 /*======================================================================*/
376 /* From rijndael-alg-fst.c */
379 * rijndael-alg-fst.c
381 * @version 3.0 (December 2000)
383 * Optimized ANSI C code for the Rijndael cipher (now AES)
385 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
386 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
387 * @author Paulo Barreto <paulo.barreto@terra.com.br>
389 * This code is hereby placed in the public domain.
391 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
392 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
393 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
394 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
395 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
396 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
397 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
398 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
399 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
400 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
401 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
405 Te0[x] = S [x].[02, 01, 01, 03];
406 Te1[x] = S [x].[03, 02, 01, 01];
407 Te2[x] = S [x].[01, 03, 02, 01];
408 Te3[x] = S [x].[01, 01, 03, 02];
409 Te4[x] = S [x].[01, 01, 01, 01];
411 Td0[x] = Si[x].[0e, 09, 0d, 0b];
412 Td1[x] = Si[x].[0b, 0e, 09, 0d];
413 Td2[x] = Si[x].[0d, 0b, 0e, 09];
414 Td3[x] = Si[x].[09, 0d, 0b, 0e];
415 Td4[x] = Si[x].[01, 01, 01, 01];
418 static const u32 Te0[256] = {
419 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
420 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
421 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
422 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
423 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
424 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
425 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
426 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
427 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
428 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
429 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
430 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
431 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
432 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
433 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
434 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
435 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
436 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
437 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
438 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
439 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
440 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
441 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
442 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
443 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
444 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
445 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
446 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
447 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
448 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
449 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
450 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
451 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
452 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
453 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
454 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
455 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
456 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
457 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
458 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
459 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
460 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
461 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
462 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
463 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
464 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
465 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
466 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
467 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
468 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
469 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
470 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
471 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
472 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
473 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
474 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
475 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
476 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
477 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
478 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
479 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
480 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
481 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
482 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
484 static const u32 Te1[256] = {
485 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
486 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
487 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
488 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
489 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
490 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
491 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
492 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
493 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
494 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
495 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
496 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
497 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
498 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
499 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
500 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
501 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
502 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
503 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
504 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
505 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
506 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
507 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
508 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
509 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
510 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
511 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
512 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
513 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
514 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
515 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
516 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
517 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
518 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
519 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
520 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
521 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
522 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
523 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
524 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
525 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
526 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
527 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
528 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
529 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
530 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
531 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
532 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
533 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
534 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
535 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
536 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
537 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
538 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
539 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
540 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
541 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
542 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
543 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
544 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
545 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
546 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
547 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
548 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
550 static const u32 Te2[256] = {
551 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
552 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
553 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
554 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
555 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
556 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
557 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
558 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
559 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
560 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
561 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
562 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
563 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
564 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
565 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
566 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
567 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
568 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
569 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
570 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
571 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
572 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
573 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
574 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
575 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
576 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
577 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
578 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
579 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
580 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
581 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
582 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
583 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
584 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
585 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
586 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
587 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
588 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
589 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
590 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
591 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
592 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
593 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
594 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
595 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
596 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
597 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
598 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
599 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
600 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
601 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
602 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
603 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
604 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
605 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
606 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
607 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
608 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
609 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
610 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
611 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
612 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
613 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
614 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
616 static const u32 Te3[256] = {
618 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
619 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
620 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
621 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
622 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
623 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
624 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
625 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
626 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
627 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
628 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
629 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
630 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
631 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
632 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
633 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
634 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
635 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
636 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
637 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
638 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
639 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
640 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
641 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
642 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
643 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
644 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
645 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
646 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
647 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
648 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
649 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
650 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
651 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
652 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
653 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
654 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
655 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
656 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
657 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
658 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
659 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
660 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
661 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
662 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
663 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
664 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
665 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
666 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
667 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
668 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
669 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
670 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
671 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
672 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
673 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
674 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
675 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
676 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
677 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
678 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
679 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
680 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
681 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
683 static const u32 Te4[256] = {
684 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
685 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
686 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
687 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
688 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
689 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
690 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
691 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
692 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
693 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
694 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
695 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
696 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
697 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
698 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
699 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
700 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
701 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
702 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
703 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
704 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
705 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
706 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
707 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
708 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
709 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
710 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
711 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
712 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
713 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
714 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
715 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
716 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
717 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
718 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
719 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
720 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
721 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
722 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
723 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
724 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
725 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
726 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
727 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
728 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
729 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
730 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
731 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
732 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
733 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
734 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
735 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
736 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
737 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
738 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
739 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
740 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
741 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
742 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
743 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
744 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
745 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
746 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
747 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
750 static const u32 rcon[] = {
751 0x01000000, 0x02000000, 0x04000000, 0x08000000,
752 0x10000000, 0x20000000, 0x40000000, 0x80000000,
753 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
756 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
758 #ifdef _MSC_VER
759 #define GETU32(p) SWAP(*((u32 *)(p)))
760 #define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
761 #else
762 #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
763 #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
764 #endif
767 * Expand the cipher key into the encryption key schedule.
769 * @return the number of rounds for the given cipher key size.
771 static int
772 rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
774 int i = 0;
775 u32 temp;
777 rk[0] = GETU32(cipherKey );
778 rk[1] = GETU32(cipherKey + 4);
779 rk[2] = GETU32(cipherKey + 8);
780 rk[3] = GETU32(cipherKey + 12);
781 if (keyBits == 128) {
782 for (;;) {
783 temp = rk[3];
784 rk[4] = rk[0] ^
785 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
786 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
787 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
788 (Te4[(temp >> 24) ] & 0x000000ff) ^
789 rcon[i];
790 rk[5] = rk[1] ^ rk[4];
791 rk[6] = rk[2] ^ rk[5];
792 rk[7] = rk[3] ^ rk[6];
793 if (++i == 10) {
794 return 10;
796 rk += 4;
799 rk[4] = GETU32(cipherKey + 16);
800 rk[5] = GETU32(cipherKey + 20);
801 if (keyBits == 192) {
802 for (;;) {
803 temp = rk[ 5];
804 rk[ 6] = rk[ 0] ^
805 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
806 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
807 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
808 (Te4[(temp >> 24) ] & 0x000000ff) ^
809 rcon[i];
810 rk[ 7] = rk[ 1] ^ rk[ 6];
811 rk[ 8] = rk[ 2] ^ rk[ 7];
812 rk[ 9] = rk[ 3] ^ rk[ 8];
813 if (++i == 8) {
814 return 12;
816 rk[10] = rk[ 4] ^ rk[ 9];
817 rk[11] = rk[ 5] ^ rk[10];
818 rk += 6;
821 rk[6] = GETU32(cipherKey + 24);
822 rk[7] = GETU32(cipherKey + 28);
823 if (keyBits == 256) {
824 for (;;) {
825 temp = rk[ 7];
826 rk[ 8] = rk[ 0] ^
827 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
828 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
829 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
830 (Te4[(temp >> 24) ] & 0x000000ff) ^
831 rcon[i];
832 rk[ 9] = rk[ 1] ^ rk[ 8];
833 rk[10] = rk[ 2] ^ rk[ 9];
834 rk[11] = rk[ 3] ^ rk[10];
835 if (++i == 7) {
836 return 14;
838 temp = rk[11];
839 rk[12] = rk[ 4] ^
840 (Te4[(temp >> 24) ] & 0xff000000) ^
841 (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
842 (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
843 (Te4[(temp ) & 0xff] & 0x000000ff);
844 rk[13] = rk[ 5] ^ rk[12];
845 rk[14] = rk[ 6] ^ rk[13];
846 rk[15] = rk[ 7] ^ rk[14];
848 rk += 8;
851 return 0;
854 #ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
855 static void
856 rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, u32 ctr3, u32 ctr2, u32 ctr1, u32 ctr0, u8 ct[16])
857 #else
858 static void
859 rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16])
860 #endif
862 u32 s0, s1, s2, s3, t0, t1, t2, t3;
863 #ifndef FULL_UNROLL
864 int r;
865 #endif /* ?FULL_UNROLL */
868 * map byte array block to cipher state
869 * and add initial round key:
871 #ifdef USE_RIJNDAEL_COUNTER_OPTIMIZATION
872 s0 = ctr3 ^ rk[0];
873 s1 = ctr2 ^ rk[1];
874 s2 = ctr1 ^ rk[2];
875 s3 = ctr0 ^ rk[3];
876 #else
877 s0 = GETU32(pt ) ^ rk[0];
878 s1 = GETU32(pt + 4) ^ rk[1];
879 s2 = GETU32(pt + 8) ^ rk[2];
880 s3 = GETU32(pt + 12) ^ rk[3];
881 #endif
883 #ifdef FULL_UNROLL
884 /* round 1: */
885 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
886 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
887 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
888 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
889 /* round 2: */
890 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
891 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
892 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
893 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
894 /* round 3: */
895 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
896 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
897 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
898 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
899 /* round 4: */
900 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
901 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
902 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
903 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
904 /* round 5: */
905 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
906 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
907 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
908 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
909 /* round 6: */
910 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
911 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
912 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
913 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
914 /* round 7: */
915 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
916 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
917 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
918 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
919 /* round 8: */
920 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
921 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
922 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
923 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
924 /* round 9: */
925 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
926 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
927 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
928 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
929 if (Nr > 10) {
930 /* round 10: */
931 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
932 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
933 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
934 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
935 /* round 11: */
936 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
937 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
938 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
939 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
940 if (Nr > 12) {
941 /* round 12: */
942 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
943 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
944 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
945 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
946 /* round 13: */
947 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
948 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
949 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
950 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
953 rk += Nr << 2;
954 #else /* !FULL_UNROLL */
956 * Nr - 1 full rounds:
958 r = Nr >> 1;
959 for (;;) {
960 t0 =
961 Te0[(s0 >> 24) ] ^
962 Te1[(s1 >> 16) & 0xff] ^
963 Te2[(s2 >> 8) & 0xff] ^
964 Te3[(s3 ) & 0xff] ^
965 rk[4];
966 t1 =
967 Te0[(s1 >> 24) ] ^
968 Te1[(s2 >> 16) & 0xff] ^
969 Te2[(s3 >> 8) & 0xff] ^
970 Te3[(s0 ) & 0xff] ^
971 rk[5];
972 t2 =
973 Te0[(s2 >> 24) ] ^
974 Te1[(s3 >> 16) & 0xff] ^
975 Te2[(s0 >> 8) & 0xff] ^
976 Te3[(s1 ) & 0xff] ^
977 rk[6];
978 t3 =
979 Te0[(s3 >> 24) ] ^
980 Te1[(s0 >> 16) & 0xff] ^
981 Te2[(s1 >> 8) & 0xff] ^
982 Te3[(s2 ) & 0xff] ^
983 rk[7];
985 rk += 8;
986 if (--r == 0) {
987 break;
990 s0 =
991 Te0[(t0 >> 24) ] ^
992 Te1[(t1 >> 16) & 0xff] ^
993 Te2[(t2 >> 8) & 0xff] ^
994 Te3[(t3 ) & 0xff] ^
995 rk[0];
996 s1 =
997 Te0[(t1 >> 24) ] ^
998 Te1[(t2 >> 16) & 0xff] ^
999 Te2[(t3 >> 8) & 0xff] ^
1000 Te3[(t0 ) & 0xff] ^
1001 rk[1];
1002 s2 =
1003 Te0[(t2 >> 24) ] ^
1004 Te1[(t3 >> 16) & 0xff] ^
1005 Te2[(t0 >> 8) & 0xff] ^
1006 Te3[(t1 ) & 0xff] ^
1007 rk[2];
1008 s3 =
1009 Te0[(t3 >> 24) ] ^
1010 Te1[(t0 >> 16) & 0xff] ^
1011 Te2[(t1 >> 8) & 0xff] ^
1012 Te3[(t2 ) & 0xff] ^
1013 rk[3];
1015 #endif /* ?FULL_UNROLL */
1017 * apply last round and
1018 * map cipher state to byte array block:
1020 s0 =
1021 (Te4[(t0 >> 24) ] & 0xff000000) ^
1022 (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1023 (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
1024 (Te4[(t3 ) & 0xff] & 0x000000ff) ^
1025 rk[0];
1026 PUTU32(ct , s0);
1027 s1 =
1028 (Te4[(t1 >> 24) ] & 0xff000000) ^
1029 (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1030 (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
1031 (Te4[(t0 ) & 0xff] & 0x000000ff) ^
1032 rk[1];
1033 PUTU32(ct + 4, s1);
1034 s2 =
1035 (Te4[(t2 >> 24) ] & 0xff000000) ^
1036 (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1037 (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
1038 (Te4[(t1 ) & 0xff] & 0x000000ff) ^
1039 rk[2];
1040 PUTU32(ct + 8, s2);
1041 s3 =
1042 (Te4[(t3 >> 24) ] & 0xff000000) ^
1043 (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1044 (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
1045 (Te4[(t2 ) & 0xff] & 0x000000ff) ^
1046 rk[3];
1047 PUTU32(ct + 12, s3);
1049 #endif
1051 #ifdef AES_BENCHMARK
1053 main(int c, char **v)
1055 int i;
1056 char blob[509]; /* the size of a cell payload. */
1057 char blob_out[509];
1058 aes_cnt_cipher_t *cipher = aes_new_cipher();
1059 aes_set_key(cipher, "aesbenchmarkkey!", 128);
1060 memset(blob, 'z', sizeof(blob));
1062 for (i=0;i<1000000; ++i) {
1063 aes_crypt(cipher, blob, sizeof(blob), blob_out);
1065 return 0;
1067 #endif