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