It looks like Visual C (or whatever the Windows snapshots are built with)
[u/mdw/putty] / sshaes.c
1 /*
2 * aes.c - implementation of AES / Rijndael
3 *
4 * AES is a flexible algorithm as regards endianness: it has no
5 * inherent preference as to which way round you should form words
6 * from the input byte stream. It talks endlessly of four-byte
7 * _vectors_, but never of 32-bit _words_ - there's no 32-bit
8 * addition at all, which would force an endianness by means of
9 * which way the carries went. So it would be possible to write a
10 * working AES that read words big-endian, and another working one
11 * that read them little-endian, just by computing a different set
12 * of tables - with no speed drop.
13 *
14 * It's therefore tempting to do just that, and remove the overhead
15 * of GET_32BIT_MSB_FIRST() et al, allowing every system to use its
16 * own endianness-native code; but I decided not to, partly for
17 * ease of testing, and mostly because I like the flexibility that
18 * allows you to encrypt a non-word-aligned block of memory (which
19 * many systems would stop being able to do if I went the
20 * endianness-dependent route).
21 *
22 * This implementation reads and stores words big-endian, but
23 * that's a minor implementation detail. By flipping the endianness
24 * of everything in the E0..E3, D0..D3 tables, and substituting
25 * GET_32BIT_LSB_FIRST for GET_32BIT_MSB_FIRST, I could create an
26 * implementation that worked internally little-endian and gave the
27 * same answers at the same speed.
28 */
29
30 #include <assert.h>
31 #include <stdlib.h>
32
33 #include "ssh.h"
34
35 #define MAX_NR 14 /* max no of rounds */
36 #define MAX_NK 8 /* max no of words in input key */
37 #define MAX_NB 8 /* max no of words in cipher blk */
38
39 #define mulby2(x) ( ((x&0x7F) << 1) ^ (x & 0x80 ? 0x1B : 0) )
40
41 #define GET_32BIT_MSB_FIRST(cp) \
42 (((unsigned long)(unsigned char)(cp)[3]) | \
43 ((unsigned long)(unsigned char)(cp)[2] << 8) | \
44 ((unsigned long)(unsigned char)(cp)[1] << 16) | \
45 ((unsigned long)(unsigned char)(cp)[0] << 24))
46
47 #define PUT_32BIT_MSB_FIRST(cp, value) do { \
48 (cp)[3] = (value); \
49 (cp)[2] = (value) >> 8; \
50 (cp)[1] = (value) >> 16; \
51 (cp)[0] = (value) >> 24; } while (0)
52
53 typedef struct AESContext AESContext;
54
55 struct AESContext {
56 word32 keysched[(MAX_NR + 1) * MAX_NB];
57 word32 invkeysched[(MAX_NR + 1) * MAX_NB];
58 void (*encrypt) (AESContext * ctx, word32 * block);
59 void (*decrypt) (AESContext * ctx, word32 * block);
60 word32 iv[MAX_NB];
61 int Nb, Nr;
62 };
63
64 /*
65 * Apple's SC 8.8.4f1 and MrC 4.1.0f1c1 refuse to handle these if
66 * they've got dimensions (they claim "already defined" when the
67 * arrays are actually defined). Microsoft Visual C refuses to handle
68 * them without ("unknown size"). Bah.
69 *
70 * K&R2 A10.2 says both are OK, of course.
71 */
72 #if defined __SC__ || defined __MRC__
73 static const unsigned char Sbox[], Sboxinv[];
74 static const word32 E0[], E1[], E2[], E3[];
75 static const word32 D0[], D1[], D2[], D3[];
76 #else
77 static const unsigned char Sbox[256], Sboxinv[256];
78 static const word32 E0[256], E1[256], E2[256], E3[256];
79 static const word32 D0[256], D1[256], D2[256], D3[256];
80 #endif
81
82 /*
83 * Common macros in both the encryption and decryption routines.
84 */
85 #define ADD_ROUND_KEY_4 (block[0]^=*keysched++, block[1]^=*keysched++, \
86 block[2]^=*keysched++, block[3]^=*keysched++)
87 #define ADD_ROUND_KEY_6 (block[0]^=*keysched++, block[1]^=*keysched++, \
88 block[2]^=*keysched++, block[3]^=*keysched++, \
89 block[4]^=*keysched++, block[5]^=*keysched++)
90 #define ADD_ROUND_KEY_8 (block[0]^=*keysched++, block[1]^=*keysched++, \
91 block[2]^=*keysched++, block[3]^=*keysched++, \
92 block[4]^=*keysched++, block[5]^=*keysched++, \
93 block[6]^=*keysched++, block[7]^=*keysched++)
94 #define MOVEWORD(i) ( block[i] = newstate[i] )
95
96 /*
97 * Macros for the encryption routine. There are three encryption
98 * cores, for Nb=4,6,8.
99 */
100 #define MAKEWORD(i) ( newstate[i] = (E0[(block[i] >> 24) & 0xFF] ^ \
101 E1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
102 E2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
103 E3[block[(i+C3)%Nb] & 0xFF]) )
104 #define LASTWORD(i) ( newstate[i] = (Sbox[(block[i] >> 24) & 0xFF] << 24) | \
105 (Sbox[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
106 (Sbox[(block[(i+C2)%Nb] >> 8) & 0xFF] << 8) | \
107 (Sbox[(block[(i+C3)%Nb] ) & 0xFF] ) )
108
109 /*
110 * Core encrypt routines, expecting word32 inputs read big-endian
111 * from the byte-oriented input stream.
112 */
113 static void aes_encrypt_nb_4(AESContext * ctx, word32 * block)
114 {
115 int i;
116 static const int C1 = 1, C2 = 2, C3 = 3, Nb = 4;
117 word32 *keysched = ctx->keysched;
118 word32 newstate[4];
119 for (i = 0; i < ctx->Nr - 1; i++) {
120 ADD_ROUND_KEY_4;
121 MAKEWORD(0);
122 MAKEWORD(1);
123 MAKEWORD(2);
124 MAKEWORD(3);
125 MOVEWORD(0);
126 MOVEWORD(1);
127 MOVEWORD(2);
128 MOVEWORD(3);
129 }
130 ADD_ROUND_KEY_4;
131 LASTWORD(0);
132 LASTWORD(1);
133 LASTWORD(2);
134 LASTWORD(3);
135 MOVEWORD(0);
136 MOVEWORD(1);
137 MOVEWORD(2);
138 MOVEWORD(3);
139 ADD_ROUND_KEY_4;
140 }
141 static void aes_encrypt_nb_6(AESContext * ctx, word32 * block)
142 {
143 int i;
144 static const int C1 = 1, C2 = 2, C3 = 3, Nb = 6;
145 word32 *keysched = ctx->keysched;
146 word32 newstate[6];
147 for (i = 0; i < ctx->Nr - 1; i++) {
148 ADD_ROUND_KEY_6;
149 MAKEWORD(0);
150 MAKEWORD(1);
151 MAKEWORD(2);
152 MAKEWORD(3);
153 MAKEWORD(4);
154 MAKEWORD(5);
155 MOVEWORD(0);
156 MOVEWORD(1);
157 MOVEWORD(2);
158 MOVEWORD(3);
159 MOVEWORD(4);
160 MOVEWORD(5);
161 }
162 ADD_ROUND_KEY_6;
163 LASTWORD(0);
164 LASTWORD(1);
165 LASTWORD(2);
166 LASTWORD(3);
167 LASTWORD(4);
168 LASTWORD(5);
169 MOVEWORD(0);
170 MOVEWORD(1);
171 MOVEWORD(2);
172 MOVEWORD(3);
173 MOVEWORD(4);
174 MOVEWORD(5);
175 ADD_ROUND_KEY_6;
176 }
177 static void aes_encrypt_nb_8(AESContext * ctx, word32 * block)
178 {
179 int i;
180 static const int C1 = 1, C2 = 3, C3 = 4, Nb = 8;
181 word32 *keysched = ctx->keysched;
182 word32 newstate[8];
183 for (i = 0; i < ctx->Nr - 1; i++) {
184 ADD_ROUND_KEY_8;
185 MAKEWORD(0);
186 MAKEWORD(1);
187 MAKEWORD(2);
188 MAKEWORD(3);
189 MAKEWORD(4);
190 MAKEWORD(5);
191 MAKEWORD(6);
192 MAKEWORD(7);
193 MOVEWORD(0);
194 MOVEWORD(1);
195 MOVEWORD(2);
196 MOVEWORD(3);
197 MOVEWORD(4);
198 MOVEWORD(5);
199 MOVEWORD(6);
200 MOVEWORD(7);
201 }
202 ADD_ROUND_KEY_8;
203 LASTWORD(0);
204 LASTWORD(1);
205 LASTWORD(2);
206 LASTWORD(3);
207 LASTWORD(4);
208 LASTWORD(5);
209 LASTWORD(6);
210 LASTWORD(7);
211 MOVEWORD(0);
212 MOVEWORD(1);
213 MOVEWORD(2);
214 MOVEWORD(3);
215 MOVEWORD(4);
216 MOVEWORD(5);
217 MOVEWORD(6);
218 MOVEWORD(7);
219 ADD_ROUND_KEY_8;
220 }
221
222 #undef MAKEWORD
223 #undef LASTWORD
224
225 /*
226 * Macros for the decryption routine. There are three decryption
227 * cores, for Nb=4,6,8.
228 */
229 #define MAKEWORD(i) ( newstate[i] = (D0[(block[i] >> 24) & 0xFF] ^ \
230 D1[(block[(i+C1)%Nb] >> 16) & 0xFF] ^ \
231 D2[(block[(i+C2)%Nb] >> 8) & 0xFF] ^ \
232 D3[block[(i+C3)%Nb] & 0xFF]) )
233 #define LASTWORD(i) (newstate[i] = (Sboxinv[(block[i] >> 24) & 0xFF] << 24) | \
234 (Sboxinv[(block[(i+C1)%Nb] >> 16) & 0xFF] << 16) | \
235 (Sboxinv[(block[(i+C2)%Nb] >> 8) & 0xFF] << 8) | \
236 (Sboxinv[(block[(i+C3)%Nb] ) & 0xFF] ) )
237
238 /*
239 * Core decrypt routines, expecting word32 inputs read big-endian
240 * from the byte-oriented input stream.
241 */
242 static void aes_decrypt_nb_4(AESContext * ctx, word32 * block)
243 {
244 int i;
245 static const int C1 = 4 - 1, C2 = 4 - 2, C3 = 4 - 3, Nb = 4;
246 word32 *keysched = ctx->invkeysched;
247 word32 newstate[4];
248 for (i = 0; i < ctx->Nr - 1; i++) {
249 ADD_ROUND_KEY_4;
250 MAKEWORD(0);
251 MAKEWORD(1);
252 MAKEWORD(2);
253 MAKEWORD(3);
254 MOVEWORD(0);
255 MOVEWORD(1);
256 MOVEWORD(2);
257 MOVEWORD(3);
258 }
259 ADD_ROUND_KEY_4;
260 LASTWORD(0);
261 LASTWORD(1);
262 LASTWORD(2);
263 LASTWORD(3);
264 MOVEWORD(0);
265 MOVEWORD(1);
266 MOVEWORD(2);
267 MOVEWORD(3);
268 ADD_ROUND_KEY_4;
269 }
270 static void aes_decrypt_nb_6(AESContext * ctx, word32 * block)
271 {
272 int i;
273 static const int C1 = 6 - 1, C2 = 6 - 2, C3 = 6 - 3, Nb = 6;
274 word32 *keysched = ctx->invkeysched;
275 word32 newstate[6];
276 for (i = 0; i < ctx->Nr - 1; i++) {
277 ADD_ROUND_KEY_6;
278 MAKEWORD(0);
279 MAKEWORD(1);
280 MAKEWORD(2);
281 MAKEWORD(3);
282 MAKEWORD(4);
283 MAKEWORD(5);
284 MOVEWORD(0);
285 MOVEWORD(1);
286 MOVEWORD(2);
287 MOVEWORD(3);
288 MOVEWORD(4);
289 MOVEWORD(5);
290 }
291 ADD_ROUND_KEY_6;
292 LASTWORD(0);
293 LASTWORD(1);
294 LASTWORD(2);
295 LASTWORD(3);
296 LASTWORD(4);
297 LASTWORD(5);
298 MOVEWORD(0);
299 MOVEWORD(1);
300 MOVEWORD(2);
301 MOVEWORD(3);
302 MOVEWORD(4);
303 MOVEWORD(5);
304 ADD_ROUND_KEY_6;
305 }
306 static void aes_decrypt_nb_8(AESContext * ctx, word32 * block)
307 {
308 int i;
309 static const int C1 = 8 - 1, C2 = 8 - 3, C3 = 8 - 4, Nb = 8;
310 word32 *keysched = ctx->invkeysched;
311 word32 newstate[8];
312 for (i = 0; i < ctx->Nr - 1; i++) {
313 ADD_ROUND_KEY_8;
314 MAKEWORD(0);
315 MAKEWORD(1);
316 MAKEWORD(2);
317 MAKEWORD(3);
318 MAKEWORD(4);
319 MAKEWORD(5);
320 MAKEWORD(6);
321 MAKEWORD(7);
322 MOVEWORD(0);
323 MOVEWORD(1);
324 MOVEWORD(2);
325 MOVEWORD(3);
326 MOVEWORD(4);
327 MOVEWORD(5);
328 MOVEWORD(6);
329 MOVEWORD(7);
330 }
331 ADD_ROUND_KEY_8;
332 LASTWORD(0);
333 LASTWORD(1);
334 LASTWORD(2);
335 LASTWORD(3);
336 LASTWORD(4);
337 LASTWORD(5);
338 LASTWORD(6);
339 LASTWORD(7);
340 MOVEWORD(0);
341 MOVEWORD(1);
342 MOVEWORD(2);
343 MOVEWORD(3);
344 MOVEWORD(4);
345 MOVEWORD(5);
346 MOVEWORD(6);
347 MOVEWORD(7);
348 ADD_ROUND_KEY_8;
349 }
350
351 #undef MAKEWORD
352 #undef LASTWORD
353
354 static const unsigned char Sbox[256] = {
355 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
356 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
357 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
358 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
359 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
360 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
361 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
362 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
363 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
364 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
365 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
366 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
367 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
368 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
369 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
370 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
371 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
372 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
373 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
374 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
375 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
376 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
377 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
378 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
379 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
380 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
381 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
382 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
383 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
384 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
385 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
386 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
387 };
388
389 static const unsigned char Sboxinv[256] = {
390 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
391 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
392 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
393 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
394 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
395 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
396 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
397 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
398 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
399 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
400 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
401 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
402 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
403 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
404 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
405 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
406 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
407 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
408 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
409 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
410 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
411 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
412 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
413 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
414 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
415 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
416 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
417 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
418 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
419 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
420 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
421 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
422 };
423
424 static const word32 E0[256] = {
425 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
426 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
427 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
428 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
429 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
430 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
431 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
432 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
433 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
434 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
435 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
436 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
437 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
438 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
439 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
440 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
441 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
442 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
443 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
444 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
445 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
446 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
447 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
448 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
449 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
450 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
451 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
452 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
453 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
454 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
455 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
456 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
457 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
458 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
459 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
460 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
461 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
462 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
463 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
464 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
465 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
466 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
467 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
468 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
469 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
470 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
471 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
472 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
473 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
474 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
475 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
476 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
477 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
478 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
479 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
480 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
481 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
482 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
483 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
484 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
485 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
486 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
487 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
488 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
489 };
490 static const word32 E1[256] = {
491 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
492 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
493 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
494 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
495 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
496 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
497 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
498 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
499 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
500 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
501 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
502 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
503 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
504 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
505 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
506 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
507 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
508 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
509 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
510 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
511 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
512 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
513 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
514 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
515 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
516 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
517 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
518 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
519 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
520 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
521 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
522 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
523 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
524 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
525 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
526 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
527 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
528 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
529 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
530 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
531 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
532 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
533 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
534 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
535 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
536 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
537 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
538 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
539 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
540 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
541 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
542 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
543 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
544 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
545 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
546 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
547 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
548 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
549 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
550 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
551 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
552 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
553 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
554 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
555 };
556 static const word32 E2[256] = {
557 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
558 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
559 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
560 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
561 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
562 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
563 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
564 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
565 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
566 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
567 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
568 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
569 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
570 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
571 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
572 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
573 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
574 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
575 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
576 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
577 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
578 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
579 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
580 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
581 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
582 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
583 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
584 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
585 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
586 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
587 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
588 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
589 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
590 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
591 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
592 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
593 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
594 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
595 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
596 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
597 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
598 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
599 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
600 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
601 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
602 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
603 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
604 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
605 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
606 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
607 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
608 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
609 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
610 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
611 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
612 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
613 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
614 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
615 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
616 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
617 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
618 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
619 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
620 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
621 };
622 static const word32 E3[256] = {
623 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
624 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
625 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
626 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
627 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
628 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
629 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
630 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
631 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
632 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
633 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
634 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
635 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
636 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
637 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
638 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
639 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
640 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
641 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
642 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
643 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
644 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
645 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
646 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
647 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
648 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
649 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
650 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
651 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
652 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
653 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
654 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
655 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
656 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
657 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
658 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
659 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
660 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
661 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
662 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
663 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
664 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
665 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
666 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
667 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
668 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
669 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
670 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
671 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
672 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
673 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
674 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
675 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
676 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
677 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
678 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
679 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
680 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
681 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
682 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
683 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
684 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
685 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
686 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
687 };
688 static const word32 D0[256] = {
689 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
690 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
691 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
692 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
693 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
694 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
695 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
696 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
697 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
698 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
699 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
700 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
701 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
702 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
703 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
704 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
705 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
706 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
707 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
708 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
709 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
710 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
711 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
712 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
713 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
714 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
715 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
716 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
717 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
718 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
719 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
720 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
721 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
722 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
723 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
724 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
725 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
726 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
727 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
728 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
729 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
730 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
731 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
732 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
733 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
734 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
735 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
736 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
737 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
738 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
739 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
740 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
741 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
742 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
743 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
744 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
745 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
746 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
747 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
748 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
749 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
750 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
751 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
752 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
753 };
754 static const word32 D1[256] = {
755 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
756 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
757 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
758 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
759 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
760 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
761 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
762 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
763 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
764 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
765 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
766 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
767 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
768 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
769 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
770 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
771 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
772 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
773 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
774 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
775 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
776 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
777 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
778 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
779 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
780 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
781 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
782 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
783 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
784 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
785 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
786 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
787 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
788 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
789 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
790 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
791 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
792 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
793 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
794 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
795 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
796 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
797 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
798 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
799 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
800 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
801 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
802 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
803 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
804 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
805 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
806 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
807 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
808 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
809 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
810 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
811 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
812 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
813 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
814 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
815 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
816 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
817 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
818 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
819 };
820 static const word32 D2[256] = {
821 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
822 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
823 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
824 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
825 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
826 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
827 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
828 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
829 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
830 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
831 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
832 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
833 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
834 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
835 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
836 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
837 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
838 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
839 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
840 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
841 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
842 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
843 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
844 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
845 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
846 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
847 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
848 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
849 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
850 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
851 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
852 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
853 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
854 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
855 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
856 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
857 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
858 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
859 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
860 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
861 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
862 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
863 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
864 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
865 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
866 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
867 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
868 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
869 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
870 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
871 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
872 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
873 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
874 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
875 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
876 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
877 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
878 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
879 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
880 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
881 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
882 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
883 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
884 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
885 };
886 static const word32 D3[256] = {
887 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
888 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
889 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
890 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
891 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
892 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
893 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
894 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
895 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
896 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
897 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
898 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
899 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
900 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
901 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
902 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
903 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
904 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
905 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
906 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
907 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
908 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
909 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
910 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
911 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
912 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
913 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
914 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
915 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
916 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
917 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
918 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
919 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
920 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
921 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
922 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
923 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
924 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
925 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
926 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
927 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
928 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
929 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
930 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
931 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
932 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
933 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
934 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
935 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
936 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
937 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
938 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
939 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
940 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
941 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
942 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
943 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
944 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
945 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
946 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
947 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
948 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
949 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
950 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
951 };
952
953 /*
954 * Set up an AESContext. `keylen' and `blocklen' are measured in
955 * bytes; each can be either 16 (128-bit), 24 (192-bit), or 32
956 * (256-bit).
957 */
958 static void aes_setup(AESContext * ctx, int blocklen,
959 unsigned char *key, int keylen)
960 {
961 int i, j, Nk, rconst;
962
963 assert(blocklen == 16 || blocklen == 24 || blocklen == 32);
964 assert(keylen == 16 || keylen == 24 || keylen == 32);
965
966 /*
967 * Basic parameters. Words per block, words in key, rounds.
968 */
969 Nk = keylen / 4;
970 ctx->Nb = blocklen / 4;
971 ctx->Nr = 6 + (ctx->Nb > Nk ? ctx->Nb : Nk);
972
973 /*
974 * Assign core-function pointers.
975 */
976 if (ctx->Nb == 8)
977 ctx->encrypt = aes_encrypt_nb_8, ctx->decrypt = aes_decrypt_nb_8;
978 else if (ctx->Nb == 6)
979 ctx->encrypt = aes_encrypt_nb_6, ctx->decrypt = aes_decrypt_nb_6;
980 else if (ctx->Nb == 4)
981 ctx->encrypt = aes_encrypt_nb_4, ctx->decrypt = aes_decrypt_nb_4;
982
983 /*
984 * Now do the key setup itself.
985 */
986 rconst = 1;
987 for (i = 0; i < (ctx->Nr + 1) * ctx->Nb; i++) {
988 if (i < Nk)
989 ctx->keysched[i] = GET_32BIT_MSB_FIRST(key + 4 * i);
990 else {
991 word32 temp = ctx->keysched[i - 1];
992 if (i % Nk == 0) {
993 int a, b, c, d;
994 a = (temp >> 16) & 0xFF;
995 b = (temp >> 8) & 0xFF;
996 c = (temp >> 0) & 0xFF;
997 d = (temp >> 24) & 0xFF;
998 temp = Sbox[a] ^ rconst;
999 temp = (temp << 8) | Sbox[b];
1000 temp = (temp << 8) | Sbox[c];
1001 temp = (temp << 8) | Sbox[d];
1002 rconst = mulby2(rconst);
1003 } else if (i % Nk == 4 && Nk > 6) {
1004 int a, b, c, d;
1005 a = (temp >> 24) & 0xFF;
1006 b = (temp >> 16) & 0xFF;
1007 c = (temp >> 8) & 0xFF;
1008 d = (temp >> 0) & 0xFF;
1009 temp = Sbox[a];
1010 temp = (temp << 8) | Sbox[b];
1011 temp = (temp << 8) | Sbox[c];
1012 temp = (temp << 8) | Sbox[d];
1013 }
1014 ctx->keysched[i] = ctx->keysched[i - Nk] ^ temp;
1015 }
1016 }
1017
1018 /*
1019 * Now prepare the modified keys for the inverse cipher.
1020 */
1021 for (i = 0; i <= ctx->Nr; i++) {
1022 for (j = 0; j < ctx->Nb; j++) {
1023 word32 temp;
1024 temp = ctx->keysched[(ctx->Nr - i) * ctx->Nb + j];
1025 if (i != 0 && i != ctx->Nr) {
1026 /*
1027 * Perform the InvMixColumn operation on i. The D
1028 * tables give the result of InvMixColumn applied
1029 * to Sboxinv on individual bytes, so we should
1030 * compose Sbox with the D tables for this.
1031 */
1032 int a, b, c, d;
1033 a = (temp >> 24) & 0xFF;
1034 b = (temp >> 16) & 0xFF;
1035 c = (temp >> 8) & 0xFF;
1036 d = (temp >> 0) & 0xFF;
1037 temp = D0[Sbox[a]];
1038 temp ^= D1[Sbox[b]];
1039 temp ^= D2[Sbox[c]];
1040 temp ^= D3[Sbox[d]];
1041 }
1042 ctx->invkeysched[i * ctx->Nb + j] = temp;
1043 }
1044 }
1045 }
1046
1047 static void aes_encrypt(AESContext * ctx, word32 * block)
1048 {
1049 ctx->encrypt(ctx, block);
1050 }
1051
1052 static void aes_decrypt(AESContext * ctx, word32 * block)
1053 {
1054 ctx->decrypt(ctx, block);
1055 }
1056
1057 static void aes_encrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
1058 {
1059 word32 iv[4];
1060 int i;
1061
1062 assert((len & 15) == 0);
1063
1064 memcpy(iv, ctx->iv, sizeof(iv));
1065
1066 while (len > 0) {
1067 for (i = 0; i < 4; i++)
1068 iv[i] ^= GET_32BIT_MSB_FIRST(blk + 4 * i);
1069 aes_encrypt(ctx, iv);
1070 for (i = 0; i < 4; i++)
1071 PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i]);
1072 blk += 16;
1073 len -= 16;
1074 }
1075
1076 memcpy(ctx->iv, iv, sizeof(iv));
1077 }
1078
1079 static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext * ctx)
1080 {
1081 word32 iv[4], x[4], ct[4];
1082 int i;
1083
1084 assert((len & 15) == 0);
1085
1086 memcpy(iv, ctx->iv, sizeof(iv));
1087
1088 while (len > 0) {
1089 for (i = 0; i < 4; i++)
1090 x[i] = ct[i] = GET_32BIT_MSB_FIRST(blk + 4 * i);
1091 aes_decrypt(ctx, x);
1092 for (i = 0; i < 4; i++) {
1093 PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i] ^ x[i]);
1094 iv[i] = ct[i];
1095 }
1096 blk += 16;
1097 len -= 16;
1098 }
1099
1100 memcpy(ctx->iv, iv, sizeof(iv));
1101 }
1102
1103 static void *aes_make_context(void)
1104 {
1105 return smalloc(sizeof(AESContext));
1106 }
1107
1108 static void aes_free_context(void *handle)
1109 {
1110 sfree(handle);
1111 }
1112
1113 static void aes128_key(void *handle, unsigned char *key)
1114 {
1115 AESContext *ctx = (AESContext *)handle;
1116 aes_setup(ctx, 16, key, 16);
1117 }
1118
1119 static void aes192_key(void *handle, unsigned char *key)
1120 {
1121 AESContext *ctx = (AESContext *)handle;
1122 aes_setup(ctx, 16, key, 24);
1123 }
1124
1125 static void aes256_key(void *handle, unsigned char *key)
1126 {
1127 AESContext *ctx = (AESContext *)handle;
1128 aes_setup(ctx, 16, key, 32);
1129 }
1130
1131 static void aes_iv(void *handle, unsigned char *iv)
1132 {
1133 AESContext *ctx = (AESContext *)handle;
1134 int i;
1135 for (i = 0; i < 4; i++)
1136 ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
1137 }
1138
1139 static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
1140 {
1141 AESContext *ctx = (AESContext *)handle;
1142 aes_encrypt_cbc(blk, len, ctx);
1143 }
1144
1145 static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
1146 {
1147 AESContext *ctx = (AESContext *)handle;
1148 aes_decrypt_cbc(blk, len, ctx);
1149 }
1150
1151 void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
1152 {
1153 AESContext ctx;
1154 aes_setup(&ctx, 16, key, 32);
1155 memset(ctx.iv, 0, sizeof(ctx.iv));
1156 aes_encrypt_cbc(blk, len, &ctx);
1157 memset(&ctx, 0, sizeof(ctx));
1158 }
1159
1160 void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
1161 {
1162 AESContext ctx;
1163 aes_setup(&ctx, 16, key, 32);
1164 memset(ctx.iv, 0, sizeof(ctx.iv));
1165 aes_decrypt_cbc(blk, len, &ctx);
1166 memset(&ctx, 0, sizeof(ctx));
1167 }
1168
1169 static const struct ssh2_cipher ssh_aes128 = {
1170 aes_make_context, aes_free_context, aes_iv, aes128_key,
1171 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1172 "aes128-cbc",
1173 16, 128, "AES-128"
1174 };
1175
1176 static const struct ssh2_cipher ssh_aes192 = {
1177 aes_make_context, aes_free_context, aes_iv, aes192_key,
1178 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1179 "aes192-cbc",
1180 16, 192, "AES-192"
1181 };
1182
1183 static const struct ssh2_cipher ssh_aes256 = {
1184 aes_make_context, aes_free_context, aes_iv, aes256_key,
1185 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1186 "aes256-cbc",
1187 16, 256, "AES-256"
1188 };
1189
1190 static const struct ssh2_cipher ssh_rijndael128 = {
1191 aes_make_context, aes_free_context, aes_iv, aes128_key,
1192 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1193 "rijndael128-cbc",
1194 16, 128, "AES-128"
1195 };
1196
1197 static const struct ssh2_cipher ssh_rijndael192 = {
1198 aes_make_context, aes_free_context, aes_iv, aes192_key,
1199 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1200 "rijndael192-cbc",
1201 16, 192, "AES-192"
1202 };
1203
1204 static const struct ssh2_cipher ssh_rijndael256 = {
1205 aes_make_context, aes_free_context, aes_iv, aes256_key,
1206 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1207 "rijndael256-cbc",
1208 16, 256, "AES-256"
1209 };
1210
1211 static const struct ssh2_cipher ssh_rijndael_lysator = {
1212 aes_make_context, aes_free_context, aes_iv, aes256_key,
1213 aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
1214 "rijndael-cbc@lysator.liu.se",
1215 16, 256, "AES-256"
1216 };
1217
1218 static const struct ssh2_cipher *const aes_list[] = {
1219 &ssh_aes256,
1220 &ssh_rijndael256,
1221 &ssh_rijndael_lysator,
1222 &ssh_aes192,
1223 &ssh_rijndael192,
1224 &ssh_aes128,
1225 &ssh_rijndael128,
1226 };
1227
1228 const struct ssh2_ciphers ssh2_aes = {
1229 sizeof(aes_list) / sizeof(*aes_list),
1230 aes_list
1231 };