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