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