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