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:
133 SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i,
134 aes_encrypt(iv, iv, &aes->u.enc));
137 case SILC_CIPHER_MODE_CFB:
138 SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
139 aes_encrypt(iv, iv, &aes->u.enc));
149 /* Decrypts with the cipher. Source and destination buffers maybe one
152 SILC_CIPHER_API_DECRYPT(aes)
154 AesContext *aes = context;
155 unsigned char prev[16];
159 case SILC_CIPHER_MODE_CTR:
160 return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
163 case SILC_CIPHER_MODE_ECB:
165 SilcUInt32 nb = len >> 4;
168 aes_decrypt(src, dst, &aes->u.dec);
175 case SILC_CIPHER_MODE_CBC:
176 SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i,
177 aes_decrypt(src, dst, &aes->u.dec));
180 case SILC_CIPHER_MODE_CFB:
181 SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
182 aes_encrypt(iv, iv, &aes->u.enc));
192 /****************************************************************************/
194 #if defined(__cplusplus)
199 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
200 # define XP_DIR __cdecl
205 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
206 #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) }
207 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
210 d_1(uint_8t, t_dec(i,box), isb_data, h0);
211 #endif /* SILC_AES_ASM */
212 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
213 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
214 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
215 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
216 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
219 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
220 k[4*(i)+5] = ss[1] ^= ss[0]; \
221 k[4*(i)+6] = ss[2] ^= ss[1]; \
222 k[4*(i)+7] = ss[3] ^= ss[2]; \
225 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
228 cx->ks[0] = ss[0] = word_in(key, 0);
229 cx->ks[1] = ss[1] = word_in(key, 1);
230 cx->ks[2] = ss[2] = word_in(key, 2);
231 cx->ks[3] = ss[3] = word_in(key, 3);
233 ke4(cx->ks, 0); ke4(cx->ks, 1);
234 ke4(cx->ks, 2); ke4(cx->ks, 3);
235 ke4(cx->ks, 4); ke4(cx->ks, 5);
236 ke4(cx->ks, 6); ke4(cx->ks, 7);
239 cx->inf.b[0] = 10 * 16;
243 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
244 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
245 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
246 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
251 k[6*(i)+10] = ss[4] ^= ss[3]; \
252 k[6*(i)+11] = ss[5] ^= ss[4]; \
255 AES_RETURN aes_encrypt_key192(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);
262 cx->ks[4] = ss[4] = word_in(key, 4);
263 cx->ks[5] = ss[5] = word_in(key, 5);
265 ke6(cx->ks, 0); ke6(cx->ks, 1);
266 ke6(cx->ks, 2); ke6(cx->ks, 3);
267 ke6(cx->ks, 4); ke6(cx->ks, 5);
270 cx->inf.b[0] = 12 * 16;
274 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
275 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
276 k[8*(i)+10] = ss[2] ^= ss[1]; \
277 k[8*(i)+11] = ss[3] ^= ss[2]; \
282 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
283 k[8*(i)+13] = ss[5] ^= ss[4]; \
284 k[8*(i)+14] = ss[6] ^= ss[5]; \
285 k[8*(i)+15] = ss[7] ^= ss[6]; \
288 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
291 cx->ks[0] = ss[0] = word_in(key, 0);
292 cx->ks[1] = ss[1] = word_in(key, 1);
293 cx->ks[2] = ss[2] = word_in(key, 2);
294 cx->ks[3] = ss[3] = word_in(key, 3);
295 cx->ks[4] = ss[4] = word_in(key, 4);
296 cx->ks[5] = ss[5] = word_in(key, 5);
297 cx->ks[6] = ss[6] = word_in(key, 6);
298 cx->ks[7] = ss[7] = word_in(key, 7);
300 ke8(cx->ks, 0); ke8(cx->ks, 1);
301 ke8(cx->ks, 2); ke8(cx->ks, 3);
302 ke8(cx->ks, 4); ke8(cx->ks, 5);
304 cx->inf.b[0] = 14 * 16;
307 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
311 case 16: case 128: aes_encrypt_key128(key, cx); return;
312 case 24: case 192: aes_encrypt_key192(key, cx); return;
313 case 32: case 256: aes_encrypt_key256(key, cx); return;
317 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
319 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
320 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
321 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
322 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
326 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
327 ss[1] = ss[1] ^ ss[3]; \
328 ss[2] = ss[2] ^ ss[3]; \
329 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
330 ss[i % 4] ^= ss[4]; \
331 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
332 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
333 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
334 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
338 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
339 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
340 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
341 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
342 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
343 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
347 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
348 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
349 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
350 k[v(40,(4*(i))+6)] = ss[0]; \
351 k[v(40,(4*(i))+7)] = ss[1]; \
354 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
356 #if defined( d_vars )
359 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
360 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
361 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
362 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
364 kdf4(cx->ks, 0); kd4(cx->ks, 1);
365 kd4(cx->ks, 2); kd4(cx->ks, 3);
366 kd4(cx->ks, 4); kd4(cx->ks, 5);
367 kd4(cx->ks, 6); kd4(cx->ks, 7);
368 kd4(cx->ks, 8); kdl4(cx->ks, 9);
369 cx->inf.b[0] = 10 * 16;
373 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
374 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
375 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
376 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
381 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
382 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
386 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
387 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
388 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
389 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
390 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
391 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
395 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
396 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
397 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
398 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
399 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
400 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
401 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
405 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
406 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
407 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
408 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
411 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
413 #if defined( d_vars )
416 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
417 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
418 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
419 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
421 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
422 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
423 kdf6(cx->ks, 0); kd6(cx->ks, 1);
424 kd6(cx->ks, 2); kd6(cx->ks, 3);
425 kd6(cx->ks, 4); kd6(cx->ks, 5);
426 kd6(cx->ks, 6); kdl6(cx->ks, 7);
427 cx->inf.b[0] = 12 * 16;
431 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
432 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
433 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
434 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
439 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
440 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
441 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
442 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
446 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
447 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
448 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
449 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
450 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
451 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
452 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
453 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
457 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
458 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
459 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
460 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
461 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
462 ss[8] = ls_box(ss[3],0); \
463 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
464 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
465 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
466 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
470 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
471 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
472 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
473 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
476 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
478 #if defined( d_vars )
481 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
482 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
483 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
484 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
486 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
487 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
488 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
489 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
490 kdf8(cx->ks, 0); kd8(cx->ks, 1);
491 kd8(cx->ks, 2); kd8(cx->ks, 3);
492 kd8(cx->ks, 4); kd8(cx->ks, 5);
494 cx->inf.b[0] = 14 * 16;
497 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
501 case 16: case 128: aes_decrypt_key128(key, cx); return;
502 case 24: case 192: aes_decrypt_key192(key, cx); return;
503 case 32: case 256: aes_decrypt_key256(key, cx); return;
508 /* C version of AES */
510 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
511 #define so(y,x,c) word_out(y, c, s(x,c))
512 #define locals(y,x) x[4],y[4]
513 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
514 s(y,2) = s(x,2); s(y,3) = s(x,3);
515 #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)
516 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
517 #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)
519 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
520 Pentium optimiation with small code but this is poor for decryption
521 so we need to control this with the following VC++ pragmas
524 #if defined( _MSC_VER ) && !defined( _WIN64 )
525 #pragma optimize( "s", on )
528 #define fwd_var(x,r,c)\
529 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
530 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
531 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
532 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
533 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
534 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
536 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
537 { uint_32t locals(b0, b1);
541 state_in(b0, in, kp);
546 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
547 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
550 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
551 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
554 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
555 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
556 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
557 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
558 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
559 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
560 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
561 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
562 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
563 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
569 #define inv_var(x,r,c)\
570 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
571 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
572 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
573 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
575 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
576 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
578 #define rnd_key(n) (kp + n * N_COLS)
580 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
581 { uint_32t locals(b0, b1);
584 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
585 state_in(b0, in, kp);
587 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
591 round(inv_rnd, b1, b0, rnd_key(-13));
592 round(inv_rnd, b0, b1, rnd_key(-12));
594 round(inv_rnd, b1, b0, rnd_key(-11));
595 round(inv_rnd, b0, b1, rnd_key(-10));
597 round(inv_rnd, b1, b0, rnd_key(-9));
598 round(inv_rnd, b0, b1, rnd_key(-8));
599 round(inv_rnd, b1, b0, rnd_key(-7));
600 round(inv_rnd, b0, b1, rnd_key(-6));
601 round(inv_rnd, b1, b0, rnd_key(-5));
602 round(inv_rnd, b0, b1, rnd_key(-4));
603 round(inv_rnd, b1, b0, rnd_key(-3));
604 round(inv_rnd, b0, b1, rnd_key(-2));
605 round(inv_rnd, b1, b0, rnd_key(-1));
606 round(inv_lrnd, b0, b1, rnd_key( 0));
612 #if defined(__cplusplus)
616 #endif /* SILC_AES_ASM */