Mercurial > dropbear
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 |