comparison aes.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children 6362d3854bb4
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
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 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11
12 /* AES implementation by Tom St Denis
13 *
14 * Derived from the Public Domain source code by
15
16 ---
17 * rijndael-alg-fst.c
18 *
19 * @version 3.0 (December 2000)
20 *
21 * Optimised ANSI C code for the Rijndael cipher (now AES)
22 *
23 * @author Vincent Rijmen <[email protected]>
24 * @author Antoon Bosselaers <[email protected]>
25 * @author Paulo Barreto <[email protected]>
26 ---
27 */
28
29 #include "mycrypt.h"
30
31 #ifdef RIJNDAEL
32
33 const struct _cipher_descriptor rijndael_desc =
34 {
35 "rijndael",
36 6,
37 16, 32, 16, 10,
38 &rijndael_setup,
39 &rijndael_ecb_encrypt,
40 &rijndael_ecb_decrypt,
41 &rijndael_test,
42 &rijndael_keysize
43 };
44
45 const struct _cipher_descriptor aes_desc =
46 {
47 "aes",
48 6,
49 16, 32, 16, 10,
50 &rijndael_setup,
51 &rijndael_ecb_encrypt,
52 &rijndael_ecb_decrypt,
53 &rijndael_test,
54 &rijndael_keysize
55 };
56
57 #include "aes_tab.c"
58
59 int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
60 {
61 int i, j;
62 ulong32 temp, *rk, *rrk;
63
64 _ARGCHK(key != NULL);
65 _ARGCHK(skey != NULL);
66
67 if (keylen != 16 && keylen != 24 && keylen != 32) {
68 return CRYPT_INVALID_KEYSIZE;
69 }
70
71 if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) {
72 return CRYPT_INVALID_ROUNDS;
73 }
74
75 skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
76
77 /* setup the forward key */
78 i = 0;
79 rk = skey->rijndael.eK;
80 LOAD32H(rk[0], key );
81 LOAD32H(rk[1], key + 4);
82 LOAD32H(rk[2], key + 8);
83 LOAD32H(rk[3], key + 12);
84 if (keylen == 16) {
85 j = 44;
86 for (;;) {
87 temp = rk[3];
88 rk[4] = rk[0] ^
89 (Te4_3[byte(temp, 2)]) ^
90 (Te4_2[byte(temp, 1)]) ^
91 (Te4_1[byte(temp, 0)]) ^
92 (Te4_0[byte(temp, 3)]) ^
93 rcon[i];
94 rk[5] = rk[1] ^ rk[4];
95 rk[6] = rk[2] ^ rk[5];
96 rk[7] = rk[3] ^ rk[6];
97 if (++i == 10) {
98 break;
99 }
100 rk += 4;
101 }
102 } else if (keylen == 24) {
103 j = 52;
104 LOAD32H(rk[4], key + 16);
105 LOAD32H(rk[5], key + 20);
106 for (;;) {
107 #ifdef _MSC_VER
108 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
109 #else
110 temp = rk[5];
111 #endif
112 rk[ 6] = rk[ 0] ^
113 (Te4_3[byte(temp, 2)]) ^
114 (Te4_2[byte(temp, 1)]) ^
115 (Te4_1[byte(temp, 0)]) ^
116 (Te4_0[byte(temp, 3)]) ^
117 rcon[i];
118 rk[ 7] = rk[ 1] ^ rk[ 6];
119 rk[ 8] = rk[ 2] ^ rk[ 7];
120 rk[ 9] = rk[ 3] ^ rk[ 8];
121 if (++i == 8) {
122 break;
123 }
124 rk[10] = rk[ 4] ^ rk[ 9];
125 rk[11] = rk[ 5] ^ rk[10];
126 rk += 6;
127 }
128 } else if (keylen == 32) {
129 j = 60;
130 LOAD32H(rk[4], key + 16);
131 LOAD32H(rk[5], key + 20);
132 LOAD32H(rk[6], key + 24);
133 LOAD32H(rk[7], key + 28);
134 for (;;) {
135 #ifdef _MSC_VER
136 temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
137 #else
138 temp = rk[7];
139 #endif
140 rk[ 8] = rk[ 0] ^
141 (Te4_3[byte(temp, 2)]) ^
142 (Te4_2[byte(temp, 1)]) ^
143 (Te4_1[byte(temp, 0)]) ^
144 (Te4_0[byte(temp, 3)]) ^
145 rcon[i];
146 rk[ 9] = rk[ 1] ^ rk[ 8];
147 rk[10] = rk[ 2] ^ rk[ 9];
148 rk[11] = rk[ 3] ^ rk[10];
149 if (++i == 7) {
150 break;
151 }
152 temp = rk[11];
153 rk[12] = rk[ 4] ^
154 (Te4_3[byte(temp, 3)]) ^
155 (Te4_2[byte(temp, 2)]) ^
156 (Te4_1[byte(temp, 1)]) ^
157 (Te4_0[byte(temp, 0)]);
158 rk[13] = rk[ 5] ^ rk[12];
159 rk[14] = rk[ 6] ^ rk[13];
160 rk[15] = rk[ 7] ^ rk[14];
161 rk += 8;
162 }
163 } else {
164 /* this can't happen */
165 j = 4;
166 }
167
168 /* setup the inverse key now */
169 rk = skey->rijndael.dK;
170 rrk = skey->rijndael.eK + j - 4;
171
172 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
173 /* copy first */
174 *rk++ = *rrk++;
175 *rk++ = *rrk++;
176 *rk++ = *rrk++;
177 *rk = *rrk;
178 rk -= 3; rrk -= 3;
179
180 for (i = 1; i < skey->rijndael.Nr; i++) {
181 rrk -= 4;
182 rk += 4;
183 #ifdef SMALL_CODE
184 temp = rrk[0];
185 rk[0] =
186 Td0(255 & Te4[byte(temp, 3)]) ^
187 Td1(255 & Te4[byte(temp, 2)]) ^
188 Td2(255 & Te4[byte(temp, 1)]) ^
189 Td3(255 & Te4[byte(temp, 0)]);
190 temp = rrk[1];
191 rk[1] =
192 Td0(255 & Te4[byte(temp, 3)]) ^
193 Td1(255 & Te4[byte(temp, 2)]) ^
194 Td2(255 & Te4[byte(temp, 1)]) ^
195 Td3(255 & Te4[byte(temp, 0)]);
196 temp = rrk[2];
197 rk[2] =
198 Td0(255 & Te4[byte(temp, 3)]) ^
199 Td1(255 & Te4[byte(temp, 2)]) ^
200 Td2(255 & Te4[byte(temp, 1)]) ^
201 Td3(255 & Te4[byte(temp, 0)]);
202 temp = rrk[3];
203 rk[3] =
204 Td0(255 & Te4[byte(temp, 3)]) ^
205 Td1(255 & Te4[byte(temp, 2)]) ^
206 Td2(255 & Te4[byte(temp, 1)]) ^
207 Td3(255 & Te4[byte(temp, 0)]);
208 #else
209 temp = rrk[0];
210 rk[0] =
211 Tks0[byte(temp, 3)] ^
212 Tks1[byte(temp, 2)] ^
213 Tks2[byte(temp, 1)] ^
214 Tks3[byte(temp, 0)];
215 temp = rrk[1];
216 rk[1] =
217 Tks0[byte(temp, 3)] ^
218 Tks1[byte(temp, 2)] ^
219 Tks2[byte(temp, 1)] ^
220 Tks3[byte(temp, 0)];
221 temp = rrk[2];
222 rk[2] =
223 Tks0[byte(temp, 3)] ^
224 Tks1[byte(temp, 2)] ^
225 Tks2[byte(temp, 1)] ^
226 Tks3[byte(temp, 0)];
227 temp = rrk[3];
228 rk[3] =
229 Tks0[byte(temp, 3)] ^
230 Tks1[byte(temp, 2)] ^
231 Tks2[byte(temp, 1)] ^
232 Tks3[byte(temp, 0)];
233 #endif
234
235 }
236
237 /* copy last */
238 rrk -= 4;
239 rk += 4;
240 *rk++ = *rrk++;
241 *rk++ = *rrk++;
242 *rk++ = *rrk++;
243 *rk = *rrk;
244
245 return CRYPT_OK;
246 }
247
248 #ifdef CLEAN_STACK
249 static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
250 #else
251 void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
252 #endif
253 {
254 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
255 int Nr, r;
256
257 _ARGCHK(pt != NULL);
258 _ARGCHK(ct != NULL);
259 _ARGCHK(skey != NULL);
260
261 Nr = skey->rijndael.Nr;
262 rk = skey->rijndael.eK;
263
264 /*
265 * map byte array block to cipher state
266 * and add initial round key:
267 */
268 LOAD32H(s0, pt ); s0 ^= rk[0];
269 LOAD32H(s1, pt + 4); s1 ^= rk[1];
270 LOAD32H(s2, pt + 8); s2 ^= rk[2];
271 LOAD32H(s3, pt + 12); s3 ^= rk[3];
272
273 /*
274 * Nr - 1 full rounds:
275 */
276 r = Nr >> 1;
277 for (;;) {
278 t0 =
279 Te0(byte(s0, 3)) ^
280 Te1(byte(s1, 2)) ^
281 Te2(byte(s2, 1)) ^
282 Te3(byte(s3, 0)) ^
283 rk[4];
284 t1 =
285 Te0(byte(s1, 3)) ^
286 Te1(byte(s2, 2)) ^
287 Te2(byte(s3, 1)) ^
288 Te3(byte(s0, 0)) ^
289 rk[5];
290 t2 =
291 Te0(byte(s2, 3)) ^
292 Te1(byte(s3, 2)) ^
293 Te2(byte(s0, 1)) ^
294 Te3(byte(s1, 0)) ^
295 rk[6];
296 t3 =
297 Te0(byte(s3, 3)) ^
298 Te1(byte(s0, 2)) ^
299 Te2(byte(s1, 1)) ^
300 Te3(byte(s2, 0)) ^
301 rk[7];
302
303 rk += 8;
304 if (--r == 0) {
305 break;
306 }
307
308 s0 =
309 Te0(byte(t0, 3)) ^
310 Te1(byte(t1, 2)) ^
311 Te2(byte(t2, 1)) ^
312 Te3(byte(t3, 0)) ^
313 rk[0];
314 s1 =
315 Te0(byte(t1, 3)) ^
316 Te1(byte(t2, 2)) ^
317 Te2(byte(t3, 1)) ^
318 Te3(byte(t0, 0)) ^
319 rk[1];
320 s2 =
321 Te0(byte(t2, 3)) ^
322 Te1(byte(t3, 2)) ^
323 Te2(byte(t0, 1)) ^
324 Te3(byte(t1, 0)) ^
325 rk[2];
326 s3 =
327 Te0(byte(t3, 3)) ^
328 Te1(byte(t0, 2)) ^
329 Te2(byte(t1, 1)) ^
330 Te3(byte(t2, 0)) ^
331 rk[3];
332 }
333 /*
334 * apply last round and
335 * map cipher state to byte array block:
336 */
337 s0 =
338 (Te4_3[(t0 >> 24) ]) ^
339 (Te4_2[(t1 >> 16) & 0xff]) ^
340 (Te4_1[(t2 >> 8) & 0xff]) ^
341 (Te4_0[(t3 ) & 0xff]) ^
342 rk[0];
343 STORE32H(s0, ct);
344 s1 =
345 (Te4_3[(t1 >> 24) ]) ^
346 (Te4_2[(t2 >> 16) & 0xff]) ^
347 (Te4_1[(t3 >> 8) & 0xff]) ^
348 (Te4_0[(t0 ) & 0xff]) ^
349 rk[1];
350 STORE32H(s1, ct+4);
351 s2 =
352 (Te4_3[(t2 >> 24) ]) ^
353 (Te4_2[(t3 >> 16) & 0xff]) ^
354 (Te4_1[(t0 >> 8) & 0xff]) ^
355 (Te4_0[(t1 ) & 0xff]) ^
356 rk[2];
357 STORE32H(s2, ct+8);
358 s3 =
359 (Te4_3[(t3 >> 24) ]) ^
360 (Te4_2[(t0 >> 16) & 0xff]) ^
361 (Te4_1[(t1 >> 8) & 0xff]) ^
362 (Te4_0[(t2 ) & 0xff]) ^
363 rk[3];
364 STORE32H(s3, ct+12);
365 }
366
367 #ifdef CLEAN_STACK
368 void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
369 {
370 _rijndael_ecb_encrypt(pt, ct, skey);
371 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
372 }
373 #endif
374
375 #ifdef CLEAN_STACK
376 static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
377 #else
378 void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
379 #endif
380 {
381 ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
382 int Nr, r;
383
384 _ARGCHK(pt != NULL);
385 _ARGCHK(ct != NULL);
386 _ARGCHK(skey != NULL);
387
388 Nr = skey->rijndael.Nr;
389 rk = skey->rijndael.dK;
390
391 /*
392 * map byte array block to cipher state
393 * and add initial round key:
394 */
395 LOAD32H(s0, ct ); s0 ^= rk[0];
396 LOAD32H(s1, ct + 4); s1 ^= rk[1];
397 LOAD32H(s2, ct + 8); s2 ^= rk[2];
398 LOAD32H(s3, ct + 12); s3 ^= rk[3];
399
400 /*
401 * Nr - 1 full rounds:
402 */
403 r = Nr >> 1;
404 for (;;) {
405
406 t0 =
407 Td0(byte(s0, 3)) ^
408 Td1(byte(s3, 2)) ^
409 Td2(byte(s2, 1)) ^
410 Td3(byte(s1, 0)) ^
411 rk[4];
412 t1 =
413 Td0(byte(s1, 3)) ^
414 Td1(byte(s0, 2)) ^
415 Td2(byte(s3, 1)) ^
416 Td3(byte(s2, 0)) ^
417 rk[5];
418 t2 =
419 Td0(byte(s2, 3)) ^
420 Td1(byte(s1, 2)) ^
421 Td2(byte(s0, 1)) ^
422 Td3(byte(s3, 0)) ^
423 rk[6];
424 t3 =
425 Td0(byte(s3, 3)) ^
426 Td1(byte(s2, 2)) ^
427 Td2(byte(s1, 1)) ^
428 Td3(byte(s0, 0)) ^
429 rk[7];
430
431 rk += 8;
432 if (--r == 0) {
433 break;
434 }
435
436
437 s0 =
438 Td0(byte(t0, 3)) ^
439 Td1(byte(t3, 2)) ^
440 Td2(byte(t2, 1)) ^
441 Td3(byte(t1, 0)) ^
442 rk[0];
443 s1 =
444 Td0(byte(t1, 3)) ^
445 Td1(byte(t0, 2)) ^
446 Td2(byte(t3, 1)) ^
447 Td3(byte(t2, 0)) ^
448 rk[1];
449 s2 =
450 Td0(byte(t2, 3)) ^
451 Td1(byte(t1, 2)) ^
452 Td2(byte(t0, 1)) ^
453 Td3(byte(t3, 0)) ^
454 rk[2];
455 s3 =
456 Td0(byte(t3, 3)) ^
457 Td1(byte(t2, 2)) ^
458 Td2(byte(t1, 1)) ^
459 Td3(byte(t0, 0)) ^
460 rk[3];
461 }
462
463 /*
464 * apply last round and
465 * map cipher state to byte array block:
466 */
467 s0 =
468 (Td4[(t0 >> 24) ] & 0xff000000) ^
469 (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
470 (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
471 (Td4[(t1 ) & 0xff] & 0x000000ff) ^
472 rk[0];
473 STORE32H(s0, pt);
474 s1 =
475 (Td4[(t1 >> 24) ] & 0xff000000) ^
476 (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
477 (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
478 (Td4[(t2 ) & 0xff] & 0x000000ff) ^
479 rk[1];
480 STORE32H(s1, pt+4);
481 s2 =
482 (Td4[(t2 >> 24) ] & 0xff000000) ^
483 (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
484 (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
485 (Td4[(t3 ) & 0xff] & 0x000000ff) ^
486 rk[2];
487 STORE32H(s2, pt+8);
488 s3 =
489 (Td4[(t3 >> 24) ] & 0xff000000) ^
490 (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
491 (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
492 (Td4[(t0 ) & 0xff] & 0x000000ff) ^
493 rk[3];
494 STORE32H(s3, pt+12);
495 }
496
497
498 #ifdef CLEAN_STACK
499 void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
500 {
501 _rijndael_ecb_decrypt(ct, pt, skey);
502 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
503 }
504 #endif
505
506 int rijndael_test(void)
507 {
508 #ifndef LTC_TEST
509 return CRYPT_NOP;
510 #else
511 int err;
512 static const struct {
513 int keylen;
514 unsigned char key[32], pt[16], ct[16];
515 } tests[] = {
516 { 16,
517 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
518 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
519 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
520 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
521 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
522 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
523 }, {
524 24,
525 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
526 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
527 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
528 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
529 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
530 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
531 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
532 }, {
533 32,
534 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
535 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
536 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
537 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
538 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
539 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
540 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
541 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
542 }
543 };
544
545 symmetric_key key;
546 unsigned char tmp[2][16];
547 int i, y;
548
549 for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
550 zeromem(&key, sizeof(key));
551 if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
552 return err;
553 }
554
555 rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
556 rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
557 if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
558 #if 0
559 printf("\n\nTest %d failed\n", i);
560 if (memcmp(tmp[0], tests[i].ct, 16)) {
561 printf("CT: ");
562 for (i = 0; i < 16; i++) {
563 printf("%02x ", tmp[0][i]);
564 }
565 printf("\n");
566 } else {
567 printf("PT: ");
568 for (i = 0; i < 16; i++) {
569 printf("%02x ", tmp[1][i]);
570 }
571 printf("\n");
572 }
573 #endif
574 return CRYPT_FAIL_TESTVECTOR;
575 }
576
577 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
578 for (y = 0; y < 16; y++) tmp[0][y] = 0;
579 for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
580 for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
581 for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
582 }
583 return CRYPT_OK;
584 #endif
585 }
586
587 int rijndael_keysize(int *desired_keysize)
588 {
589 _ARGCHK(desired_keysize != NULL);
590
591 if (*desired_keysize < 16)
592 return CRYPT_INVALID_KEYSIZE;
593 if (*desired_keysize < 24) {
594 *desired_keysize = 16;
595 return CRYPT_OK;
596 } else if (*desired_keysize < 32) {
597 *desired_keysize = 24;
598 return CRYPT_OK;
599 } else {
600 *desired_keysize = 32;
601 return CRYPT_OK;
602 }
603 }
604
605 #endif
606