Add a bunch more warnings to out warning suite; resolve them; pack structs a little...
[tor.git] / src / common / aes.c
blob01f6994702e00927b53b5dc15ec433ca1a60a110
1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar.
2 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char aes_c_id[] = "$Id$";
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 "aes.h"
22 #include "util.h"
23 #include "log.h"
25 /* Use OpenSSL's AES if we're running 0.9.7 or later. (The f at the end of
26 * the version below means "release"; see opensslv.h) */
27 #if OPENSSL_VERSION_NUMBER >= 0x0090700fl
28 #define USE_OPENSSL_AES
29 #include <openssl/aes.h>
30 #include <openssl/evp.h>
31 #endif
33 /* For now, if OpenSSL supports AES, we always use the EVP_CIPHER_CTX version
34 * of it, so OpenSSL can use an engine instead if available. If the overhead
35 * turns out to suck, we should maybe switch to use OpenSSL's AES directly
36 * when no engine exists.
38 #ifdef USE_OPENSSL_AES
39 #define USE_OPENSSL_EVP
40 #endif
42 /*======================================================================*/
43 /* From rijndael-alg-fst.h */
45 typedef uint64_t u64;
46 typedef uint32_t u32;
47 typedef uint8_t u8;
49 #ifndef USE_OPENSSL_AES
50 #define MAXKC (256/32)
51 #define MAXKB (256/8)
52 #define MAXNR 14
54 static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
55 static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]);
56 #endif
58 /*======================================================================*/
59 /* Interface to AES code, and counter implementation */
61 struct aes_cnt_cipher {
62 #if defined(USE_OPENSSL_EVP)
63 EVP_CIPHER_CTX key;
64 #elif defined(USE_OPENSSL_AES)
65 AES_KEY key;
66 #else
67 u32 rk[4*(MAXNR+1)];
68 int nr;
69 #endif
70 u32 counter1;
71 u32 counter0;
72 u8 buf[16];
73 u8 pos;
76 /**
77 * Helper function: set <b>cipher</b>'s internal buffer to the encrypted
78 * value of the current counter.
80 static void
81 _aes_fill_buf(aes_cnt_cipher_t *cipher)
83 /* We don't currently use OpenSSL's counter mode implementation because:
84 * 1) some versions have known bugs
85 * 2) its attitude towards IVs is not our own
86 * 3) changing the counter position was not trivial, last time I looked.
87 * None of these issues are insurmountable in principle.
89 u32 counter0 = cipher->counter0;
90 u32 counter1 = cipher->counter1;
91 u8 buf[16];
92 memset(buf, 0, 8);
93 buf[15] = (counter0 >> 0) & 0xff;
94 buf[14] = (counter0 >> 8) & 0xff;
95 buf[13] = (counter0 >> 16) & 0xff;
96 buf[12] = (counter0 >> 24) & 0xff;
97 buf[11] = (counter1 >> 0) & 0xff;
98 buf[10] = (counter1 >> 8) & 0xff;
99 buf[ 9] = (counter1 >> 16) & 0xff;
100 buf[ 8] = (counter1 >> 24) & 0xff;
102 #if defined(USE_OPENSSL_EVP)
104 int outl=16, inl=16;
105 EVP_EncryptUpdate(&cipher->key, cipher->buf, &outl, buf, inl);
107 #elif defined(USE_OPENSSL_AES)
108 AES_encrypt(buf, cipher->buf, &cipher->key);
109 #else
110 rijndaelEncrypt(cipher->rk, cipher->nr, buf, cipher->buf);
111 #endif
115 * Return a newly allocated counter-mode AES128 cipher implementation.
117 aes_cnt_cipher_t*
118 aes_new_cipher(void)
120 aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
122 return result;
125 /** Set the key of <b>cipher</b> to <b>key</b>, which is
126 * <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets
127 * the counter to 0.
129 void
130 aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
132 #if defined(USE_OPENSSL_EVP)
133 const EVP_CIPHER *c;
134 switch (key_bits) {
135 case 128: c = EVP_aes_128_ecb(); break;
136 case 192: c = EVP_aes_192_ecb(); break;
137 case 256: c = EVP_aes_256_ecb(); break;
138 default: tor_assert(0);
140 EVP_EncryptInit(&cipher->key, c, (const unsigned char*)key, NULL);
141 #elif defined(USE_OPENSSL_AES)
142 AES_set_encrypt_key((const unsigned char *)key, key_bits, &(cipher->key));
143 #else
144 cipher->nr = rijndaelKeySetupEnc(cipher->rk, (const unsigned char*)key,
145 key_bits);
146 #endif
147 cipher->counter0 = 0;
148 cipher->counter1 = 0;
149 cipher->pos = 0;
150 _aes_fill_buf(cipher);
153 /** Release storage held by <b>cipher</b>
155 void
156 aes_free_cipher(aes_cnt_cipher_t *cipher)
158 assert(cipher);
159 memset(cipher, 0, sizeof(cipher));
160 free(cipher);
163 /** Encrypt <b>len</b> bytes from <b>input</b>, storing the result in
164 * <b>output</b>. Uses the key in <b>cipher</b>, and advances the counter
165 * by <b>len</b> bytes as it encrypts.
167 void
168 aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len, char *output)
170 int c = cipher->pos;
171 if (!len) return;
173 while (1) {
174 do {
175 if (len-- == 0) { cipher->pos = c; return; }
176 *(output++) = *(input++) ^ cipher->buf[c];
177 } while (++c != 16);
178 cipher->pos = c = 0;
179 if (! ++cipher->counter0)
180 ++cipher->counter1;
181 _aes_fill_buf(cipher);
185 /** Return the current value of <b>cipher</b>'s counter. */
187 aes_get_counter(aes_cnt_cipher_t *cipher)
189 u64 counter = cipher->pos;
190 counter |= ((u64)cipher->counter0) << 4;
191 counter |= ((u64)cipher->counter1) << 36;
192 return counter;
195 /** Set <b>cipher</b>'s counter to <b>counter</b>. */
196 void
197 aes_set_counter(aes_cnt_cipher_t *cipher, u64 counter)
199 cipher->pos = (u8)(counter & 0x0f);
200 cipher->counter0 = (u32) ((counter >> 4) & 0xffffffff);
201 cipher->counter1 = (u32) (counter >> 36);
202 _aes_fill_buf(cipher);
205 /** Increment <b>cipher</b>'s counter by <b>delta</b>. */
206 void
207 aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta)
209 u64 counter = aes_get_counter(cipher);
210 counter += delta;
211 aes_set_counter(cipher, counter);
214 #ifndef USE_OPENSSL_AES
215 /*======================================================================*/
216 /* From rijndael-alg-fst.c */
219 * rijndael-alg-fst.c
221 * @version 3.0 (December 2000)
223 * Optimised ANSI C code for the Rijndael cipher (now AES)
225 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
226 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
227 * @author Paulo Barreto <paulo.barreto@terra.com.br>
229 * This code is hereby placed in the public domain.
231 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
232 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
233 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
235 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
236 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
237 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
238 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
239 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
240 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
241 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245 Te0[x] = S [x].[02, 01, 01, 03];
246 Te1[x] = S [x].[03, 02, 01, 01];
247 Te2[x] = S [x].[01, 03, 02, 01];
248 Te3[x] = S [x].[01, 01, 03, 02];
249 Te4[x] = S [x].[01, 01, 01, 01];
251 Td0[x] = Si[x].[0e, 09, 0d, 0b];
252 Td1[x] = Si[x].[0b, 0e, 09, 0d];
253 Td2[x] = Si[x].[0d, 0b, 0e, 09];
254 Td3[x] = Si[x].[09, 0d, 0b, 0e];
255 Td4[x] = Si[x].[01, 01, 01, 01];
258 static const u32 Te0[256] = {
259 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
260 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
261 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
262 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
263 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
264 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
265 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
266 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
267 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
268 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
269 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
270 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
271 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
272 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
273 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
274 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
275 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
276 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
277 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
278 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
279 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
280 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
281 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
282 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
283 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
284 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
285 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
286 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
287 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
288 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
289 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
290 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
291 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
292 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
293 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
294 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
295 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
296 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
297 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
298 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
299 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
300 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
301 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
302 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
303 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
304 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
305 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
306 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
307 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
308 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
309 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
310 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
311 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
312 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
313 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
314 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
315 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
316 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
317 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
318 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
319 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
320 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
321 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
322 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
324 static const u32 Te1[256] = {
325 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
326 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
327 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
328 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
329 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
330 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
331 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
332 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
333 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
334 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
335 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
336 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
337 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
338 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
339 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
340 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
341 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
342 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
343 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
344 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
345 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
346 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
347 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
348 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
349 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
350 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
351 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
352 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
353 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
354 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
355 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
356 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
357 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
358 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
359 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
360 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
361 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
362 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
363 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
364 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
365 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
366 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
367 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
368 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
369 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
370 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
371 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
372 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
373 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
374 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
375 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
376 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
377 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
378 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
379 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
380 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
381 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
382 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
383 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
384 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
385 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
386 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
387 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
388 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
390 static const u32 Te2[256] = {
391 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
392 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
393 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
394 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
395 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
396 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
397 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
398 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
399 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
400 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
401 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
402 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
403 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
404 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
405 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
406 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
407 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
408 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
409 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
410 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
411 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
412 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
413 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
414 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
415 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
416 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
417 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
418 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
419 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
420 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
421 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
422 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
423 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
424 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
425 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
426 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
427 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
428 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
429 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
430 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
431 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
432 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
433 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
434 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
435 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
436 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
437 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
438 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
439 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
440 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
441 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
442 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
443 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
444 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
445 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
446 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
447 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
448 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
449 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
450 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
451 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
452 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
453 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
454 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
456 static const u32 Te3[256] = {
458 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
459 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
460 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
461 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
462 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
463 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
464 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
465 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
466 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
467 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
468 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
469 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
470 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
471 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
472 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
473 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
474 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
475 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
476 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
477 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
478 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
479 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
480 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
481 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
482 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
483 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
484 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
485 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
486 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
487 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
488 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
489 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
490 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
491 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
492 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
493 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
494 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
495 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
496 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
497 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
498 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
499 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
500 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
501 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
502 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
503 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
504 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
505 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
506 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
507 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
508 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
509 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
510 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
511 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
512 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
513 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
514 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
515 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
516 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
517 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
518 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
519 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
520 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
521 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
523 static const u32 Te4[256] = {
524 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
525 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
526 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
527 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
528 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
529 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
530 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
531 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
532 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
533 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
534 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
535 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
536 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
537 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
538 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
539 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
540 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
541 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
542 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
543 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
544 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
545 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
546 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
547 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
548 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
549 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
550 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
551 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
552 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
553 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
554 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
555 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
556 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
557 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
558 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
559 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
560 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
561 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
562 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
563 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
564 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
565 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
566 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
567 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
568 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
569 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
570 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
571 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
572 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
573 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
574 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
575 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
576 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
577 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
578 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
579 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
580 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
581 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
582 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
583 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
584 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
585 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
586 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
587 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
590 static const u32 rcon[] = {
591 0x01000000, 0x02000000, 0x04000000, 0x08000000,
592 0x10000000, 0x20000000, 0x40000000, 0x80000000,
593 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
596 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
598 #ifdef _MSC_VER
599 #define GETU32(p) SWAP(*((u32 *)(p)))
600 #define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
601 #else
602 #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
603 #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
604 #endif
607 * Expand the cipher key into the encryption key schedule.
609 * @return the number of rounds for the given cipher key size.
611 int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
612 int i = 0;
613 u32 temp;
615 rk[0] = GETU32(cipherKey );
616 rk[1] = GETU32(cipherKey + 4);
617 rk[2] = GETU32(cipherKey + 8);
618 rk[3] = GETU32(cipherKey + 12);
619 if (keyBits == 128) {
620 for (;;) {
621 temp = rk[3];
622 rk[4] = rk[0] ^
623 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
624 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
625 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
626 (Te4[(temp >> 24) ] & 0x000000ff) ^
627 rcon[i];
628 rk[5] = rk[1] ^ rk[4];
629 rk[6] = rk[2] ^ rk[5];
630 rk[7] = rk[3] ^ rk[6];
631 if (++i == 10) {
632 return 10;
634 rk += 4;
637 rk[4] = GETU32(cipherKey + 16);
638 rk[5] = GETU32(cipherKey + 20);
639 if (keyBits == 192) {
640 for (;;) {
641 temp = rk[ 5];
642 rk[ 6] = rk[ 0] ^
643 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
644 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
645 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
646 (Te4[(temp >> 24) ] & 0x000000ff) ^
647 rcon[i];
648 rk[ 7] = rk[ 1] ^ rk[ 6];
649 rk[ 8] = rk[ 2] ^ rk[ 7];
650 rk[ 9] = rk[ 3] ^ rk[ 8];
651 if (++i == 8) {
652 return 12;
654 rk[10] = rk[ 4] ^ rk[ 9];
655 rk[11] = rk[ 5] ^ rk[10];
656 rk += 6;
659 rk[6] = GETU32(cipherKey + 24);
660 rk[7] = GETU32(cipherKey + 28);
661 if (keyBits == 256) {
662 for (;;) {
663 temp = rk[ 7];
664 rk[ 8] = rk[ 0] ^
665 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
666 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
667 (Te4[(temp ) & 0xff] & 0x0000ff00) ^
668 (Te4[(temp >> 24) ] & 0x000000ff) ^
669 rcon[i];
670 rk[ 9] = rk[ 1] ^ rk[ 8];
671 rk[10] = rk[ 2] ^ rk[ 9];
672 rk[11] = rk[ 3] ^ rk[10];
673 if (++i == 7) {
674 return 14;
676 temp = rk[11];
677 rk[12] = rk[ 4] ^
678 (Te4[(temp >> 24) ] & 0xff000000) ^
679 (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
680 (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
681 (Te4[(temp ) & 0xff] & 0x000000ff);
682 rk[13] = rk[ 5] ^ rk[12];
683 rk[14] = rk[ 6] ^ rk[13];
684 rk[15] = rk[ 7] ^ rk[14];
686 rk += 8;
689 return 0;
692 void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
693 u32 s0, s1, s2, s3, t0, t1, t2, t3;
694 #ifndef FULL_UNROLL
695 int r;
696 #endif /* ?FULL_UNROLL */
699 * map byte array block to cipher state
700 * and add initial round key:
702 s0 = GETU32(pt ) ^ rk[0];
703 s1 = GETU32(pt + 4) ^ rk[1];
704 s2 = GETU32(pt + 8) ^ rk[2];
705 s3 = GETU32(pt + 12) ^ rk[3];
706 #ifdef FULL_UNROLL
707 /* round 1: */
708 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
709 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
710 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
711 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
712 /* round 2: */
713 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
714 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
715 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
716 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
717 /* round 3: */
718 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
719 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
720 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
721 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
722 /* round 4: */
723 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
724 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
725 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
726 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
727 /* round 5: */
728 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
729 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
730 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
731 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
732 /* round 6: */
733 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
734 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
735 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
736 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
737 /* round 7: */
738 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
739 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
740 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
741 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
742 /* round 8: */
743 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
744 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
745 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
746 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
747 /* round 9: */
748 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
749 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
750 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
751 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
752 if (Nr > 10) {
753 /* round 10: */
754 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
755 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
756 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
757 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
758 /* round 11: */
759 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
760 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
761 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
762 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
763 if (Nr > 12) {
764 /* round 12: */
765 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
766 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
767 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
768 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
769 /* round 13: */
770 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
771 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
772 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
773 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
776 rk += Nr << 2;
777 #else /* !FULL_UNROLL */
779 * Nr - 1 full rounds:
781 r = Nr >> 1;
782 for (;;) {
783 t0 =
784 Te0[(s0 >> 24) ] ^
785 Te1[(s1 >> 16) & 0xff] ^
786 Te2[(s2 >> 8) & 0xff] ^
787 Te3[(s3 ) & 0xff] ^
788 rk[4];
789 t1 =
790 Te0[(s1 >> 24) ] ^
791 Te1[(s2 >> 16) & 0xff] ^
792 Te2[(s3 >> 8) & 0xff] ^
793 Te3[(s0 ) & 0xff] ^
794 rk[5];
795 t2 =
796 Te0[(s2 >> 24) ] ^
797 Te1[(s3 >> 16) & 0xff] ^
798 Te2[(s0 >> 8) & 0xff] ^
799 Te3[(s1 ) & 0xff] ^
800 rk[6];
801 t3 =
802 Te0[(s3 >> 24) ] ^
803 Te1[(s0 >> 16) & 0xff] ^
804 Te2[(s1 >> 8) & 0xff] ^
805 Te3[(s2 ) & 0xff] ^
806 rk[7];
808 rk += 8;
809 if (--r == 0) {
810 break;
813 s0 =
814 Te0[(t0 >> 24) ] ^
815 Te1[(t1 >> 16) & 0xff] ^
816 Te2[(t2 >> 8) & 0xff] ^
817 Te3[(t3 ) & 0xff] ^
818 rk[0];
819 s1 =
820 Te0[(t1 >> 24) ] ^
821 Te1[(t2 >> 16) & 0xff] ^
822 Te2[(t3 >> 8) & 0xff] ^
823 Te3[(t0 ) & 0xff] ^
824 rk[1];
825 s2 =
826 Te0[(t2 >> 24) ] ^
827 Te1[(t3 >> 16) & 0xff] ^
828 Te2[(t0 >> 8) & 0xff] ^
829 Te3[(t1 ) & 0xff] ^
830 rk[2];
831 s3 =
832 Te0[(t3 >> 24) ] ^
833 Te1[(t0 >> 16) & 0xff] ^
834 Te2[(t1 >> 8) & 0xff] ^
835 Te3[(t2 ) & 0xff] ^
836 rk[3];
838 #endif /* ?FULL_UNROLL */
840 * apply last round and
841 * map cipher state to byte array block:
843 s0 =
844 (Te4[(t0 >> 24) ] & 0xff000000) ^
845 (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
846 (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
847 (Te4[(t3 ) & 0xff] & 0x000000ff) ^
848 rk[0];
849 PUTU32(ct , s0);
850 s1 =
851 (Te4[(t1 >> 24) ] & 0xff000000) ^
852 (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
853 (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
854 (Te4[(t0 ) & 0xff] & 0x000000ff) ^
855 rk[1];
856 PUTU32(ct + 4, s1);
857 s2 =
858 (Te4[(t2 >> 24) ] & 0xff000000) ^
859 (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
860 (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
861 (Te4[(t1 ) & 0xff] & 0x000000ff) ^
862 rk[2];
863 PUTU32(ct + 8, s2);
864 s3 =
865 (Te4[(t3 >> 24) ] & 0xff000000) ^
866 (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
867 (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
868 (Te4[(t2 ) & 0xff] & 0x000000ff) ^
869 rk[3];
870 PUTU32(ct + 12, s3);
872 #endif