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 /* Returns the size of the cipher context. */
59 SILC_CIPHER_API_CONTEXT_LEN(aes_cbc)
61 return sizeof(AesContext);
64 /* Encrypts with the cipher in CBC mode. Source and destination buffers
65 maybe one and same. */
67 SILC_CIPHER_API_ENCRYPT(aes_cbc)
71 SILC_ASSERT((len & (16 - 1)) == 0);
76 lp32(iv)[0] ^= lp32(src)[0];
77 lp32(iv)[1] ^= lp32(src)[1];
78 lp32(iv)[2] ^= lp32(src)[2];
79 lp32(iv)[3] ^= lp32(src)[3];
80 aes_encrypt(iv, iv, &((AesContext *)context)->u.enc);
89 /* Decrypts with the cipher in CBC mode. Source and destination buffers
90 maybe one and same. */
92 SILC_CIPHER_API_DECRYPT(aes_cbc)
94 unsigned char tmp[16];
101 memcpy(tmp, src, 16);
102 aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
103 lp32(dst)[0] ^= lp32(iv)[0];
104 lp32(dst)[1] ^= lp32(iv)[1];
105 lp32(dst)[2] ^= lp32(iv)[2];
106 lp32(dst)[3] ^= lp32(iv)[3];
117 /* Sets the key for the cipher. */
119 SILC_CIPHER_API_SET_KEY(aes_ctr)
121 AesContext *aes = context;
122 memset(&aes->u.enc, 0, sizeof(aes->u.enc));
123 aes_encrypt_key(key, keylen, &aes->u.enc);
127 /* Returns the size of the cipher context. */
129 SILC_CIPHER_API_CONTEXT_LEN(aes_ctr)
131 return sizeof(AesContext);
134 /* Encrypts with the cipher in CTR mode. Source and destination buffers
135 maybe one and same. Assumes MSB first ordered counter. */
137 SILC_CIPHER_API_ENCRYPT(aes_ctr)
139 AesContext *aes = context;
143 SILC_GET32_MSB(ctr[0], iv);
144 SILC_GET32_MSB(ctr[1], iv + 4);
145 SILC_GET32_MSB(ctr[2], iv + 8);
146 SILC_GET32_MSB(ctr[3], iv + 12);
148 i = aes->u.enc.inf.b[2];
159 SILC_PUT32_MSB(ctr[0], iv);
160 SILC_PUT32_MSB(ctr[1], iv + 4);
161 SILC_PUT32_MSB(ctr[2], iv + 8);
162 SILC_PUT32_MSB(ctr[3], iv + 12);
164 aes_encrypt(iv, iv, &aes->u.enc);
167 *dst++ = *src++ ^ iv[i++];
169 aes->u.enc.inf.b[2] = i;
171 SILC_PUT32_MSB(ctr[0], iv);
172 SILC_PUT32_MSB(ctr[1], iv + 4);
173 SILC_PUT32_MSB(ctr[2], iv + 8);
174 SILC_PUT32_MSB(ctr[3], iv + 12);
179 /* Decrypts with the cipher in CTR mode. Source and destination buffers
180 maybe one and same. */
182 SILC_CIPHER_API_DECRYPT(aes_ctr)
184 return silc_aes_ctr_encrypt(context, src, dst, len, iv);
187 /****************************************************************************/
189 #if defined(__cplusplus)
194 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
195 # define XP_DIR __cdecl
200 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
201 #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) }
202 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
205 d_1(uint_8t, t_dec(i,box), isb_data, h0);
206 #endif /* SILC_ASM_AES */
207 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
208 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
209 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
210 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
211 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
214 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
215 k[4*(i)+5] = ss[1] ^= ss[0]; \
216 k[4*(i)+6] = ss[2] ^= ss[1]; \
217 k[4*(i)+7] = ss[3] ^= ss[2]; \
220 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
223 cx->ks[0] = ss[0] = word_in(key, 0);
224 cx->ks[1] = ss[1] = word_in(key, 1);
225 cx->ks[2] = ss[2] = word_in(key, 2);
226 cx->ks[3] = ss[3] = word_in(key, 3);
228 ke4(cx->ks, 0); ke4(cx->ks, 1);
229 ke4(cx->ks, 2); ke4(cx->ks, 3);
230 ke4(cx->ks, 4); ke4(cx->ks, 5);
231 ke4(cx->ks, 6); ke4(cx->ks, 7);
235 cx->inf.b[0] = 10 * 16;
239 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
240 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
241 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
242 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
247 k[6*(i)+10] = ss[4] ^= ss[3]; \
248 k[6*(i)+11] = ss[5] ^= ss[4]; \
251 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
254 cx->ks[0] = ss[0] = word_in(key, 0);
255 cx->ks[1] = ss[1] = word_in(key, 1);
256 cx->ks[2] = ss[2] = word_in(key, 2);
257 cx->ks[3] = ss[3] = word_in(key, 3);
258 cx->ks[4] = ss[4] = word_in(key, 4);
259 cx->ks[5] = ss[5] = word_in(key, 5);
261 ke6(cx->ks, 0); ke6(cx->ks, 1);
262 ke6(cx->ks, 2); ke6(cx->ks, 3);
263 ke6(cx->ks, 4); ke6(cx->ks, 5);
267 cx->inf.b[0] = 12 * 16;
271 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
272 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
273 k[8*(i)+10] = ss[2] ^= ss[1]; \
274 k[8*(i)+11] = ss[3] ^= ss[2]; \
279 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
280 k[8*(i)+13] = ss[5] ^= ss[4]; \
281 k[8*(i)+14] = ss[6] ^= ss[5]; \
282 k[8*(i)+15] = ss[7] ^= ss[6]; \
285 AES_RETURN aes_encrypt_key256(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);
294 cx->ks[6] = ss[6] = word_in(key, 6);
295 cx->ks[7] = ss[7] = word_in(key, 7);
297 ke8(cx->ks, 0); ke8(cx->ks, 1);
298 ke8(cx->ks, 2); ke8(cx->ks, 3);
299 ke8(cx->ks, 4); ke8(cx->ks, 5);
302 cx->inf.b[0] = 14 * 16;
305 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
309 case 16: case 128: aes_encrypt_key128(key, cx); return;
310 case 24: case 192: aes_encrypt_key192(key, cx); return;
311 case 32: case 256: aes_encrypt_key256(key, cx); return;
315 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
317 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
318 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
319 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
320 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
324 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
325 ss[1] = ss[1] ^ ss[3]; \
326 ss[2] = ss[2] ^ ss[3]; \
327 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
328 ss[i % 4] ^= ss[4]; \
329 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
330 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
331 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
332 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
336 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
337 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
338 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
339 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
340 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
341 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
345 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
346 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
347 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
348 k[v(40,(4*(i))+6)] = ss[0]; \
349 k[v(40,(4*(i))+7)] = ss[1]; \
352 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
354 #if defined( d_vars )
357 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
358 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
359 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
360 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
362 kdf4(cx->ks, 0); kd4(cx->ks, 1);
363 kd4(cx->ks, 2); kd4(cx->ks, 3);
364 kd4(cx->ks, 4); kd4(cx->ks, 5);
365 kd4(cx->ks, 6); kd4(cx->ks, 7);
366 kd4(cx->ks, 8); kdl4(cx->ks, 9);
368 cx->inf.b[0] = 10 * 16;
372 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
373 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
374 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
375 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
380 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
381 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
385 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
386 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
387 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
388 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
389 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
390 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
394 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
395 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
396 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
397 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
398 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
399 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
400 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
404 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
405 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
406 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
407 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
410 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
412 #if defined( d_vars )
415 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
416 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
417 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
418 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
420 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
421 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
422 kdf6(cx->ks, 0); kd6(cx->ks, 1);
423 kd6(cx->ks, 2); kd6(cx->ks, 3);
424 kd6(cx->ks, 4); kd6(cx->ks, 5);
425 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);
495 cx->inf.b[0] = 14 * 16;
498 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
502 case 16: case 128: aes_decrypt_key128(key, cx); return;
503 case 24: case 192: aes_decrypt_key192(key, cx); return;
504 case 32: case 256: aes_decrypt_key256(key, cx); return;
509 /* C version of AES */
511 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
512 #define so(y,x,c) word_out(y, c, s(x,c))
513 #define locals(y,x) x[4],y[4]
514 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
515 s(y,2) = s(x,2); s(y,3) = s(x,3);
516 #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)
517 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
518 #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)
520 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
521 Pentium optimiation with small code but this is poor for decryption
522 so we need to control this with the following VC++ pragmas
525 #if defined( _MSC_VER ) && !defined( _WIN64 )
526 #pragma optimize( "s", on )
529 #define fwd_var(x,r,c)\
530 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
531 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
532 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
533 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
534 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
535 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
537 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
538 { uint_32t locals(b0, b1);
542 state_in(b0, in, kp);
547 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
548 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
551 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
552 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
555 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
556 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
557 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
558 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
559 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
560 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
561 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
562 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
563 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
564 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
570 #define inv_var(x,r,c)\
571 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
572 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
573 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
574 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
576 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
577 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
579 #define rnd_key(n) (kp + n * N_COLS)
581 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
582 { uint_32t locals(b0, b1);
585 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
586 state_in(b0, in, kp);
588 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
592 round(inv_rnd, b1, b0, rnd_key(-13));
593 round(inv_rnd, b0, b1, rnd_key(-12));
595 round(inv_rnd, b1, b0, rnd_key(-11));
596 round(inv_rnd, b0, b1, rnd_key(-10));
598 round(inv_rnd, b1, b0, rnd_key(-9));
599 round(inv_rnd, b0, b1, rnd_key(-8));
600 round(inv_rnd, b1, b0, rnd_key(-7));
601 round(inv_rnd, b0, b1, rnd_key(-6));
602 round(inv_rnd, b1, b0, rnd_key(-5));
603 round(inv_rnd, b0, b1, rnd_key(-4));
604 round(inv_rnd, b1, b0, rnd_key(-3));
605 round(inv_rnd, b0, b1, rnd_key(-2));
606 round(inv_rnd, b1, b0, rnd_key(-1));
607 round(inv_lrnd, b0, b1, rnd_key( 0));
613 #if defined(__cplusplus)
617 #endif /* SILC_ASM_AES */