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