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