1 /* Modified for SILC -Pekka */
2 /* Includes key scheduling in C always, and encryption and decryption in C
3 when assembler optimized version cannot be used. */
5 ---------------------------------------------------------------------------
6 Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
10 The free distribution and use of this software in both source and binary
11 form is allowed (with or without changes) provided that:
13 1. distributions of this source code include the above copyright
14 notice, this list of conditions and the following disclaimer;
16 2. distributions in binary form include the above copyright
17 notice, this list of conditions and the following disclaimer
18 in the documentation and/or other associated materials;
20 3. the copyright holder's name is not used to endorse products
21 built using this software without specific written permission.
23 ALTERNATIVELY, provided that this notice is retained in full, this product
24 may be distributed under the terms of the GNU General Public License (GPL),
25 in which case the provisions of the GPL apply INSTEAD OF those given above.
29 This software is provided 'as is' with no explicit or implied warranties
30 in respect of its properties, including, but not limited to, correctness
31 and/or fitness for purpose.
32 ---------------------------------------------------------------------------
37 #include "rijndael_internal.h"
41 * SILC Crypto API for AES
46 /* Sets the key for the cipher. */
48 SILC_CIPHER_API_SET_KEY(aes_cbc)
51 aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
53 aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
57 /* Sets IV for the cipher. */
59 SILC_CIPHER_API_SET_IV(aes_cbc)
64 /* Returns the size of the cipher context. */
66 SILC_CIPHER_API_CONTEXT_LEN(aes_cbc)
68 return sizeof(AesContext);
71 /* Encrypts with the cipher in CBC mode. Source and destination buffers
72 maybe one and same. */
74 SILC_CIPHER_API_ENCRYPT(aes_cbc)
77 SilcUInt32 tmp[4], tmp2[4];
79 SILC_ASSERT((len & (16 - 1)) == 0);
84 SILC_GET32_MSB(tmp[0], &iv[0]);
85 SILC_GET32_MSB(tmp[1], &iv[4]);
86 SILC_GET32_MSB(tmp[2], &iv[8]);
87 SILC_GET32_MSB(tmp[3], &iv[12]);
89 SILC_GET32_MSB(tmp2[0], &src[0]);
90 SILC_GET32_MSB(tmp2[1], &src[4]);
91 SILC_GET32_MSB(tmp2[2], &src[8]);
92 SILC_GET32_MSB(tmp2[3], &src[12]);
94 tmp[0] = tmp[0] ^ tmp2[0];
95 tmp[1] = tmp[1] ^ tmp2[1];
96 tmp[2] = tmp[2] ^ tmp2[2];
97 tmp[3] = tmp[3] ^ tmp2[3];
99 SILC_PUT32_MSB(tmp[0], &iv[0]);
100 SILC_PUT32_MSB(tmp[1], &iv[4]);
101 SILC_PUT32_MSB(tmp[2], &iv[8]);
102 SILC_PUT32_MSB(tmp[3], &iv[12]);
104 aes_encrypt(iv, iv, &((AesContext *)context)->u.enc);
114 /* Decrypts with the cipher in CBC mode. Source and destination buffers
115 maybe one and same. */
117 SILC_CIPHER_API_DECRYPT(aes_cbc)
119 unsigned char tmp[16];
121 SilcUInt32 tmp2[4], tmp3[4];
127 memcpy(tmp, src, 16);
128 aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
130 SILC_GET32_MSB(tmp2[0], &iv[0]);
131 SILC_GET32_MSB(tmp2[1], &iv[4]);
132 SILC_GET32_MSB(tmp2[2], &iv[8]);
133 SILC_GET32_MSB(tmp2[3], &iv[12]);
135 SILC_GET32_MSB(tmp3[0], &dst[0]);
136 SILC_GET32_MSB(tmp3[1], &dst[4]);
137 SILC_GET32_MSB(tmp3[2], &dst[8]);
138 SILC_GET32_MSB(tmp3[3], &dst[12]);
140 tmp2[0] = tmp3[0] ^ tmp2[0];
141 tmp2[1] = tmp3[1] ^ tmp2[1];
142 tmp2[2] = tmp3[2] ^ tmp2[2];
143 tmp2[3] = tmp3[3] ^ tmp2[3];
145 SILC_PUT32_MSB(tmp2[0], &dst[0]);
146 SILC_PUT32_MSB(tmp2[1], &dst[4]);
147 SILC_PUT32_MSB(tmp2[2], &dst[8]);
148 SILC_PUT32_MSB(tmp2[3], &dst[12]);
160 /* Sets the key for the cipher. */
162 SILC_CIPHER_API_SET_KEY(aes_ctr)
164 AesContext *aes = context;
165 memset(&aes->u.enc, 0, sizeof(aes->u.enc));
166 aes_encrypt_key(key, keylen, &aes->u.enc);
170 /* Sets IV for the cipher. */
172 SILC_CIPHER_API_SET_IV(aes_ctr)
174 AesContext *aes = context;
176 /* Starts new block. */
177 aes->u.enc.inf.b[2] = 0;
180 /* Returns the size of the cipher context. */
182 SILC_CIPHER_API_CONTEXT_LEN(aes_ctr)
184 return sizeof(AesContext);
187 /* Encrypts with the cipher in CTR mode. Source and destination buffers
188 may be one and same. Assumes MSB first ordered counter. */
190 SILC_CIPHER_API_ENCRYPT(aes_ctr)
192 AesContext *aes = context;
195 i = aes->u.enc.inf.b[2];
201 for (k = 15; k >= 0; k--)
205 aes_encrypt(iv, aes->u.enc.pad, &aes->u.enc);
208 *dst++ = *src++ ^ aes->u.enc.pad[i++];
210 aes->u.enc.inf.b[2] = i;
215 /* Decrypts with the cipher in CTR mode. Source and destination buffers
216 maybe one and same. */
218 SILC_CIPHER_API_DECRYPT(aes_ctr)
220 return silc_aes_ctr_encrypt(context, src, dst, len, iv);
223 /****************************************************************************/
225 #if defined(__cplusplus)
230 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
231 # define XP_DIR __cdecl
236 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
237 #define d_4(t,n,b,e,f,g,h) ALIGN const XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
238 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
241 d_1(uint_8t, t_dec(i,box), isb_data, h0);
242 #endif /* SILC_AES_ASM */
243 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
244 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
245 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
246 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
247 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
250 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
251 k[4*(i)+5] = ss[1] ^= ss[0]; \
252 k[4*(i)+6] = ss[2] ^= ss[1]; \
253 k[4*(i)+7] = ss[3] ^= ss[2]; \
256 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
259 cx->ks[0] = ss[0] = word_in(key, 0);
260 cx->ks[1] = ss[1] = word_in(key, 1);
261 cx->ks[2] = ss[2] = word_in(key, 2);
262 cx->ks[3] = ss[3] = word_in(key, 3);
264 ke4(cx->ks, 0); ke4(cx->ks, 1);
265 ke4(cx->ks, 2); ke4(cx->ks, 3);
266 ke4(cx->ks, 4); ke4(cx->ks, 5);
267 ke4(cx->ks, 6); ke4(cx->ks, 7);
271 cx->inf.b[0] = 10 * 16;
275 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
276 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
277 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
278 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
283 k[6*(i)+10] = ss[4] ^= ss[3]; \
284 k[6*(i)+11] = ss[5] ^= ss[4]; \
287 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
290 cx->ks[0] = ss[0] = word_in(key, 0);
291 cx->ks[1] = ss[1] = word_in(key, 1);
292 cx->ks[2] = ss[2] = word_in(key, 2);
293 cx->ks[3] = ss[3] = word_in(key, 3);
294 cx->ks[4] = ss[4] = word_in(key, 4);
295 cx->ks[5] = ss[5] = word_in(key, 5);
297 ke6(cx->ks, 0); ke6(cx->ks, 1);
298 ke6(cx->ks, 2); ke6(cx->ks, 3);
299 ke6(cx->ks, 4); ke6(cx->ks, 5);
303 cx->inf.b[0] = 12 * 16;
307 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
308 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
309 k[8*(i)+10] = ss[2] ^= ss[1]; \
310 k[8*(i)+11] = ss[3] ^= ss[2]; \
315 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
316 k[8*(i)+13] = ss[5] ^= ss[4]; \
317 k[8*(i)+14] = ss[6] ^= ss[5]; \
318 k[8*(i)+15] = ss[7] ^= ss[6]; \
321 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
324 cx->ks[0] = ss[0] = word_in(key, 0);
325 cx->ks[1] = ss[1] = word_in(key, 1);
326 cx->ks[2] = ss[2] = word_in(key, 2);
327 cx->ks[3] = ss[3] = word_in(key, 3);
328 cx->ks[4] = ss[4] = word_in(key, 4);
329 cx->ks[5] = ss[5] = word_in(key, 5);
330 cx->ks[6] = ss[6] = word_in(key, 6);
331 cx->ks[7] = ss[7] = word_in(key, 7);
333 ke8(cx->ks, 0); ke8(cx->ks, 1);
334 ke8(cx->ks, 2); ke8(cx->ks, 3);
335 ke8(cx->ks, 4); ke8(cx->ks, 5);
338 cx->inf.b[0] = 14 * 16;
341 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
345 case 16: case 128: aes_encrypt_key128(key, cx); return;
346 case 24: case 192: aes_encrypt_key192(key, cx); return;
347 case 32: case 256: aes_encrypt_key256(key, cx); return;
351 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
353 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
354 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
355 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
356 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
360 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
361 ss[1] = ss[1] ^ ss[3]; \
362 ss[2] = ss[2] ^ ss[3]; \
363 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
364 ss[i % 4] ^= ss[4]; \
365 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
366 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
367 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
368 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
372 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
373 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
374 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
375 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
376 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
377 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
381 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
382 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
383 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
384 k[v(40,(4*(i))+6)] = ss[0]; \
385 k[v(40,(4*(i))+7)] = ss[1]; \
388 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
390 #if defined( d_vars )
393 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
394 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
395 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
396 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
398 kdf4(cx->ks, 0); kd4(cx->ks, 1);
399 kd4(cx->ks, 2); kd4(cx->ks, 3);
400 kd4(cx->ks, 4); kd4(cx->ks, 5);
401 kd4(cx->ks, 6); kd4(cx->ks, 7);
402 kd4(cx->ks, 8); kdl4(cx->ks, 9);
404 cx->inf.b[0] = 10 * 16;
408 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
409 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
410 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
411 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
416 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
417 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
421 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
422 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
423 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
424 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
425 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
426 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
430 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
431 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
432 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
433 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
434 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
435 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
436 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
440 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
441 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
442 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
443 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
446 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
448 #if defined( d_vars )
451 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
452 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
453 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
454 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
456 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
457 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
458 kdf6(cx->ks, 0); kd6(cx->ks, 1);
459 kd6(cx->ks, 2); kd6(cx->ks, 3);
460 kd6(cx->ks, 4); kd6(cx->ks, 5);
461 kd6(cx->ks, 6); kdl6(cx->ks, 7);
463 cx->inf.b[0] = 12 * 16;
467 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
468 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
469 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
470 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
475 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
476 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
477 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
478 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
482 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
483 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
484 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
485 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
486 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
487 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
488 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
489 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
493 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
494 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
495 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
496 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
497 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
498 ss[8] = ls_box(ss[3],0); \
499 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
500 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
501 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
502 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
506 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
507 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
508 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
509 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
512 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
514 #if defined( d_vars )
517 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
518 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
519 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
520 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
522 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
523 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
524 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
525 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
526 kdf8(cx->ks, 0); kd8(cx->ks, 1);
527 kd8(cx->ks, 2); kd8(cx->ks, 3);
528 kd8(cx->ks, 4); kd8(cx->ks, 5);
531 cx->inf.b[0] = 14 * 16;
534 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
538 case 16: case 128: aes_decrypt_key128(key, cx); return;
539 case 24: case 192: aes_decrypt_key192(key, cx); return;
540 case 32: case 256: aes_decrypt_key256(key, cx); return;
545 /* C version of AES */
547 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
548 #define so(y,x,c) word_out(y, c, s(x,c))
549 #define locals(y,x) x[4],y[4]
550 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
551 s(y,2) = s(x,2); s(y,3) = s(x,3);
552 #define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
553 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
554 #define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
556 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
557 Pentium optimiation with small code but this is poor for decryption
558 so we need to control this with the following VC++ pragmas
561 #if defined( _MSC_VER ) && !defined( _WIN64 )
562 #pragma optimize( "s", on )
565 #define fwd_var(x,r,c)\
566 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
567 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
568 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
569 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
570 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
571 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
573 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
574 { uint_32t locals(b0, b1);
578 state_in(b0, in, kp);
583 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
584 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
587 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
588 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
591 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
592 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
593 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
594 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
595 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
596 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
597 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
598 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
599 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
600 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
606 #define inv_var(x,r,c)\
607 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
608 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
609 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
610 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
612 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
613 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
615 #define rnd_key(n) (kp + n * N_COLS)
617 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
618 { uint_32t locals(b0, b1);
621 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
622 state_in(b0, in, kp);
624 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
628 round(inv_rnd, b1, b0, rnd_key(-13));
629 round(inv_rnd, b0, b1, rnd_key(-12));
631 round(inv_rnd, b1, b0, rnd_key(-11));
632 round(inv_rnd, b0, b1, rnd_key(-10));
634 round(inv_rnd, b1, b0, rnd_key(-9));
635 round(inv_rnd, b0, b1, rnd_key(-8));
636 round(inv_rnd, b1, b0, rnd_key(-7));
637 round(inv_rnd, b0, b1, rnd_key(-6));
638 round(inv_rnd, b1, b0, rnd_key(-5));
639 round(inv_rnd, b0, b1, rnd_key(-4));
640 round(inv_rnd, b1, b0, rnd_key(-3));
641 round(inv_rnd, b0, b1, rnd_key(-2));
642 round(inv_rnd, b1, b0, rnd_key(-1));
643 round(inv_lrnd, b0, b1, rnd_key( 0));
649 #if defined(__cplusplus)
653 #endif /* SILC_AES_ASM */