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