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
44 /* Sets the key for the cipher. */
46 SILC_CIPHER_API_SET_KEY(aes)
48 switch (cipher->mode) {
49 case SILC_CIPHER_MODE_CBC:
51 aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
53 aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
56 case SILC_CIPHER_MODE_CTR:
57 case SILC_CIPHER_MODE_CFB:
58 aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
67 /* Sets IV for the cipher. */
69 SILC_CIPHER_API_SET_IV(aes)
71 AesContext *aes = context;
73 switch (cipher->mode) {
75 case SILC_CIPHER_MODE_CTR:
76 /* Starts new block. */
77 aes->u.enc.inf.b[2] = 0;
80 case SILC_CIPHER_MODE_CFB:
81 /* Starts new block. */
82 aes->u.enc.inf.b[2] = 16;
90 /* Returns the size of the cipher context. */
92 SILC_CIPHER_API_CONTEXT_LEN(aes)
94 return sizeof(AesContext);
97 /* Encrypts with the cipher. Source and destination buffers maybe one and
100 SILC_CIPHER_API_ENCRYPT(aes)
102 AesContext *aes = context;
105 switch (cipher->mode) {
106 case SILC_CIPHER_MODE_CBC:
110 SILC_ASSERT((len & (16 - 1)) == 0);
115 lp32(iv)[0] ^= lp32(src)[0];
116 lp32(iv)[1] ^= lp32(src)[1];
117 lp32(iv)[2] ^= lp32(src)[2];
118 lp32(iv)[3] ^= lp32(src)[3];
119 aes_encrypt(iv, iv, &aes->u.enc);
127 case SILC_CIPHER_MODE_CTR:
128 SILC_CTR_MSB_128_8(iv, ctr, iv, aes->u.enc.inf.b[2], src, dst,
129 aes_encrypt(iv, iv, &aes->u.enc));
132 case SILC_CIPHER_MODE_CFB:
133 SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
134 aes_encrypt(iv, iv, &aes->u.enc));
144 /* Decrypts with the cipher. Source and destination buffers maybe one
147 SILC_CIPHER_API_DECRYPT(aes)
149 AesContext *aes = context;
151 switch (cipher->mode) {
152 case SILC_CIPHER_MODE_CBC:
154 unsigned char tmp[16];
161 memcpy(tmp, src, 16);
162 aes_decrypt(src, dst, &aes->u.dec);
163 lp32(dst)[0] ^= lp32(iv)[0];
164 lp32(dst)[1] ^= lp32(iv)[1];
165 lp32(dst)[2] ^= lp32(iv)[2];
166 lp32(dst)[3] ^= lp32(iv)[3];
174 case SILC_CIPHER_MODE_CTR:
175 return silc_aes_encrypt(cipher, context, src, dst, len, iv);
178 case SILC_CIPHER_MODE_CFB:
179 SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
180 aes_encrypt(iv, iv, &aes->u.enc));
190 /****************************************************************************/
192 #if defined(__cplusplus)
197 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
198 # define XP_DIR __cdecl
203 #define d_1(t,n,b,e) ALIGN const XP_DIR t n[256] = b(e)
204 #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) }
205 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
208 d_1(uint_8t, t_dec(i,box), isb_data, h0);
209 #endif /* SILC_AES_ASM */
210 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
211 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
212 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
213 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
214 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
217 { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
218 k[4*(i)+5] = ss[1] ^= ss[0]; \
219 k[4*(i)+6] = ss[2] ^= ss[1]; \
220 k[4*(i)+7] = ss[3] ^= ss[2]; \
223 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
226 cx->ks[0] = ss[0] = word_in(key, 0);
227 cx->ks[1] = ss[1] = word_in(key, 1);
228 cx->ks[2] = ss[2] = word_in(key, 2);
229 cx->ks[3] = ss[3] = word_in(key, 3);
231 ke4(cx->ks, 0); ke4(cx->ks, 1);
232 ke4(cx->ks, 2); ke4(cx->ks, 3);
233 ke4(cx->ks, 4); ke4(cx->ks, 5);
234 ke4(cx->ks, 6); ke4(cx->ks, 7);
237 cx->inf.b[0] = 10 * 16;
241 { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
242 k[6*(i)+ 7] = ss[1] ^= ss[0]; \
243 k[6*(i)+ 8] = ss[2] ^= ss[1]; \
244 k[6*(i)+ 9] = ss[3] ^= ss[2]; \
249 k[6*(i)+10] = ss[4] ^= ss[3]; \
250 k[6*(i)+11] = ss[5] ^= ss[4]; \
253 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
256 cx->ks[0] = ss[0] = word_in(key, 0);
257 cx->ks[1] = ss[1] = word_in(key, 1);
258 cx->ks[2] = ss[2] = word_in(key, 2);
259 cx->ks[3] = ss[3] = word_in(key, 3);
260 cx->ks[4] = ss[4] = word_in(key, 4);
261 cx->ks[5] = ss[5] = word_in(key, 5);
263 ke6(cx->ks, 0); ke6(cx->ks, 1);
264 ke6(cx->ks, 2); ke6(cx->ks, 3);
265 ke6(cx->ks, 4); ke6(cx->ks, 5);
268 cx->inf.b[0] = 12 * 16;
272 { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
273 k[8*(i)+ 9] = ss[1] ^= ss[0]; \
274 k[8*(i)+10] = ss[2] ^= ss[1]; \
275 k[8*(i)+11] = ss[3] ^= ss[2]; \
280 k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
281 k[8*(i)+13] = ss[5] ^= ss[4]; \
282 k[8*(i)+14] = ss[6] ^= ss[5]; \
283 k[8*(i)+15] = ss[7] ^= ss[6]; \
286 AES_RETURN aes_encrypt_key256(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);
295 cx->ks[6] = ss[6] = word_in(key, 6);
296 cx->ks[7] = ss[7] = word_in(key, 7);
298 ke8(cx->ks, 0); ke8(cx->ks, 1);
299 ke8(cx->ks, 2); ke8(cx->ks, 3);
300 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);
367 cx->inf.b[0] = 10 * 16;
371 { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
372 k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
373 k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
374 k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
379 k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
380 k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
384 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
385 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
386 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
387 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
388 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
389 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
393 { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
394 ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
395 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
396 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
397 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
398 ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
399 ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
403 { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
404 ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
405 ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
406 ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
409 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
411 #if defined( d_vars )
414 cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
415 cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
416 cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
417 cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
419 cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
420 cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
421 kdf6(cx->ks, 0); kd6(cx->ks, 1);
422 kd6(cx->ks, 2); kd6(cx->ks, 3);
423 kd6(cx->ks, 4); kd6(cx->ks, 5);
424 kd6(cx->ks, 6); kdl6(cx->ks, 7);
425 cx->inf.b[0] = 12 * 16;
429 { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
430 k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
431 k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
432 k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
437 k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
438 k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
439 k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
440 k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
444 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
445 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
446 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
447 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
448 ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
449 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
450 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
451 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
455 { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
456 ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
457 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
458 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
459 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
460 ss[8] = ls_box(ss[3],0); \
461 ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
462 ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
463 ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
464 ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
468 { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
469 ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
470 ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
471 ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
474 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
476 #if defined( d_vars )
479 cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
480 cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
481 cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
482 cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
484 cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
485 cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
486 cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
487 cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
488 kdf8(cx->ks, 0); kd8(cx->ks, 1);
489 kd8(cx->ks, 2); kd8(cx->ks, 3);
490 kd8(cx->ks, 4); kd8(cx->ks, 5);
492 cx->inf.b[0] = 14 * 16;
495 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
499 case 16: case 128: aes_decrypt_key128(key, cx); return;
500 case 24: case 192: aes_decrypt_key192(key, cx); return;
501 case 32: case 256: aes_decrypt_key256(key, cx); return;
506 /* C version of AES */
508 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
509 #define so(y,x,c) word_out(y, c, s(x,c))
510 #define locals(y,x) x[4],y[4]
511 #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
512 s(y,2) = s(x,2); s(y,3) = s(x,3);
513 #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)
514 #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
515 #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)
517 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
518 Pentium optimiation with small code but this is poor for decryption
519 so we need to control this with the following VC++ pragmas
522 #if defined( _MSC_VER ) && !defined( _WIN64 )
523 #pragma optimize( "s", on )
526 #define fwd_var(x,r,c)\
527 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
528 : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
529 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
530 : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
531 #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
532 #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
534 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
535 { uint_32t locals(b0, b1);
539 state_in(b0, in, kp);
544 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
545 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
548 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
549 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
552 round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
553 round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
554 round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
555 round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
556 round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
557 round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
558 round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
559 round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
560 round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
561 round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
567 #define inv_var(x,r,c)\
568 ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
569 : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
570 : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
571 : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
573 #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
574 #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
576 #define rnd_key(n) (kp + n * N_COLS)
578 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
579 { uint_32t locals(b0, b1);
582 kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
583 state_in(b0, in, kp);
585 kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
589 round(inv_rnd, b1, b0, rnd_key(-13));
590 round(inv_rnd, b0, b1, rnd_key(-12));
592 round(inv_rnd, b1, b0, rnd_key(-11));
593 round(inv_rnd, b0, b1, rnd_key(-10));
595 round(inv_rnd, b1, b0, rnd_key(-9));
596 round(inv_rnd, b0, b1, rnd_key(-8));
597 round(inv_rnd, b1, b0, rnd_key(-7));
598 round(inv_rnd, b0, b1, rnd_key(-6));
599 round(inv_rnd, b1, b0, rnd_key(-5));
600 round(inv_rnd, b0, b1, rnd_key(-4));
601 round(inv_rnd, b1, b0, rnd_key(-3));
602 round(inv_rnd, b0, b1, rnd_key(-2));
603 round(inv_rnd, b1, b0, rnd_key(-1));
604 round(inv_lrnd, b0, b1, rnd_key( 0));
610 #if defined(__cplusplus)
614 #endif /* SILC_AES_ASM */