Mercurial > dropbear
comparison libtomcrypt/src/ciphers/aes/aes.c @ 285:1b9e69c058d2
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 20dccfc09627970a312d77fb41dc2970b62689c3)
to branch 'au.asn.ucc.matt.dropbear' (head fdf4a7a3b97ae5046139915de7e40399cceb2c01)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 08 Mar 2006 13:23:58 +0000 |
parents | |
children | 0cbe8f6dbf9e |
comparison
equal
deleted
inserted
replaced
281:997e6f7dc01e | 285:1b9e69c058d2 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 | |
12 /* AES implementation by Tom St Denis | |
13 * | |
14 * Derived from the Public Domain source code by | |
15 | |
16 --- | |
17 * rijndael-alg-fst.c | |
18 * | |
19 * @version 3.0 (December 2000) | |
20 * | |
21 * Optimised ANSI C code for the Rijndael cipher (now AES) | |
22 * | |
23 * @author Vincent Rijmen <[email protected]> | |
24 * @author Antoon Bosselaers <[email protected]> | |
25 * @author Paulo Barreto <[email protected]> | |
26 --- | |
27 */ | |
28 /** | |
29 @file aes.c | |
30 Implementation of AES | |
31 */ | |
32 | |
33 #include "tomcrypt.h" | |
34 | |
35 #ifdef RIJNDAEL | |
36 | |
37 #ifndef ENCRYPT_ONLY | |
38 | |
39 #define SETUP rijndael_setup | |
40 #define ECB_ENC rijndael_ecb_encrypt | |
41 #define ECB_DEC rijndael_ecb_decrypt | |
42 #define ECB_DONE rijndael_done | |
43 #define ECB_TEST rijndael_test | |
44 #define ECB_KS rijndael_keysize | |
45 | |
46 #if 0 | |
47 const struct ltc_cipher_descriptor rijndael_desc = | |
48 { | |
49 "rijndael", | |
50 6, | |
51 16, 32, 16, 10, | |
52 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, | |
53 NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
54 }; | |
55 #endif | |
56 | |
57 const struct ltc_cipher_descriptor aes_desc = | |
58 { | |
59 "aes", | |
60 6, | |
61 16, 32, 16, 10, | |
62 SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, | |
63 NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
64 }; | |
65 | |
66 #else | |
67 | |
68 #define SETUP rijndael_enc_setup | |
69 #define ECB_ENC rijndael_enc_ecb_encrypt | |
70 #define ECB_KS rijndael_enc_keysize | |
71 #define ECB_DONE rijndael_enc_done | |
72 | |
73 const struct ltc_cipher_descriptor rijndael_enc_desc = | |
74 { | |
75 "rijndael", | |
76 6, | |
77 16, 32, 16, 10, | |
78 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, | |
79 NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
80 }; | |
81 | |
82 const struct ltc_cipher_descriptor aes_enc_desc = | |
83 { | |
84 "aes", | |
85 6, | |
86 16, 32, 16, 10, | |
87 SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, | |
88 NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
89 }; | |
90 | |
91 #endif | |
92 | |
93 #include "aes_tab.c" | |
94 | |
95 static ulong32 setup_mix(ulong32 temp) | |
96 { | |
97 return (Te4_3[byte(temp, 2)]) ^ | |
98 (Te4_2[byte(temp, 1)]) ^ | |
99 (Te4_1[byte(temp, 0)]) ^ | |
100 (Te4_0[byte(temp, 3)]); | |
101 } | |
102 | |
103 #ifndef ENCRYPT_ONLY | |
104 #ifdef LTC_SMALL_CODE | |
105 static ulong32 setup_mix2(ulong32 temp) | |
106 { | |
107 return Td0(255 & Te4[byte(temp, 3)]) ^ | |
108 Td1(255 & Te4[byte(temp, 2)]) ^ | |
109 Td2(255 & Te4[byte(temp, 1)]) ^ | |
110 Td3(255 & Te4[byte(temp, 0)]); | |
111 } | |
112 #endif | |
113 #endif | |
114 | |
115 /** | |
116 Initialize the AES (Rijndael) block cipher | |
117 @param key The symmetric key you wish to pass | |
118 @param keylen The key length in bytes | |
119 @param num_rounds The number of rounds desired (0 for default) | |
120 @param skey The key in as scheduled by this function. | |
121 @return CRYPT_OK if successful | |
122 */ | |
123 int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | |
124 { | |
125 int i, j; | |
126 ulong32 temp, *rk; | |
127 #ifndef ENCRYPT_ONLY | |
128 ulong32 *rrk; | |
129 #endif | |
130 LTC_ARGCHK(key != NULL); | |
131 LTC_ARGCHK(skey != NULL); | |
132 | |
133 if (keylen != 16 && keylen != 24 && keylen != 32) { | |
134 return CRYPT_INVALID_KEYSIZE; | |
135 } | |
136 | |
137 if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { | |
138 return CRYPT_INVALID_ROUNDS; | |
139 } | |
140 | |
141 skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; | |
142 | |
143 /* setup the forward key */ | |
144 i = 0; | |
145 rk = skey->rijndael.eK; | |
146 LOAD32H(rk[0], key ); | |
147 LOAD32H(rk[1], key + 4); | |
148 LOAD32H(rk[2], key + 8); | |
149 LOAD32H(rk[3], key + 12); | |
150 if (keylen == 16) { | |
151 j = 44; | |
152 for (;;) { | |
153 temp = rk[3]; | |
154 rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; | |
155 rk[5] = rk[1] ^ rk[4]; | |
156 rk[6] = rk[2] ^ rk[5]; | |
157 rk[7] = rk[3] ^ rk[6]; | |
158 if (++i == 10) { | |
159 break; | |
160 } | |
161 rk += 4; | |
162 } | |
163 } else if (keylen == 24) { | |
164 j = 52; | |
165 LOAD32H(rk[4], key + 16); | |
166 LOAD32H(rk[5], key + 20); | |
167 for (;;) { | |
168 #ifdef _MSC_VER | |
169 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; | |
170 #else | |
171 temp = rk[5]; | |
172 #endif | |
173 rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; | |
174 rk[ 7] = rk[ 1] ^ rk[ 6]; | |
175 rk[ 8] = rk[ 2] ^ rk[ 7]; | |
176 rk[ 9] = rk[ 3] ^ rk[ 8]; | |
177 if (++i == 8) { | |
178 break; | |
179 } | |
180 rk[10] = rk[ 4] ^ rk[ 9]; | |
181 rk[11] = rk[ 5] ^ rk[10]; | |
182 rk += 6; | |
183 } | |
184 } else if (keylen == 32) { | |
185 j = 60; | |
186 LOAD32H(rk[4], key + 16); | |
187 LOAD32H(rk[5], key + 20); | |
188 LOAD32H(rk[6], key + 24); | |
189 LOAD32H(rk[7], key + 28); | |
190 for (;;) { | |
191 #ifdef _MSC_VER | |
192 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; | |
193 #else | |
194 temp = rk[7]; | |
195 #endif | |
196 rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; | |
197 rk[ 9] = rk[ 1] ^ rk[ 8]; | |
198 rk[10] = rk[ 2] ^ rk[ 9]; | |
199 rk[11] = rk[ 3] ^ rk[10]; | |
200 if (++i == 7) { | |
201 break; | |
202 } | |
203 temp = rk[11]; | |
204 rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8)); | |
205 rk[13] = rk[ 5] ^ rk[12]; | |
206 rk[14] = rk[ 6] ^ rk[13]; | |
207 rk[15] = rk[ 7] ^ rk[14]; | |
208 rk += 8; | |
209 } | |
210 } else { | |
211 /* this can't happen */ | |
212 return CRYPT_ERROR; | |
213 } | |
214 | |
215 #ifndef ENCRYPT_ONLY | |
216 /* setup the inverse key now */ | |
217 rk = skey->rijndael.dK; | |
218 rrk = skey->rijndael.eK + j - 4; | |
219 | |
220 /* apply the inverse MixColumn transform to all round keys but the first and the last: */ | |
221 /* copy first */ | |
222 *rk++ = *rrk++; | |
223 *rk++ = *rrk++; | |
224 *rk++ = *rrk++; | |
225 *rk = *rrk; | |
226 rk -= 3; rrk -= 3; | |
227 | |
228 for (i = 1; i < skey->rijndael.Nr; i++) { | |
229 rrk -= 4; | |
230 rk += 4; | |
231 #ifdef LTC_SMALL_CODE | |
232 temp = rrk[0]; | |
233 rk[0] = setup_mix2(temp); | |
234 temp = rrk[1]; | |
235 rk[1] = setup_mix2(temp); | |
236 temp = rrk[2]; | |
237 rk[2] = setup_mix2(temp); | |
238 temp = rrk[3]; | |
239 rk[3] = setup_mix2(temp); | |
240 #else | |
241 temp = rrk[0]; | |
242 rk[0] = | |
243 Tks0[byte(temp, 3)] ^ | |
244 Tks1[byte(temp, 2)] ^ | |
245 Tks2[byte(temp, 1)] ^ | |
246 Tks3[byte(temp, 0)]; | |
247 temp = rrk[1]; | |
248 rk[1] = | |
249 Tks0[byte(temp, 3)] ^ | |
250 Tks1[byte(temp, 2)] ^ | |
251 Tks2[byte(temp, 1)] ^ | |
252 Tks3[byte(temp, 0)]; | |
253 temp = rrk[2]; | |
254 rk[2] = | |
255 Tks0[byte(temp, 3)] ^ | |
256 Tks1[byte(temp, 2)] ^ | |
257 Tks2[byte(temp, 1)] ^ | |
258 Tks3[byte(temp, 0)]; | |
259 temp = rrk[3]; | |
260 rk[3] = | |
261 Tks0[byte(temp, 3)] ^ | |
262 Tks1[byte(temp, 2)] ^ | |
263 Tks2[byte(temp, 1)] ^ | |
264 Tks3[byte(temp, 0)]; | |
265 #endif | |
266 | |
267 } | |
268 | |
269 /* copy last */ | |
270 rrk -= 4; | |
271 rk += 4; | |
272 *rk++ = *rrk++; | |
273 *rk++ = *rrk++; | |
274 *rk++ = *rrk++; | |
275 *rk = *rrk; | |
276 #endif /* ENCRYPT_ONLY */ | |
277 | |
278 return CRYPT_OK; | |
279 } | |
280 | |
281 /** | |
282 Encrypts a block of text with AES | |
283 @param pt The input plaintext (16 bytes) | |
284 @param ct The output ciphertext (16 bytes) | |
285 @param skey The key as scheduled | |
286 */ | |
287 #ifdef LTC_CLEAN_STACK | |
288 static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
289 #else | |
290 void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
291 #endif | |
292 { | |
293 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | |
294 int Nr, r; | |
295 | |
296 LTC_ARGCHK(pt != NULL); | |
297 LTC_ARGCHK(ct != NULL); | |
298 LTC_ARGCHK(skey != NULL); | |
299 | |
300 Nr = skey->rijndael.Nr; | |
301 rk = skey->rijndael.eK; | |
302 | |
303 /* | |
304 * map byte array block to cipher state | |
305 * and add initial round key: | |
306 */ | |
307 LOAD32H(s0, pt ); s0 ^= rk[0]; | |
308 LOAD32H(s1, pt + 4); s1 ^= rk[1]; | |
309 LOAD32H(s2, pt + 8); s2 ^= rk[2]; | |
310 LOAD32H(s3, pt + 12); s3 ^= rk[3]; | |
311 | |
312 | |
313 #ifdef LTC_SMALL_CODE | |
314 | |
315 for (r = 0; ; r++) { | |
316 rk += 4; | |
317 t0 = | |
318 Te0(byte(s0, 3)) ^ | |
319 Te1(byte(s1, 2)) ^ | |
320 Te2(byte(s2, 1)) ^ | |
321 Te3(byte(s3, 0)) ^ | |
322 rk[0]; | |
323 t1 = | |
324 Te0(byte(s1, 3)) ^ | |
325 Te1(byte(s2, 2)) ^ | |
326 Te2(byte(s3, 1)) ^ | |
327 Te3(byte(s0, 0)) ^ | |
328 rk[1]; | |
329 t2 = | |
330 Te0(byte(s2, 3)) ^ | |
331 Te1(byte(s3, 2)) ^ | |
332 Te2(byte(s0, 1)) ^ | |
333 Te3(byte(s1, 0)) ^ | |
334 rk[2]; | |
335 t3 = | |
336 Te0(byte(s3, 3)) ^ | |
337 Te1(byte(s0, 2)) ^ | |
338 Te2(byte(s1, 1)) ^ | |
339 Te3(byte(s2, 0)) ^ | |
340 rk[3]; | |
341 if (r == Nr-2) { | |
342 break; | |
343 } | |
344 s0 = t0; s1 = t1; s2 = t2; s3 = t3; | |
345 } | |
346 rk += 4; | |
347 | |
348 #else | |
349 | |
350 /* | |
351 * Nr - 1 full rounds: | |
352 */ | |
353 r = Nr >> 1; | |
354 for (;;) { | |
355 t0 = | |
356 Te0(byte(s0, 3)) ^ | |
357 Te1(byte(s1, 2)) ^ | |
358 Te2(byte(s2, 1)) ^ | |
359 Te3(byte(s3, 0)) ^ | |
360 rk[4]; | |
361 t1 = | |
362 Te0(byte(s1, 3)) ^ | |
363 Te1(byte(s2, 2)) ^ | |
364 Te2(byte(s3, 1)) ^ | |
365 Te3(byte(s0, 0)) ^ | |
366 rk[5]; | |
367 t2 = | |
368 Te0(byte(s2, 3)) ^ | |
369 Te1(byte(s3, 2)) ^ | |
370 Te2(byte(s0, 1)) ^ | |
371 Te3(byte(s1, 0)) ^ | |
372 rk[6]; | |
373 t3 = | |
374 Te0(byte(s3, 3)) ^ | |
375 Te1(byte(s0, 2)) ^ | |
376 Te2(byte(s1, 1)) ^ | |
377 Te3(byte(s2, 0)) ^ | |
378 rk[7]; | |
379 | |
380 rk += 8; | |
381 if (--r == 0) { | |
382 break; | |
383 } | |
384 | |
385 s0 = | |
386 Te0(byte(t0, 3)) ^ | |
387 Te1(byte(t1, 2)) ^ | |
388 Te2(byte(t2, 1)) ^ | |
389 Te3(byte(t3, 0)) ^ | |
390 rk[0]; | |
391 s1 = | |
392 Te0(byte(t1, 3)) ^ | |
393 Te1(byte(t2, 2)) ^ | |
394 Te2(byte(t3, 1)) ^ | |
395 Te3(byte(t0, 0)) ^ | |
396 rk[1]; | |
397 s2 = | |
398 Te0(byte(t2, 3)) ^ | |
399 Te1(byte(t3, 2)) ^ | |
400 Te2(byte(t0, 1)) ^ | |
401 Te3(byte(t1, 0)) ^ | |
402 rk[2]; | |
403 s3 = | |
404 Te0(byte(t3, 3)) ^ | |
405 Te1(byte(t0, 2)) ^ | |
406 Te2(byte(t1, 1)) ^ | |
407 Te3(byte(t2, 0)) ^ | |
408 rk[3]; | |
409 } | |
410 | |
411 #endif | |
412 | |
413 /* | |
414 * apply last round and | |
415 * map cipher state to byte array block: | |
416 */ | |
417 s0 = | |
418 (Te4_3[byte(t0, 3)]) ^ | |
419 (Te4_2[byte(t1, 2)]) ^ | |
420 (Te4_1[byte(t2, 1)]) ^ | |
421 (Te4_0[byte(t3, 0)]) ^ | |
422 rk[0]; | |
423 STORE32H(s0, ct); | |
424 s1 = | |
425 (Te4_3[byte(t1, 3)]) ^ | |
426 (Te4_2[byte(t2, 2)]) ^ | |
427 (Te4_1[byte(t3, 1)]) ^ | |
428 (Te4_0[byte(t0, 0)]) ^ | |
429 rk[1]; | |
430 STORE32H(s1, ct+4); | |
431 s2 = | |
432 (Te4_3[byte(t2, 3)]) ^ | |
433 (Te4_2[byte(t3, 2)]) ^ | |
434 (Te4_1[byte(t0, 1)]) ^ | |
435 (Te4_0[byte(t1, 0)]) ^ | |
436 rk[2]; | |
437 STORE32H(s2, ct+8); | |
438 s3 = | |
439 (Te4_3[byte(t3, 3)]) ^ | |
440 (Te4_2[byte(t0, 2)]) ^ | |
441 (Te4_1[byte(t1, 1)]) ^ | |
442 (Te4_0[byte(t2, 0)]) ^ | |
443 rk[3]; | |
444 STORE32H(s3, ct+12); | |
445 } | |
446 | |
447 #ifdef LTC_CLEAN_STACK | |
448 void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | |
449 { | |
450 _rijndael_ecb_encrypt(pt, ct, skey); | |
451 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | |
452 } | |
453 #endif | |
454 | |
455 #ifndef ENCRYPT_ONLY | |
456 | |
457 /** | |
458 Decrypts a block of text with AES | |
459 @param ct The input ciphertext (16 bytes) | |
460 @param pt The output plaintext (16 bytes) | |
461 @param skey The key as scheduled | |
462 */ | |
463 #ifdef LTC_CLEAN_STACK | |
464 static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
465 #else | |
466 void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
467 #endif | |
468 { | |
469 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | |
470 int Nr, r; | |
471 | |
472 LTC_ARGCHK(pt != NULL); | |
473 LTC_ARGCHK(ct != NULL); | |
474 LTC_ARGCHK(skey != NULL); | |
475 | |
476 Nr = skey->rijndael.Nr; | |
477 rk = skey->rijndael.dK; | |
478 | |
479 /* | |
480 * map byte array block to cipher state | |
481 * and add initial round key: | |
482 */ | |
483 LOAD32H(s0, ct ); s0 ^= rk[0]; | |
484 LOAD32H(s1, ct + 4); s1 ^= rk[1]; | |
485 LOAD32H(s2, ct + 8); s2 ^= rk[2]; | |
486 LOAD32H(s3, ct + 12); s3 ^= rk[3]; | |
487 | |
488 #ifdef LTC_SMALL_CODE | |
489 for (r = 0; ; r++) { | |
490 rk += 4; | |
491 t0 = | |
492 Td0(byte(s0, 3)) ^ | |
493 Td1(byte(s3, 2)) ^ | |
494 Td2(byte(s2, 1)) ^ | |
495 Td3(byte(s1, 0)) ^ | |
496 rk[0]; | |
497 t1 = | |
498 Td0(byte(s1, 3)) ^ | |
499 Td1(byte(s0, 2)) ^ | |
500 Td2(byte(s3, 1)) ^ | |
501 Td3(byte(s2, 0)) ^ | |
502 rk[1]; | |
503 t2 = | |
504 Td0(byte(s2, 3)) ^ | |
505 Td1(byte(s1, 2)) ^ | |
506 Td2(byte(s0, 1)) ^ | |
507 Td3(byte(s3, 0)) ^ | |
508 rk[2]; | |
509 t3 = | |
510 Td0(byte(s3, 3)) ^ | |
511 Td1(byte(s2, 2)) ^ | |
512 Td2(byte(s1, 1)) ^ | |
513 Td3(byte(s0, 0)) ^ | |
514 rk[3]; | |
515 if (r == Nr-2) { | |
516 break; | |
517 } | |
518 s0 = t0; s1 = t1; s2 = t2; s3 = t3; | |
519 } | |
520 rk += 4; | |
521 | |
522 #else | |
523 | |
524 /* | |
525 * Nr - 1 full rounds: | |
526 */ | |
527 r = Nr >> 1; | |
528 for (;;) { | |
529 | |
530 t0 = | |
531 Td0(byte(s0, 3)) ^ | |
532 Td1(byte(s3, 2)) ^ | |
533 Td2(byte(s2, 1)) ^ | |
534 Td3(byte(s1, 0)) ^ | |
535 rk[4]; | |
536 t1 = | |
537 Td0(byte(s1, 3)) ^ | |
538 Td1(byte(s0, 2)) ^ | |
539 Td2(byte(s3, 1)) ^ | |
540 Td3(byte(s2, 0)) ^ | |
541 rk[5]; | |
542 t2 = | |
543 Td0(byte(s2, 3)) ^ | |
544 Td1(byte(s1, 2)) ^ | |
545 Td2(byte(s0, 1)) ^ | |
546 Td3(byte(s3, 0)) ^ | |
547 rk[6]; | |
548 t3 = | |
549 Td0(byte(s3, 3)) ^ | |
550 Td1(byte(s2, 2)) ^ | |
551 Td2(byte(s1, 1)) ^ | |
552 Td3(byte(s0, 0)) ^ | |
553 rk[7]; | |
554 | |
555 rk += 8; | |
556 if (--r == 0) { | |
557 break; | |
558 } | |
559 | |
560 | |
561 s0 = | |
562 Td0(byte(t0, 3)) ^ | |
563 Td1(byte(t3, 2)) ^ | |
564 Td2(byte(t2, 1)) ^ | |
565 Td3(byte(t1, 0)) ^ | |
566 rk[0]; | |
567 s1 = | |
568 Td0(byte(t1, 3)) ^ | |
569 Td1(byte(t0, 2)) ^ | |
570 Td2(byte(t3, 1)) ^ | |
571 Td3(byte(t2, 0)) ^ | |
572 rk[1]; | |
573 s2 = | |
574 Td0(byte(t2, 3)) ^ | |
575 Td1(byte(t1, 2)) ^ | |
576 Td2(byte(t0, 1)) ^ | |
577 Td3(byte(t3, 0)) ^ | |
578 rk[2]; | |
579 s3 = | |
580 Td0(byte(t3, 3)) ^ | |
581 Td1(byte(t2, 2)) ^ | |
582 Td2(byte(t1, 1)) ^ | |
583 Td3(byte(t0, 0)) ^ | |
584 rk[3]; | |
585 } | |
586 #endif | |
587 | |
588 /* | |
589 * apply last round and | |
590 * map cipher state to byte array block: | |
591 */ | |
592 s0 = | |
593 (Td4[byte(t0, 3)] & 0xff000000) ^ | |
594 (Td4[byte(t3, 2)] & 0x00ff0000) ^ | |
595 (Td4[byte(t2, 1)] & 0x0000ff00) ^ | |
596 (Td4[byte(t1, 0)] & 0x000000ff) ^ | |
597 rk[0]; | |
598 STORE32H(s0, pt); | |
599 s1 = | |
600 (Td4[byte(t1, 3)] & 0xff000000) ^ | |
601 (Td4[byte(t0, 2)] & 0x00ff0000) ^ | |
602 (Td4[byte(t3, 1)] & 0x0000ff00) ^ | |
603 (Td4[byte(t2, 0)] & 0x000000ff) ^ | |
604 rk[1]; | |
605 STORE32H(s1, pt+4); | |
606 s2 = | |
607 (Td4[byte(t2, 3)] & 0xff000000) ^ | |
608 (Td4[byte(t1, 2)] & 0x00ff0000) ^ | |
609 (Td4[byte(t0, 1)] & 0x0000ff00) ^ | |
610 (Td4[byte(t3, 0)] & 0x000000ff) ^ | |
611 rk[2]; | |
612 STORE32H(s2, pt+8); | |
613 s3 = | |
614 (Td4[byte(t3, 3)] & 0xff000000) ^ | |
615 (Td4[byte(t2, 2)] & 0x00ff0000) ^ | |
616 (Td4[byte(t1, 1)] & 0x0000ff00) ^ | |
617 (Td4[byte(t0, 0)] & 0x000000ff) ^ | |
618 rk[3]; | |
619 STORE32H(s3, pt+12); | |
620 } | |
621 | |
622 | |
623 #ifdef LTC_CLEAN_STACK | |
624 void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | |
625 { | |
626 _rijndael_ecb_decrypt(ct, pt, skey); | |
627 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | |
628 } | |
629 #endif | |
630 | |
631 /** | |
632 Performs a self-test of the AES block cipher | |
633 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled | |
634 */ | |
635 int ECB_TEST(void) | |
636 { | |
637 #ifndef LTC_TEST | |
638 return CRYPT_NOP; | |
639 #else | |
640 int err; | |
641 static const struct { | |
642 int keylen; | |
643 unsigned char key[32], pt[16], ct[16]; | |
644 } tests[] = { | |
645 { 16, | |
646 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
647 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, | |
648 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | |
649 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, | |
650 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, | |
651 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } | |
652 }, { | |
653 24, | |
654 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
655 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | |
656 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, | |
657 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | |
658 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, | |
659 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, | |
660 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } | |
661 }, { | |
662 32, | |
663 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
664 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | |
665 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | |
666 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, | |
667 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | |
668 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, | |
669 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, | |
670 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } | |
671 } | |
672 }; | |
673 | |
674 symmetric_key key; | |
675 unsigned char tmp[2][16]; | |
676 int i, y; | |
677 | |
678 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { | |
679 zeromem(&key, sizeof(key)); | |
680 if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { | |
681 return err; | |
682 } | |
683 | |
684 rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); | |
685 rijndael_ecb_decrypt(tmp[0], tmp[1], &key); | |
686 if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { | |
687 #if 0 | |
688 printf("\n\nTest %d failed\n", i); | |
689 if (memcmp(tmp[0], tests[i].ct, 16)) { | |
690 printf("CT: "); | |
691 for (i = 0; i < 16; i++) { | |
692 printf("%02x ", tmp[0][i]); | |
693 } | |
694 printf("\n"); | |
695 } else { | |
696 printf("PT: "); | |
697 for (i = 0; i < 16; i++) { | |
698 printf("%02x ", tmp[1][i]); | |
699 } | |
700 printf("\n"); | |
701 } | |
702 #endif | |
703 return CRYPT_FAIL_TESTVECTOR; | |
704 } | |
705 | |
706 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
707 for (y = 0; y < 16; y++) tmp[0][y] = 0; | |
708 for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); | |
709 for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); | |
710 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
711 } | |
712 return CRYPT_OK; | |
713 #endif | |
714 } | |
715 | |
716 #endif /* ENCRYPT_ONLY */ | |
717 | |
718 | |
719 /** Terminate the context | |
720 @param skey The scheduled key | |
721 */ | |
722 void ECB_DONE(symmetric_key *skey) | |
723 { | |
724 } | |
725 | |
726 | |
727 /** | |
728 Gets suitable key size | |
729 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. | |
730 @return CRYPT_OK if the input key size is acceptable. | |
731 */ | |
732 int ECB_KS(int *keysize) | |
733 { | |
734 LTC_ARGCHK(keysize != NULL); | |
735 | |
736 if (*keysize < 16) | |
737 return CRYPT_INVALID_KEYSIZE; | |
738 if (*keysize < 24) { | |
739 *keysize = 16; | |
740 return CRYPT_OK; | |
741 } else if (*keysize < 32) { | |
742 *keysize = 24; | |
743 return CRYPT_OK; | |
744 } else { | |
745 *keysize = 32; | |
746 return CRYPT_OK; | |
747 } | |
748 } | |
749 | |
750 #endif | |
751 | |
752 | |
753 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */ | |
754 /* $Revision: 1.8 $ */ | |
755 /* $Date: 2005/05/05 14:35:58 $ */ |