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