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 ---------------------------------------------------------------------------
36 #include "silccrypto.h"
37 #include "aes_internal.h"
41 * SILC Crypto API for AES
44 /* Sets the key for the cipher. */
46 SILC_CIPHER_API_SET_KEY(aes)
49 case SILC_CIPHER_MODE_CTR:
50 case SILC_CIPHER_MODE_CFB:
51 aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
54 case SILC_CIPHER_MODE_CBC:
55 case SILC_CIPHER_MODE_ECB:
57 aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
59 aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
68 /* Sets IV for the cipher. */
70 SILC_CIPHER_API_SET_IV(aes)
72 AesContext *aes = context;
76 case SILC_CIPHER_MODE_CTR:
77 case SILC_CIPHER_MODE_CFB:
78 /* Starts new block. */
79 aes->u.enc.inf.b[2] = 16;
89 SILC_CIPHER_API_INIT(aes)
91 AesContext *aes = silc_calloc(1, sizeof(AesContext));
93 aes->u.enc.inf.b[2] = 16;
99 SILC_CIPHER_API_UNINIT(aes)
101 AesContext *aes = context;
102 memset(aes, 0, sizeof(*aes));
106 /* Encrypts with the cipher. Source and destination buffers maybe one and
109 SILC_CIPHER_API_ENCRYPT(aes)
111 AesContext *aes = context;
115 case SILC_CIPHER_MODE_CTR:
116 SILC_CTR_MSB_128_8(iv, cipher->block, aes->u.enc.inf.b[2], src, dst,
117 aes_encrypt(iv, cipher->block, &aes->u.enc));
120 case SILC_CIPHER_MODE_ECB:
122 SilcUInt32 nb = len >> 4;
125 aes_encrypt(src, dst, &aes->u.enc);
132 case SILC_CIPHER_MODE_CBC:
134 SilcUInt32 nb = len >> 4;
136 SILC_ASSERT((len & (16 - 1)) == 0);
141 lp32(iv)[0] ^= lp32(src)[0];
142 lp32(iv)[1] ^= lp32(src)[1];
143 lp32(iv)[2] ^= lp32(src)[2];
144 lp32(iv)[3] ^= lp32(src)[3];
145 aes_encrypt(iv, iv, &aes->u.enc);
153 case SILC_CIPHER_MODE_CFB:
154 SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
155 aes_encrypt(iv, iv, &aes->u.enc));
165 /* Decrypts with the cipher. Source and destination buffers maybe one
168 SILC_CIPHER_API_DECRYPT(aes)
170 AesContext *aes = context;
173 case SILC_CIPHER_MODE_CTR:
174 return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
177 case SILC_CIPHER_MODE_ECB:
179 SilcUInt32 nb = len >> 4;
182 aes_decrypt(src, dst, &aes->u.dec);
189 case SILC_CIPHER_MODE_CBC:
191 unsigned char tmp[16];
192 SilcUInt32 nb = len >> 4;
198 memcpy(tmp, src, 16);
199 aes_decrypt(src, dst, &aes->u.dec);
200 lp32(dst)[0] ^= lp32(iv)[0];
201 lp32(dst)[1] ^= lp32(iv)[1];
202 lp32(dst)[2] ^= lp32(iv)[2];
203 lp32(dst)[3] ^= lp32(iv)[3];
211 case SILC_CIPHER_MODE_CFB:
212 SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
213 aes_encrypt(iv, iv, &aes->u.enc));
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);
270 cx->inf.b[0] = 10 * 16;
274 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
275 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
276 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
277 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
282 k[6*(i)+10] = ss[4] ^= ss[3]; \
283 k[6*(i)+11] = ss[5] ^= ss[4]; \
286 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
289 cx->ks[0] = ss[0] = word_in(key, 0);
290 cx->ks[1] = ss[1] = word_in(key, 1);
291 cx->ks[2] = ss[2] = word_in(key, 2);
292 cx->ks[3] = ss[3] = word_in(key, 3);
293 cx->ks[4] = ss[4] = word_in(key, 4);
294 cx->ks[5] = ss[5] = word_in(key, 5);
296 ke6(cx->ks, 0); ke6(cx->ks, 1);
297 ke6(cx->ks, 2); ke6(cx->ks, 3);
298 ke6(cx->ks, 4); ke6(cx->ks, 5);
301 cx->inf.b[0] = 12 * 16;
305 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
306 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
307 k[8*(i)+10] = ss[2] ^= ss[1]; \
308 k[8*(i)+11] = ss[3] ^= ss[2]; \
313 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
314 k[8*(i)+13] = ss[5] ^= ss[4]; \
315 k[8*(i)+14] = ss[6] ^= ss[5]; \
316 k[8*(i)+15] = ss[7] ^= ss[6]; \
319 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
322 cx->ks[0] = ss[0] = word_in(key, 0);
323 cx->ks[1] = ss[1] = word_in(key, 1);
324 cx->ks[2] = ss[2] = word_in(key, 2);
325 cx->ks[3] = ss[3] = word_in(key, 3);
326 cx->ks[4] = ss[4] = word_in(key, 4);
327 cx->ks[5] = ss[5] = word_in(key, 5);
328 cx->ks[6] = ss[6] = word_in(key, 6);
329 cx->ks[7] = ss[7] = word_in(key, 7);
331 ke8(cx->ks, 0); ke8(cx->ks, 1);
332 ke8(cx->ks, 2); ke8(cx->ks, 3);
333 ke8(cx->ks, 4); ke8(cx->ks, 5);
335 cx->inf.b[0] = 14 * 16;
338 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
342 case 16: case 128: aes_encrypt_key128(key, cx); return;
343 case 24: case 192: aes_encrypt_key192(key, cx); return;
344 case 32: case 256: aes_encrypt_key256(key, cx); return;
348 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
350 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
351 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
352 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
353 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
357 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
358 ss[1] = ss[1] ^ ss[3]; \
359 ss[2] = ss[2] ^ ss[3]; \
360 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
361 ss[i % 4] ^= ss[4]; \
362 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
363 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
364 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
365 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
369 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
370 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
371 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
372 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
373 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
374 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
378 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
379 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
380 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
381 k[v(40,(4*(i))+6)] = ss[0]; \
382 k[v(40,(4*(i))+7)] = ss[1]; \
385 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
387 #if defined( d_vars )
390 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
391 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
392 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
393 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
395 kdf4(cx->ks, 0); kd4(cx->ks, 1);
396 kd4(cx->ks, 2); kd4(cx->ks, 3);
397 kd4(cx->ks, 4); kd4(cx->ks, 5);
398 kd4(cx->ks, 6); kd4(cx->ks, 7);
399 kd4(cx->ks, 8); kdl4(cx->ks, 9);
400 cx->inf.b[0] = 10 * 16;
404 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
405 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
406 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
407 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
412 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
413 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
417 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
418 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
419 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
420 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
421 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
422 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
426 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
427 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
428 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
429 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
430 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
431 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
432 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
436 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
437 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
438 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
439 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
442 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
444 #if defined( d_vars )
447 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
448 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
449 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
450 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
452 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
453 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
454 kdf6(cx->ks, 0); kd6(cx->ks, 1);
455 kd6(cx->ks, 2); kd6(cx->ks, 3);
456 kd6(cx->ks, 4); kd6(cx->ks, 5);
457 kd6(cx->ks, 6); kdl6(cx->ks, 7);
458 cx->inf.b[0] = 12 * 16;
462 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
463 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
464 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
465 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
470 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
471 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
472 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
473 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
477 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
478 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
479 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
480 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
481 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
482 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
483 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
484 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
488 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
489 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
490 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
491 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
492 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
493 ss[8] = ls_box(ss[3],0); \
494 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
495 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
496 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
497 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
501 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
502 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
503 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
504 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
507 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
509 #if defined( d_vars )
512 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
513 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
514 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
515 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
517 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
518 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
519 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
520 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
521 kdf8(cx->ks, 0); kd8(cx->ks, 1);
522 kd8(cx->ks, 2); kd8(cx->ks, 3);
523 kd8(cx->ks, 4); kd8(cx->ks, 5);
525 cx->inf.b[0] = 14 * 16;
528 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
532 case 16: case 128: aes_decrypt_key128(key, cx); return;
533 case 24: case 192: aes_decrypt_key192(key, cx); return;
534 case 32: case 256: aes_decrypt_key256(key, cx); return;
539 /* C version of AES */
541 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
542 #define so(y,x,c) word_out(y, c, s(x,c))
543 #define locals(y,x) x[4],y[4]
544 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
545 s(y,2) = s(x,2); s(y,3) = s(x,3);
546 #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)
547 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
548 #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)
550 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
551 Pentium optimiation with small code but this is poor for decryption
552 so we need to control this with the following VC++ pragmas
555 #if defined( _MSC_VER ) && !defined( _WIN64 )
556 #pragma optimize( "s", on )
559 #define fwd_var(x,r,c)\
560 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
561 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
562 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
563 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
564 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
565 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
567 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
568 { uint_32t locals(b0, b1);
572 state_in(b0, in, kp);
577 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
578 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
581 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
582 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
585 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
586 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
587 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
588 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
589 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
590 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
591 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
592 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
593 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
594 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
600 #define inv_var(x,r,c)\
601 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
602 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
603 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
604 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
606 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
607 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
609 #define rnd_key(n) (kp + n * N_COLS)
611 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
612 { uint_32t locals(b0, b1);
615 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
616 state_in(b0, in, kp);
618 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
622 round(inv_rnd, b1, b0, rnd_key(-13));
623 round(inv_rnd, b0, b1, rnd_key(-12));
625 round(inv_rnd, b1, b0, rnd_key(-11));
626 round(inv_rnd, b0, b1, rnd_key(-10));
628 round(inv_rnd, b1, b0, rnd_key(-9));
629 round(inv_rnd, b0, b1, rnd_key(-8));
630 round(inv_rnd, b1, b0, rnd_key(-7));
631 round(inv_rnd, b0, b1, rnd_key(-6));
632 round(inv_rnd, b1, b0, rnd_key(-5));
633 round(inv_rnd, b0, b1, rnd_key(-4));
634 round(inv_rnd, b1, b0, rnd_key(-3));
635 round(inv_rnd, b0, b1, rnd_key(-2));
636 round(inv_rnd, b1, b0, rnd_key(-1));
637 round(inv_lrnd, b0, b1, rnd_key( 0));
643 #if defined(__cplusplus)
647 #endif /* SILC_AES_ASM */