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