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;
98 SILC_CIPHER_API_UNINIT(aes)
100 AesContext *aes = context;
101 memset(aes, 0, sizeof(*aes));
105 /* Encrypts with the cipher. Source and destination buffers maybe one and
108 SILC_CIPHER_API_ENCRYPT(aes)
110 AesContext *aes = context;
114 case SILC_CIPHER_MODE_CTR:
115 SILC_CTR_MSB_128_8(iv, cipher->block, aes->u.enc.inf.b[2], src, dst,
116 aes_encrypt(iv, cipher->block, &aes->u.enc));
119 case SILC_CIPHER_MODE_ECB:
121 SilcUInt32 nb = len >> 4;
124 aes_encrypt(src, dst, &aes->u.enc);
131 case SILC_CIPHER_MODE_CBC:
133 SilcUInt32 nb = len >> 4;
135 SILC_ASSERT((len & (16 - 1)) == 0);
140 lp32(iv)[0] ^= lp32(src)[0];
141 lp32(iv)[1] ^= lp32(src)[1];
142 lp32(iv)[2] ^= lp32(src)[2];
143 lp32(iv)[3] ^= lp32(src)[3];
144 aes_encrypt(iv, iv, &aes->u.enc);
152 case SILC_CIPHER_MODE_CFB:
153 SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
154 aes_encrypt(iv, iv, &aes->u.enc));
164 /* Decrypts with the cipher. Source and destination buffers maybe one
167 SILC_CIPHER_API_DECRYPT(aes)
169 AesContext *aes = context;
172 case SILC_CIPHER_MODE_CTR:
173 return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
176 case SILC_CIPHER_MODE_ECB:
178 SilcUInt32 nb = len >> 4;
181 aes_decrypt(src, dst, &aes->u.dec);
188 case SILC_CIPHER_MODE_CBC:
190 unsigned char tmp[16];
191 SilcUInt32 nb = len >> 4;
197 memcpy(tmp, src, 16);
198 aes_decrypt(src, dst, &aes->u.dec);
199 lp32(dst)[0] ^= lp32(iv)[0];
200 lp32(dst)[1] ^= lp32(iv)[1];
201 lp32(dst)[2] ^= lp32(iv)[2];
202 lp32(dst)[3] ^= lp32(iv)[3];
210 case SILC_CIPHER_MODE_CFB:
211 SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
212 aes_encrypt(iv, iv, &aes->u.enc));
222 /****************************************************************************/
224 #if defined(__cplusplus)
229 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
230 # define XP_DIR __cdecl
235 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
236 #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) }
237 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
240 d_1(uint_8t, t_dec(i,box), isb_data, h0);
241 #endif /* SILC_AES_ASM */
242 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
243 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
244 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
245 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
246 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
249 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
250 k[4*(i)+5] = ss[1] ^= ss[0]; \
251 k[4*(i)+6] = ss[2] ^= ss[1]; \
252 k[4*(i)+7] = ss[3] ^= ss[2]; \
255 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
258 cx->ks[0] = ss[0] = word_in(key, 0);
259 cx->ks[1] = ss[1] = word_in(key, 1);
260 cx->ks[2] = ss[2] = word_in(key, 2);
261 cx->ks[3] = ss[3] = word_in(key, 3);
263 ke4(cx->ks, 0); ke4(cx->ks, 1);
264 ke4(cx->ks, 2); ke4(cx->ks, 3);
265 ke4(cx->ks, 4); ke4(cx->ks, 5);
266 ke4(cx->ks, 6); ke4(cx->ks, 7);
269 cx->inf.b[0] = 10 * 16;
273 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
274 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
275 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
276 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
281 k[6*(i)+10] = ss[4] ^= ss[3]; \
282 k[6*(i)+11] = ss[5] ^= ss[4]; \
285 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
288 cx->ks[0] = ss[0] = word_in(key, 0);
289 cx->ks[1] = ss[1] = word_in(key, 1);
290 cx->ks[2] = ss[2] = word_in(key, 2);
291 cx->ks[3] = ss[3] = word_in(key, 3);
292 cx->ks[4] = ss[4] = word_in(key, 4);
293 cx->ks[5] = ss[5] = word_in(key, 5);
295 ke6(cx->ks, 0); ke6(cx->ks, 1);
296 ke6(cx->ks, 2); ke6(cx->ks, 3);
297 ke6(cx->ks, 4); ke6(cx->ks, 5);
300 cx->inf.b[0] = 12 * 16;
304 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
305 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
306 k[8*(i)+10] = ss[2] ^= ss[1]; \
307 k[8*(i)+11] = ss[3] ^= ss[2]; \
312 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
313 k[8*(i)+13] = ss[5] ^= ss[4]; \
314 k[8*(i)+14] = ss[6] ^= ss[5]; \
315 k[8*(i)+15] = ss[7] ^= ss[6]; \
318 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
321 cx->ks[0] = ss[0] = word_in(key, 0);
322 cx->ks[1] = ss[1] = word_in(key, 1);
323 cx->ks[2] = ss[2] = word_in(key, 2);
324 cx->ks[3] = ss[3] = word_in(key, 3);
325 cx->ks[4] = ss[4] = word_in(key, 4);
326 cx->ks[5] = ss[5] = word_in(key, 5);
327 cx->ks[6] = ss[6] = word_in(key, 6);
328 cx->ks[7] = ss[7] = word_in(key, 7);
330 ke8(cx->ks, 0); ke8(cx->ks, 1);
331 ke8(cx->ks, 2); ke8(cx->ks, 3);
332 ke8(cx->ks, 4); ke8(cx->ks, 5);
334 cx->inf.b[0] = 14 * 16;
337 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
341 case 16: case 128: aes_encrypt_key128(key, cx); return;
342 case 24: case 192: aes_encrypt_key192(key, cx); return;
343 case 32: case 256: aes_encrypt_key256(key, cx); return;
347 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
349 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
350 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
351 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
352 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
356 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
357 ss[1] = ss[1] ^ ss[3]; \
358 ss[2] = ss[2] ^ ss[3]; \
359 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
360 ss[i % 4] ^= ss[4]; \
361 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
362 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
363 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
364 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
368 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
369 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
370 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
371 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
372 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
373 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
377 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
378 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
379 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
380 k[v(40,(4*(i))+6)] = ss[0]; \
381 k[v(40,(4*(i))+7)] = ss[1]; \
384 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
386 #if defined( d_vars )
389 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
390 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
391 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
392 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
394 kdf4(cx->ks, 0); kd4(cx->ks, 1);
395 kd4(cx->ks, 2); kd4(cx->ks, 3);
396 kd4(cx->ks, 4); kd4(cx->ks, 5);
397 kd4(cx->ks, 6); kd4(cx->ks, 7);
398 kd4(cx->ks, 8); kdl4(cx->ks, 9);
399 cx->inf.b[0] = 10 * 16;
403 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
404 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
405 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
406 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
411 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
412 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
416 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
417 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
418 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
419 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
420 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
421 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
425 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
426 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
427 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
428 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
429 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
430 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
431 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
435 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
436 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
437 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
438 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
441 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
443 #if defined( d_vars )
446 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
447 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
448 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
449 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
451 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
452 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
453 kdf6(cx->ks, 0); kd6(cx->ks, 1);
454 kd6(cx->ks, 2); kd6(cx->ks, 3);
455 kd6(cx->ks, 4); kd6(cx->ks, 5);
456 kd6(cx->ks, 6); kdl6(cx->ks, 7);
457 cx->inf.b[0] = 12 * 16;
461 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
462 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
463 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
464 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
469 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
470 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
471 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
472 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
476 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
477 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
478 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
479 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
480 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
481 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
482 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
483 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
487 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
488 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
489 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
490 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
491 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
492 ss[8] = ls_box(ss[3],0); \
493 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
494 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
495 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
496 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
500 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
501 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
502 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
503 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
506 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
508 #if defined( d_vars )
511 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
512 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
513 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
514 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
516 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
517 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
518 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
519 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
520 kdf8(cx->ks, 0); kd8(cx->ks, 1);
521 kd8(cx->ks, 2); kd8(cx->ks, 3);
522 kd8(cx->ks, 4); kd8(cx->ks, 5);
524 cx->inf.b[0] = 14 * 16;
527 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
531 case 16: case 128: aes_decrypt_key128(key, cx); return;
532 case 24: case 192: aes_decrypt_key192(key, cx); return;
533 case 32: case 256: aes_decrypt_key256(key, cx); return;
538 /* C version of AES */
540 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
541 #define so(y,x,c) word_out(y, c, s(x,c))
542 #define locals(y,x) x[4],y[4]
543 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
544 s(y,2) = s(x,2); s(y,3) = s(x,3);
545 #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)
546 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
547 #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)
549 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
550 Pentium optimiation with small code but this is poor for decryption
551 so we need to control this with the following VC++ pragmas
554 #if defined( _MSC_VER ) && !defined( _WIN64 )
555 #pragma optimize( "s", on )
558 #define fwd_var(x,r,c)\
559 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
560 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
561 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
562 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
563 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
564 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
566 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
567 { uint_32t locals(b0, b1);
571 state_in(b0, in, kp);
576 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
577 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
580 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
581 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
584 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
585 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
586 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
587 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
588 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
589 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
590 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
591 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
592 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
593 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
599 #define inv_var(x,r,c)\
600 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
601 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
602 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
603 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
605 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
606 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
608 #define rnd_key(n) (kp + n * N_COLS)
610 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
611 { uint_32t locals(b0, b1);
614 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
615 state_in(b0, in, kp);
617 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
621 round(inv_rnd, b1, b0, rnd_key(-13));
622 round(inv_rnd, b0, b1, rnd_key(-12));
624 round(inv_rnd, b1, b0, rnd_key(-11));
625 round(inv_rnd, b0, b1, rnd_key(-10));
627 round(inv_rnd, b1, b0, rnd_key(-9));
628 round(inv_rnd, b0, b1, rnd_key(-8));
629 round(inv_rnd, b1, b0, rnd_key(-7));
630 round(inv_rnd, b0, b1, rnd_key(-6));
631 round(inv_rnd, b1, b0, rnd_key(-5));
632 round(inv_rnd, b0, b1, rnd_key(-4));
633 round(inv_rnd, b1, b0, rnd_key(-3));
634 round(inv_rnd, b0, b1, rnd_key(-2));
635 round(inv_rnd, b1, b0, rnd_key(-1));
636 round(inv_lrnd, b0, b1, rnd_key( 0));
642 #if defined(__cplusplus)
646 #endif /* SILC_AES_ASM */