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)
78 SILC_ASSERT((len & (16 - 1)) == 0);
83 lp32(iv)[0] ^= lp32(src)[0];
84 lp32(iv)[1] ^= lp32(src)[1];
85 lp32(iv)[2] ^= lp32(src)[2];
86 lp32(iv)[3] ^= lp32(src)[3];
87 aes_encrypt(iv, iv, &((AesContext *)context)->u.enc);
96 /* Decrypts with the cipher in CBC mode. Source and destination buffers
97 maybe one and same. */
99 SILC_CIPHER_API_DECRYPT(aes_cbc)
101 unsigned char tmp[16];
108 memcpy(tmp, src, 16);
109 aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
110 lp32(dst)[0] ^= lp32(iv)[0];
111 lp32(dst)[1] ^= lp32(iv)[1];
112 lp32(dst)[2] ^= lp32(iv)[2];
113 lp32(dst)[3] ^= lp32(iv)[3];
124 /* Sets the key for the cipher. */
126 SILC_CIPHER_API_SET_KEY(aes_ctr)
128 AesContext *aes = context;
129 memset(&aes->u.enc, 0, sizeof(aes->u.enc));
130 aes_encrypt_key(key, keylen, &aes->u.enc);
134 /* Sets IV for the cipher. */
136 SILC_CIPHER_API_SET_IV(aes_ctr)
138 AesContext *aes = context;
140 /* Starts new block. */
141 aes->u.enc.inf.b[2] = 0;
144 /* Returns the size of the cipher context. */
146 SILC_CIPHER_API_CONTEXT_LEN(aes_ctr)
148 return sizeof(AesContext);
151 /* Encrypts with the cipher in CTR mode. Source and destination buffers
152 may be one and same. Assumes MSB first ordered counter. */
154 SILC_CIPHER_API_ENCRYPT(aes_ctr)
156 AesContext *aes = context;
160 SILC_GET32_MSB(ctr[0], iv);
161 SILC_GET32_MSB(ctr[1], iv + 4);
162 SILC_GET32_MSB(ctr[2], iv + 8);
163 SILC_GET32_MSB(ctr[3], iv + 12);
165 i = aes->u.enc.inf.b[2];
176 SILC_PUT32_MSB(ctr[0], iv);
177 SILC_PUT32_MSB(ctr[1], iv + 4);
178 SILC_PUT32_MSB(ctr[2], iv + 8);
179 SILC_PUT32_MSB(ctr[3], iv + 12);
181 aes_encrypt(iv, iv, &aes->u.enc);
184 *dst++ = *src++ ^ iv[i++];
186 aes->u.enc.inf.b[2] = i;
188 SILC_PUT32_MSB(ctr[0], iv);
189 SILC_PUT32_MSB(ctr[1], iv + 4);
190 SILC_PUT32_MSB(ctr[2], iv + 8);
191 SILC_PUT32_MSB(ctr[3], iv + 12);
196 /* Decrypts with the cipher in CTR mode. Source and destination buffers
197 maybe one and same. */
199 SILC_CIPHER_API_DECRYPT(aes_ctr)
201 return silc_aes_ctr_encrypt(context, src, dst, len, iv);
204 /****************************************************************************/
206 #if defined(__cplusplus)
211 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
212 # define XP_DIR __cdecl
217 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
218 #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) }
219 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
222 d_1(uint_8t, t_dec(i,box), isb_data, h0);
223 #endif /* SILC_AES_ASM */
224 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
225 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
226 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
227 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
228 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
231 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
232 k[4*(i)+5] = ss[1] ^= ss[0]; \
233 k[4*(i)+6] = ss[2] ^= ss[1]; \
234 k[4*(i)+7] = ss[3] ^= ss[2]; \
237 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
240 cx->ks[0] = ss[0] = word_in(key, 0);
241 cx->ks[1] = ss[1] = word_in(key, 1);
242 cx->ks[2] = ss[2] = word_in(key, 2);
243 cx->ks[3] = ss[3] = word_in(key, 3);
245 ke4(cx->ks, 0); ke4(cx->ks, 1);
246 ke4(cx->ks, 2); ke4(cx->ks, 3);
247 ke4(cx->ks, 4); ke4(cx->ks, 5);
248 ke4(cx->ks, 6); ke4(cx->ks, 7);
252 cx->inf.b[0] = 10 * 16;
256 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
257 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
258 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
259 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
264 k[6*(i)+10] = ss[4] ^= ss[3]; \
265 k[6*(i)+11] = ss[5] ^= ss[4]; \
268 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
271 cx->ks[0] = ss[0] = word_in(key, 0);
272 cx->ks[1] = ss[1] = word_in(key, 1);
273 cx->ks[2] = ss[2] = word_in(key, 2);
274 cx->ks[3] = ss[3] = word_in(key, 3);
275 cx->ks[4] = ss[4] = word_in(key, 4);
276 cx->ks[5] = ss[5] = word_in(key, 5);
278 ke6(cx->ks, 0); ke6(cx->ks, 1);
279 ke6(cx->ks, 2); ke6(cx->ks, 3);
280 ke6(cx->ks, 4); ke6(cx->ks, 5);
284 cx->inf.b[0] = 12 * 16;
288 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
289 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
290 k[8*(i)+10] = ss[2] ^= ss[1]; \
291 k[8*(i)+11] = ss[3] ^= ss[2]; \
296 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
297 k[8*(i)+13] = ss[5] ^= ss[4]; \
298 k[8*(i)+14] = ss[6] ^= ss[5]; \
299 k[8*(i)+15] = ss[7] ^= ss[6]; \
302 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
305 cx->ks[0] = ss[0] = word_in(key, 0);
306 cx->ks[1] = ss[1] = word_in(key, 1);
307 cx->ks[2] = ss[2] = word_in(key, 2);
308 cx->ks[3] = ss[3] = word_in(key, 3);
309 cx->ks[4] = ss[4] = word_in(key, 4);
310 cx->ks[5] = ss[5] = word_in(key, 5);
311 cx->ks[6] = ss[6] = word_in(key, 6);
312 cx->ks[7] = ss[7] = word_in(key, 7);
314 ke8(cx->ks, 0); ke8(cx->ks, 1);
315 ke8(cx->ks, 2); ke8(cx->ks, 3);
316 ke8(cx->ks, 4); ke8(cx->ks, 5);
319 cx->inf.b[0] = 14 * 16;
322 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
326 case 16: case 128: aes_encrypt_key128(key, cx); return;
327 case 24: case 192: aes_encrypt_key192(key, cx); return;
328 case 32: case 256: aes_encrypt_key256(key, cx); return;
332 #define v(n,i) ((n) - (i) + 2 * ((i) & 3))
334 { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
335 k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
336 k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
337 k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
341 { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
342 ss[1] = ss[1] ^ ss[3]; \
343 ss[2] = ss[2] ^ ss[3]; \
344 ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
345 ss[i % 4] ^= ss[4]; \
346 ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
347 ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
348 ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
349 ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
353 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
354 ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
355 k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
356 k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
357 k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
358 k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
362 { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
363 k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
364 k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
365 k[v(40,(4*(i))+6)] = ss[0]; \
366 k[v(40,(4*(i))+7)] = ss[1]; \
369 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
371 #if defined( d_vars )
374 cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
375 cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
376 cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
377 cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
379 kdf4(cx->ks, 0); kd4(cx->ks, 1);
380 kd4(cx->ks, 2); kd4(cx->ks, 3);
381 kd4(cx->ks, 4); kd4(cx->ks, 5);
382 kd4(cx->ks, 6); kd4(cx->ks, 7);
383 kd4(cx->ks, 8); kdl4(cx->ks, 9);
385 cx->inf.b[0] = 10 * 16;
389 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
390 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
391 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
392 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
397 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
398 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
402 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
403 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
404 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
405 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
406 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
407 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
411 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
412 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
413 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
414 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
415 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
416 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
417 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
421 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
422 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
423 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
424 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
427 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
429 #if defined( d_vars )
432 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
433 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
434 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
435 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
437 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
438 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
439 kdf6(cx->ks, 0); kd6(cx->ks, 1);
440 kd6(cx->ks, 2); kd6(cx->ks, 3);
441 kd6(cx->ks, 4); kd6(cx->ks, 5);
442 kd6(cx->ks, 6); kdl6(cx->ks, 7);
444 cx->inf.b[0] = 12 * 16;
448 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
449 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
450 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
451 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
456 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
457 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
458 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
459 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
463 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
464 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
465 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
466 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
467 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
468 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
469 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
470 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
474 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
475 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
476 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
477 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
478 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
479 ss[8] = ls_box(ss[3],0); \
480 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
481 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
482 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
483 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
487 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
488 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
489 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
490 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
493 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
495 #if defined( d_vars )
498 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
499 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
500 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
501 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
503 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
504 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
505 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
506 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
507 kdf8(cx->ks, 0); kd8(cx->ks, 1);
508 kd8(cx->ks, 2); kd8(cx->ks, 3);
509 kd8(cx->ks, 4); kd8(cx->ks, 5);
512 cx->inf.b[0] = 14 * 16;
515 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
519 case 16: case 128: aes_decrypt_key128(key, cx); return;
520 case 24: case 192: aes_decrypt_key192(key, cx); return;
521 case 32: case 256: aes_decrypt_key256(key, cx); return;
526 /* C version of AES */
528 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
529 #define so(y,x,c) word_out(y, c, s(x,c))
530 #define locals(y,x) x[4],y[4]
531 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
532 s(y,2) = s(x,2); s(y,3) = s(x,3);
533 #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)
534 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
535 #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)
537 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
538 Pentium optimiation with small code but this is poor for decryption
539 so we need to control this with the following VC++ pragmas
542 #if defined( _MSC_VER ) && !defined( _WIN64 )
543 #pragma optimize( "s", on )
546 #define fwd_var(x,r,c)\
547 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
548 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
549 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
550 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
551 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
552 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
554 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
555 { uint_32t locals(b0, b1);
559 state_in(b0, in, kp);
564 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
565 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
568 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
569 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
572 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
573 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
574 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
575 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
576 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
577 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
578 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
579 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
580 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
581 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
587 #define inv_var(x,r,c)\
588 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
589 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
590 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
591 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
593 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
594 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
596 #define rnd_key(n) (kp + n * N_COLS)
598 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
599 { uint_32t locals(b0, b1);
602 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
603 state_in(b0, in, kp);
605 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
609 round(inv_rnd, b1, b0, rnd_key(-13));
610 round(inv_rnd, b0, b1, rnd_key(-12));
612 round(inv_rnd, b1, b0, rnd_key(-11));
613 round(inv_rnd, b0, b1, rnd_key(-10));
615 round(inv_rnd, b1, b0, rnd_key(-9));
616 round(inv_rnd, b0, b1, rnd_key(-8));
617 round(inv_rnd, b1, b0, rnd_key(-7));
618 round(inv_rnd, b0, b1, rnd_key(-6));
619 round(inv_rnd, b1, b0, rnd_key(-5));
620 round(inv_rnd, b0, b1, rnd_key(-4));
621 round(inv_rnd, b1, b0, rnd_key(-3));
622 round(inv_rnd, b0, b1, rnd_key(-2));
623 round(inv_rnd, b1, b0, rnd_key(-1));
624 round(inv_lrnd, b0, b1, rnd_key( 0));
630 #if defined(__cplusplus)
634 #endif /* SILC_AES_ASM */