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