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