2 ---------------------------------------------------------------------------
3 Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
7 The free distribution and use of this software is allowed (with or without
8 changes) provided that:
10 1. source code distributions include the above copyright notice, this
11 list of conditions and the following disclaimer;
13 2. binary distributions include the above copyright notice, this list
14 of conditions and the following disclaimer in their documentation;
16 3. the name of the copyright holder is not used to endorse products
17 built using this software without specific written permission.
21 This software is provided 'as is' with no explicit or implied warranties
22 in respect of its properties, including, but not limited to, correctness
23 and/or fitness for purpose.
24 ---------------------------------------------------------------------------
25 Issue Date: 20/12/2007
31 #ifdef USE_VIA_ACE_IF_PRESENT
32 # include "aes_via_ace.h"
35 #if defined(__cplusplus)
40 /* Initialise the key schedule from the user supplied key. The key
41 length can be specified in bytes, with legal values of 16, 24
42 and 32, or in bits, with legal values of 128, 192 and 256. These
43 values correspond with Nk values of 4, 6 and 8 respectively.
45 The following macros implement a single cycle in the key
46 schedule generation process. The number of cycles needed
47 for each cx->n_col and nk value is:
50 ------------------------------
51 cx->n_col = 4 10 9 8 7 7
52 cx->n_col = 5 14 11 10 9 9
53 cx->n_col = 6 19 15 12 11 11
54 cx->n_col = 7 21 19 16 13 14
55 cx->n_col = 8 29 23 19 17 14
58 #if (FUNCS_IN_C & ENC_KEYING_IN_C)
60 #if defined(AES_128) || defined(AES_VAR)
63 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
64 k[4*(i)+5] = ss[1] ^= ss[0]; \
65 k[4*(i)+6] = ss[2] ^= ss[1]; \
66 k[4*(i)+7] = ss[3] ^= ss[2]; \
69 AES_RETURN
aes_encrypt_key128(const unsigned char *key
, aes_encrypt_ctx cx
[1])
72 cx
->ks
[0] = ss
[0] = word_in(key
, 0);
73 cx
->ks
[1] = ss
[1] = word_in(key
, 1);
74 cx
->ks
[2] = ss
[2] = word_in(key
, 2);
75 cx
->ks
[3] = ss
[3] = word_in(key
, 3);
77 #if ENC_UNROLL == NONE
79 for(i
= 0; i
< 9; ++i
)
83 ke4(cx
->ks
, 0); ke4(cx
->ks
, 1);
84 ke4(cx
->ks
, 2); ke4(cx
->ks
, 3);
85 ke4(cx
->ks
, 4); ke4(cx
->ks
, 5);
86 ke4(cx
->ks
, 6); ke4(cx
->ks
, 7);
91 cx
->inf
.b
[0] = 10 * 16;
93 #ifdef USE_VIA_ACE_IF_PRESENT
98 #if defined( AES_ERR_CHK )
105 #if defined(AES_192) || defined(AES_VAR)
108 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
109 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
110 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
111 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
116 k[6*(i)+10] = ss[4] ^= ss[3]; \
117 k[6*(i)+11] = ss[5] ^= ss[4]; \
120 AES_RETURN
aes_encrypt_key192(const unsigned char *key
, aes_encrypt_ctx cx
[1])
123 cx
->ks
[0] = ss
[0] = word_in(key
, 0);
124 cx
->ks
[1] = ss
[1] = word_in(key
, 1);
125 cx
->ks
[2] = ss
[2] = word_in(key
, 2);
126 cx
->ks
[3] = ss
[3] = word_in(key
, 3);
127 cx
->ks
[4] = ss
[4] = word_in(key
, 4);
128 cx
->ks
[5] = ss
[5] = word_in(key
, 5);
130 #if ENC_UNROLL == NONE
132 for(i
= 0; i
< 7; ++i
)
136 ke6(cx
->ks
, 0); ke6(cx
->ks
, 1);
137 ke6(cx
->ks
, 2); ke6(cx
->ks
, 3);
138 ke6(cx
->ks
, 4); ke6(cx
->ks
, 5);
143 cx
->inf
.b
[0] = 12 * 16;
145 #ifdef USE_VIA_ACE_IF_PRESENT
146 if(VIA_ACE_AVAILABLE
)
150 #if defined( AES_ERR_CHK )
157 #if defined(AES_256) || defined(AES_VAR)
160 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
161 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
162 k[8*(i)+10] = ss[2] ^= ss[1]; \
163 k[8*(i)+11] = ss[3] ^= ss[2]; \
168 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
169 k[8*(i)+13] = ss[5] ^= ss[4]; \
170 k[8*(i)+14] = ss[6] ^= ss[5]; \
171 k[8*(i)+15] = ss[7] ^= ss[6]; \
174 AES_RETURN
aes_encrypt_key256(const unsigned char *key
, aes_encrypt_ctx cx
[1])
177 cx
->ks
[0] = ss
[0] = word_in(key
, 0);
178 cx
->ks
[1] = ss
[1] = word_in(key
, 1);
179 cx
->ks
[2] = ss
[2] = word_in(key
, 2);
180 cx
->ks
[3] = ss
[3] = word_in(key
, 3);
181 cx
->ks
[4] = ss
[4] = word_in(key
, 4);
182 cx
->ks
[5] = ss
[5] = word_in(key
, 5);
183 cx
->ks
[6] = ss
[6] = word_in(key
, 6);
184 cx
->ks
[7] = ss
[7] = word_in(key
, 7);
186 #if ENC_UNROLL == NONE
188 for(i
= 0; i
< 6; ++i
)
192 ke8(cx
->ks
, 0); ke8(cx
->ks
, 1);
193 ke8(cx
->ks
, 2); ke8(cx
->ks
, 3);
194 ke8(cx
->ks
, 4); ke8(cx
->ks
, 5);
198 cx
->inf
.b
[0] = 14 * 16;
200 #ifdef USE_VIA_ACE_IF_PRESENT
201 if(VIA_ACE_AVAILABLE
)
205 #if defined( AES_ERR_CHK )
214 AES_RETURN
aes_encrypt_key(const unsigned char *key
, int key_len
, aes_encrypt_ctx cx
[1])
218 #if defined( AES_ERR_CHK )
219 case 16: case 128: return aes_encrypt_key128(key
, cx
);
220 case 24: case 192: return aes_encrypt_key192(key
, cx
);
221 case 32: case 256: return aes_encrypt_key256(key
, cx
);
222 default: return EXIT_FAILURE
;
224 case 16: case 128: aes_encrypt_key128(key
, cx
); return;
225 case 24: case 192: aes_encrypt_key192(key
, cx
); return;
226 case 32: case 256: aes_encrypt_key256(key
, cx
); return;
235 #if (FUNCS_IN_C & DEC_KEYING_IN_C)
237 /* this is used to store the decryption round keys */
238 /* in forward or reverse order */
241 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
246 #if DEC_ROUND == NO_TABLES
249 #define ff(x) inv_mcol(x)
250 #if defined( dec_imvars )
251 #define d_vars dec_imvars
255 #if defined(AES_128) || defined(AES_VAR)
258 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
259 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
260 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
261 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
267 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
268 ss[1] = ss[1] ^ ss[3]; \
269 ss[2] = ss[2] ^ ss[3]; \
270 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
271 ss[i % 4] ^= ss[4]; \
272 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
273 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
274 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
275 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
279 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
280 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
281 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
282 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
283 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
284 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
288 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
289 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
290 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
291 k[v(40,(4*(i))+6)] = ss[0]; \
292 k[v(40,(4*(i))+7)] = ss[1]; \
298 { ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
299 ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
300 ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
301 ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
305 { ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
306 ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
307 ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
308 ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
309 ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
313 { ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
314 ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
315 ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
316 ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
321 AES_RETURN
aes_decrypt_key128(const unsigned char *key
, aes_decrypt_ctx cx
[1])
323 #if defined( d_vars )
326 cx
->ks
[v(40,(0))] = ss
[0] = word_in(key
, 0);
327 cx
->ks
[v(40,(1))] = ss
[1] = word_in(key
, 1);
328 cx
->ks
[v(40,(2))] = ss
[2] = word_in(key
, 2);
329 cx
->ks
[v(40,(3))] = ss
[3] = word_in(key
, 3);
331 #if DEC_UNROLL == NONE
333 for(i
= 0; i
< 10; ++i
)
335 #if !(DEC_ROUND == NO_TABLES)
336 for(i
= N_COLS
; i
< 10 * N_COLS
; ++i
)
337 cx
->ks
[i
] = inv_mcol(cx
->ks
[i
]);
341 kdf4(cx
->ks
, 0); kd4(cx
->ks
, 1);
342 kd4(cx
->ks
, 2); kd4(cx
->ks
, 3);
343 kd4(cx
->ks
, 4); kd4(cx
->ks
, 5);
344 kd4(cx
->ks
, 6); kd4(cx
->ks
, 7);
345 kd4(cx
->ks
, 8); kdl4(cx
->ks
, 9);
348 cx
->inf
.b
[0] = 10 * 16;
350 #ifdef USE_VIA_ACE_IF_PRESENT
351 if(VIA_ACE_AVAILABLE
)
355 #if defined( AES_ERR_CHK )
362 #if defined(AES_192) || defined(AES_VAR)
365 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
366 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
367 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
368 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
373 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
374 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
378 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
379 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
380 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
381 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
382 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
383 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
387 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
388 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
389 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
390 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
391 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
392 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
393 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
397 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
398 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
399 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
400 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
403 AES_RETURN
aes_decrypt_key192(const unsigned char *key
, aes_decrypt_ctx cx
[1])
405 #if defined( d_vars )
408 cx
->ks
[v(48,(0))] = ss
[0] = word_in(key
, 0);
409 cx
->ks
[v(48,(1))] = ss
[1] = word_in(key
, 1);
410 cx
->ks
[v(48,(2))] = ss
[2] = word_in(key
, 2);
411 cx
->ks
[v(48,(3))] = ss
[3] = word_in(key
, 3);
413 #if DEC_UNROLL == NONE
414 cx
->ks
[v(48,(4))] = ss
[4] = word_in(key
, 4);
415 cx
->ks
[v(48,(5))] = ss
[5] = word_in(key
, 5);
418 for(i
= 0; i
< 7; ++i
)
421 #if !(DEC_ROUND == NO_TABLES)
422 for(i
= N_COLS
; i
< 12 * N_COLS
; ++i
)
423 cx
->ks
[i
] = inv_mcol(cx
->ks
[i
]);
427 cx
->ks
[v(48,(4))] = ff(ss
[4] = word_in(key
, 4));
428 cx
->ks
[v(48,(5))] = ff(ss
[5] = word_in(key
, 5));
429 kdf6(cx
->ks
, 0); kd6(cx
->ks
, 1);
430 kd6(cx
->ks
, 2); kd6(cx
->ks
, 3);
431 kd6(cx
->ks
, 4); kd6(cx
->ks
, 5);
432 kd6(cx
->ks
, 6); kdl6(cx
->ks
, 7);
435 cx
->inf
.b
[0] = 12 * 16;
437 #ifdef USE_VIA_ACE_IF_PRESENT
438 if(VIA_ACE_AVAILABLE
)
442 #if defined( AES_ERR_CHK )
449 #if defined(AES_256) || defined(AES_VAR)
452 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
453 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
454 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
455 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
460 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
461 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
462 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
463 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
467 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
468 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
469 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
470 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
471 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
472 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
473 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
474 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
478 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
479 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
480 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
481 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
482 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
483 ss[8] = ls_box(ss[3],0); \
484 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
485 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
486 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
487 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
491 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
492 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
493 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
494 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
497 AES_RETURN
aes_decrypt_key256(const unsigned char *key
, aes_decrypt_ctx cx
[1])
499 #if defined( d_vars )
502 cx
->ks
[v(56,(0))] = ss
[0] = word_in(key
, 0);
503 cx
->ks
[v(56,(1))] = ss
[1] = word_in(key
, 1);
504 cx
->ks
[v(56,(2))] = ss
[2] = word_in(key
, 2);
505 cx
->ks
[v(56,(3))] = ss
[3] = word_in(key
, 3);
507 #if DEC_UNROLL == NONE
508 cx
->ks
[v(56,(4))] = ss
[4] = word_in(key
, 4);
509 cx
->ks
[v(56,(5))] = ss
[5] = word_in(key
, 5);
510 cx
->ks
[v(56,(6))] = ss
[6] = word_in(key
, 6);
511 cx
->ks
[v(56,(7))] = ss
[7] = word_in(key
, 7);
514 for(i
= 0; i
< 6; ++i
)
517 #if !(DEC_ROUND == NO_TABLES)
518 for(i
= N_COLS
; i
< 14 * N_COLS
; ++i
)
519 cx
->ks
[i
] = inv_mcol(cx
->ks
[i
]);
524 cx
->ks
[v(56,(4))] = ff(ss
[4] = word_in(key
, 4));
525 cx
->ks
[v(56,(5))] = ff(ss
[5] = word_in(key
, 5));
526 cx
->ks
[v(56,(6))] = ff(ss
[6] = word_in(key
, 6));
527 cx
->ks
[v(56,(7))] = ff(ss
[7] = word_in(key
, 7));
528 kdf8(cx
->ks
, 0); kd8(cx
->ks
, 1);
529 kd8(cx
->ks
, 2); kd8(cx
->ks
, 3);
530 kd8(cx
->ks
, 4); kd8(cx
->ks
, 5);
534 cx
->inf
.b
[0] = 14 * 16;
536 #ifdef USE_VIA_ACE_IF_PRESENT
537 if(VIA_ACE_AVAILABLE
)
541 #if defined( AES_ERR_CHK )
550 AES_RETURN
aes_decrypt_key(const unsigned char *key
, int key_len
, aes_decrypt_ctx cx
[1])
554 #if defined( AES_ERR_CHK )
555 case 16: case 128: return aes_decrypt_key128(key
, cx
);
556 case 24: case 192: return aes_decrypt_key192(key
, cx
);
557 case 32: case 256: return aes_decrypt_key256(key
, cx
);
558 default: return EXIT_FAILURE
;
560 case 16: case 128: aes_decrypt_key128(key
, cx
); return;
561 case 24: case 192: aes_decrypt_key192(key
, cx
); return;
562 case 32: case 256: aes_decrypt_key256(key
, cx
); return;
571 #if defined(__cplusplus)