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