comparison src/ciphers/aes/aes.c @ 192:9cc34777b479 libtomcrypt

propagate from branch 'au.asn.ucc.matt.ltc-orig' (head 9ba8f01f44320e9cb9f19881105ae84f84a43ea9) to branch 'au.asn.ucc.matt.dropbear.ltc' (head dbf51c569bc34956ad948e4cc87a0eeb2170b768)
author Matt Johnston <matt@ucc.asn.au>
date Sun, 08 May 2005 06:36:47 +0000
parents 1c15b283127b
children 4768b55c5240
comparison
equal deleted inserted replaced
164:cd1143579f00 192:9cc34777b479
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