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, tomstdenis@gmail.com, http://libtomcrypt.com
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 <vincent.rijmen@esat.kuleuven.ac.be>
24 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
25 * @author Paulo Barreto <paulo.barreto@terra.com.br>
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, 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, 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, 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, NULL, NULL, NULL, NULL, NULL
89 };
90
91 #endif
92
93 #include "aes_tab.c"
94
setup_mix(ulong32 temp)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
setup_mix2(ulong32 temp)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 */
SETUP(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)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 @return CRYPT_OK if successful
287 */
288 #ifdef LTC_CLEAN_STACK
_rijndael_ecb_encrypt(const unsigned char * pt,unsigned char * ct,symmetric_key * skey)289 static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
290 #else
291 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
292 #endif
293 {
294 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
295 int Nr, r;
296
297 LTC_ARGCHK(pt != NULL);
298 LTC_ARGCHK(ct != NULL);
299 LTC_ARGCHK(skey != NULL);
300
301 Nr = skey->rijndael.Nr;
302 rk = skey->rijndael.eK;
303
304 /*
305 * map byte array block to cipher state
306 * and add initial round key:
307 */
308 LOAD32H(s0, pt ); s0 ^= rk[0];
309 LOAD32H(s1, pt + 4); s1 ^= rk[1];
310 LOAD32H(s2, pt + 8); s2 ^= rk[2];
311 LOAD32H(s3, pt + 12); s3 ^= rk[3];
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 return CRYPT_OK;
447 }
448
449 #ifdef LTC_CLEAN_STACK
ECB_ENC(const unsigned char * pt,unsigned char * ct,symmetric_key * skey)450 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
451 {
452 int err = _rijndael_ecb_encrypt(pt, ct, skey);
453 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
454 return err;
455 }
456 #endif
457
458 #ifndef ENCRYPT_ONLY
459
460 /**
461 Decrypts a block of text with AES
462 @param ct The input ciphertext (16 bytes)
463 @param pt The output plaintext (16 bytes)
464 @param skey The key as scheduled
465 @return CRYPT_OK if successful
466 */
467 #ifdef LTC_CLEAN_STACK
_rijndael_ecb_decrypt(const unsigned char * ct,unsigned char * pt,symmetric_key * skey)468 static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
469 #else
470 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
471 #endif
472 {
473 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
474 int Nr, r;
475
476 LTC_ARGCHK(pt != NULL);
477 LTC_ARGCHK(ct != NULL);
478 LTC_ARGCHK(skey != NULL);
479
480 Nr = skey->rijndael.Nr;
481 rk = skey->rijndael.dK;
482
483 /*
484 * map byte array block to cipher state
485 * and add initial round key:
486 */
487 LOAD32H(s0, ct ); s0 ^= rk[0];
488 LOAD32H(s1, ct + 4); s1 ^= rk[1];
489 LOAD32H(s2, ct + 8); s2 ^= rk[2];
490 LOAD32H(s3, ct + 12); s3 ^= rk[3];
491
492 #ifdef LTC_SMALL_CODE
493 for (r = 0; ; r++) {
494 rk += 4;
495 t0 =
496 Td0(byte(s0, 3)) ^
497 Td1(byte(s3, 2)) ^
498 Td2(byte(s2, 1)) ^
499 Td3(byte(s1, 0)) ^
500 rk[0];
501 t1 =
502 Td0(byte(s1, 3)) ^
503 Td1(byte(s0, 2)) ^
504 Td2(byte(s3, 1)) ^
505 Td3(byte(s2, 0)) ^
506 rk[1];
507 t2 =
508 Td0(byte(s2, 3)) ^
509 Td1(byte(s1, 2)) ^
510 Td2(byte(s0, 1)) ^
511 Td3(byte(s3, 0)) ^
512 rk[2];
513 t3 =
514 Td0(byte(s3, 3)) ^
515 Td1(byte(s2, 2)) ^
516 Td2(byte(s1, 1)) ^
517 Td3(byte(s0, 0)) ^
518 rk[3];
519 if (r == Nr-2) {
520 break;
521 }
522 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
523 }
524 rk += 4;
525
526 #else
527
528 /*
529 * Nr - 1 full rounds:
530 */
531 r = Nr >> 1;
532 for (;;) {
533
534 t0 =
535 Td0(byte(s0, 3)) ^
536 Td1(byte(s3, 2)) ^
537 Td2(byte(s2, 1)) ^
538 Td3(byte(s1, 0)) ^
539 rk[4];
540 t1 =
541 Td0(byte(s1, 3)) ^
542 Td1(byte(s0, 2)) ^
543 Td2(byte(s3, 1)) ^
544 Td3(byte(s2, 0)) ^
545 rk[5];
546 t2 =
547 Td0(byte(s2, 3)) ^
548 Td1(byte(s1, 2)) ^
549 Td2(byte(s0, 1)) ^
550 Td3(byte(s3, 0)) ^
551 rk[6];
552 t3 =
553 Td0(byte(s3, 3)) ^
554 Td1(byte(s2, 2)) ^
555 Td2(byte(s1, 1)) ^
556 Td3(byte(s0, 0)) ^
557 rk[7];
558
559 rk += 8;
560 if (--r == 0) {
561 break;
562 }
563
564
565 s0 =
566 Td0(byte(t0, 3)) ^
567 Td1(byte(t3, 2)) ^
568 Td2(byte(t2, 1)) ^
569 Td3(byte(t1, 0)) ^
570 rk[0];
571 s1 =
572 Td0(byte(t1, 3)) ^
573 Td1(byte(t0, 2)) ^
574 Td2(byte(t3, 1)) ^
575 Td3(byte(t2, 0)) ^
576 rk[1];
577 s2 =
578 Td0(byte(t2, 3)) ^
579 Td1(byte(t1, 2)) ^
580 Td2(byte(t0, 1)) ^
581 Td3(byte(t3, 0)) ^
582 rk[2];
583 s3 =
584 Td0(byte(t3, 3)) ^
585 Td1(byte(t2, 2)) ^
586 Td2(byte(t1, 1)) ^
587 Td3(byte(t0, 0)) ^
588 rk[3];
589 }
590 #endif
591
592 /*
593 * apply last round and
594 * map cipher state to byte array block:
595 */
596 s0 =
597 (Td4[byte(t0, 3)] & 0xff000000) ^
598 (Td4[byte(t3, 2)] & 0x00ff0000) ^
599 (Td4[byte(t2, 1)] & 0x0000ff00) ^
600 (Td4[byte(t1, 0)] & 0x000000ff) ^
601 rk[0];
602 STORE32H(s0, pt);
603 s1 =
604 (Td4[byte(t1, 3)] & 0xff000000) ^
605 (Td4[byte(t0, 2)] & 0x00ff0000) ^
606 (Td4[byte(t3, 1)] & 0x0000ff00) ^
607 (Td4[byte(t2, 0)] & 0x000000ff) ^
608 rk[1];
609 STORE32H(s1, pt+4);
610 s2 =
611 (Td4[byte(t2, 3)] & 0xff000000) ^
612 (Td4[byte(t1, 2)] & 0x00ff0000) ^
613 (Td4[byte(t0, 1)] & 0x0000ff00) ^
614 (Td4[byte(t3, 0)] & 0x000000ff) ^
615 rk[2];
616 STORE32H(s2, pt+8);
617 s3 =
618 (Td4[byte(t3, 3)] & 0xff000000) ^
619 (Td4[byte(t2, 2)] & 0x00ff0000) ^
620 (Td4[byte(t1, 1)] & 0x0000ff00) ^
621 (Td4[byte(t0, 0)] & 0x000000ff) ^
622 rk[3];
623 STORE32H(s3, pt+12);
624
625 return CRYPT_OK;
626 }
627
628
629 #ifdef LTC_CLEAN_STACK
ECB_DEC(const unsigned char * ct,unsigned char * pt,symmetric_key * skey)630 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
631 {
632 int err = _rijndael_ecb_decrypt(ct, pt, skey);
633 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
634 return err;
635 }
636 #endif
637
638 /**
639 Performs a self-test of the AES block cipher
640 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
641 */
ECB_TEST(void)642 int ECB_TEST(void)
643 {
644 #ifndef LTC_TEST
645 return CRYPT_NOP;
646 #else
647 int err;
648 static const struct {
649 int keylen;
650 unsigned char key[32], pt[16], ct[16];
651 } tests[] = {
652 { 16,
653 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
654 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
655 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
656 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
657 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
658 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
659 }, {
660 24,
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 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
665 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
666 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
667 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
668 }, {
669 32,
670 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
671 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
672 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
673 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
674 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
675 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
676 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
677 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
678 }
679 };
680
681 symmetric_key key;
682 unsigned char tmp[2][16];
683 int i, y;
684
685 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
686 zeromem(&key, sizeof(key));
687 if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
688 return err;
689 }
690
691 rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
692 rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
693 if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
694 #if 0
695 printf("\n\nTest %d failed\n", i);
696 if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
697 printf("CT: ");
698 for (i = 0; i < 16; i++) {
699 printf("%02x ", tmp[0][i]);
700 }
701 printf("\n");
702 } else {
703 printf("PT: ");
704 for (i = 0; i < 16; i++) {
705 printf("%02x ", tmp[1][i]);
706 }
707 printf("\n");
708 }
709 #endif
710 return CRYPT_FAIL_TESTVECTOR;
711 }
712
713 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
714 for (y = 0; y < 16; y++) tmp[0][y] = 0;
715 for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
716 for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
717 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
718 }
719 return CRYPT_OK;
720 #endif
721 }
722
723 #endif /* ENCRYPT_ONLY */
724
725
726 /** Terminate the context
727 @param skey The scheduled key
728 */
ECB_DONE(symmetric_key * skey)729 void ECB_DONE(symmetric_key *skey)
730 {
731 }
732
733
734 /**
735 Gets suitable key size
736 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
737 @return CRYPT_OK if the input key size is acceptable.
738 */
ECB_KS(int * keysize)739 int ECB_KS(int *keysize)
740 {
741 LTC_ARGCHK(keysize != NULL);
742
743 if (*keysize < 16)
744 return CRYPT_INVALID_KEYSIZE;
745 if (*keysize < 24) {
746 *keysize = 16;
747 return CRYPT_OK;
748 } else if (*keysize < 32) {
749 *keysize = 24;
750 return CRYPT_OK;
751 } else {
752 *keysize = 32;
753 return CRYPT_OK;
754 }
755 }
756
757 #endif
758
759
760 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */
761 /* $Revision: 1.14 $ */
762 /* $Date: 2006/11/08 23:01:06 $ */
763