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