9fc9f1e663ec0450e0f0523b35c59616e2b18a9a
[silc.git] / lib / silccrypt / aes.c
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. */
4 /*
5  ---------------------------------------------------------------------------
6  Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
7
8  LICENSE TERMS
9
10  The free distribution and use of this software in both source and binary
11  form is allowed (with or without changes) provided that:
12
13    1. distributions of this source code include the above copyright
14       notice, this list of conditions and the following disclaimer;
15
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;
19
20    3. the copyright holder's name is not used to endorse products
21       built using this software without specific written permission.
22
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.
26
27  DISCLAIMER
28
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  ---------------------------------------------------------------------------
33  Issue 09/09/2006
34 */
35
36 #include "silc.h"
37 #include "rijndael_internal.h"
38 #include "aes.h"
39
40 /*
41  * SILC Crypto API for AES
42  */
43
44 /* Sets the key for the cipher. */
45
46 SILC_CIPHER_API_SET_KEY(aes)
47 {
48   aes_encrypt_key(key, keylen, &((AesContext *)context)->enc);
49   aes_decrypt_key(key, keylen, &((AesContext *)context)->dec);
50   return TRUE;
51 }
52
53 /* Returns the size of the cipher context. */
54
55 SILC_CIPHER_API_CONTEXT_LEN(aes)
56 {
57   return sizeof(AesContext);
58 }
59
60 /* Encrypts with the cipher in CBC mode. Source and destination buffers
61    maybe one and same. */
62
63 SILC_CIPHER_API_ENCRYPT_CBC(aes)
64 {
65   int nb = len >> 4;
66
67   while(nb--) {
68     lp32(iv)[0] ^= lp32(src)[0];
69     lp32(iv)[1] ^= lp32(src)[1];
70     lp32(iv)[2] ^= lp32(src)[2];
71     lp32(iv)[3] ^= lp32(src)[3];
72     aes_encrypt(iv, iv, &((AesContext *)context)->enc);
73     memcpy(dst, iv, 16);
74     src += 16;
75     dst += 16;
76   }
77
78   return TRUE;
79 }
80
81 /* Decrypts with the cipher in CBC mode. Source and destination buffers
82    maybe one and same. */
83
84 SILC_CIPHER_API_DECRYPT_CBC(aes)
85 {
86   unsigned char tmp[16];
87   int nb = len >> 4;
88
89   while(nb--) {
90     memcpy(tmp, src, 16);
91     aes_decrypt(src, dst, &((AesContext *)context)->dec);
92     lp32(dst)[0] ^= lp32(iv)[0];
93     lp32(dst)[1] ^= lp32(iv)[1];
94     lp32(dst)[2] ^= lp32(iv)[2];
95     lp32(dst)[3] ^= lp32(iv)[3];
96     memcpy(iv, tmp, 16);
97     src += 16;
98     dst += 16;
99   }
100
101   return TRUE;
102 }
103
104 /****************************************************************************/
105
106 #if defined(__cplusplus)
107 extern "C"
108 {
109 #endif
110
111 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
112 #  define XP_DIR __cdecl
113 #else
114 #  define XP_DIR
115 #endif
116
117 #define d_1(t,n,b,e)       ALIGN const XP_DIR t n[256]    =   b(e)
118 #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) }
119 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
120
121 #ifdef SILC_ASM_AES
122 d_1(uint_8t, t_dec(i,box), isb_data, h0);
123 #endif /* SILC_ASM_AES */
124 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
125 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
126 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
127 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
128 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
129
130 #define ke4(k,i) \
131 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
132     k[4*(i)+5] = ss[1] ^= ss[0]; \
133     k[4*(i)+6] = ss[2] ^= ss[1]; \
134     k[4*(i)+7] = ss[3] ^= ss[2]; \
135 }
136
137 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
138 {   uint_32t    ss[4];
139
140     cx->ks[0] = ss[0] = word_in(key, 0);
141     cx->ks[1] = ss[1] = word_in(key, 1);
142     cx->ks[2] = ss[2] = word_in(key, 2);
143     cx->ks[3] = ss[3] = word_in(key, 3);
144
145     ke4(cx->ks, 0);  ke4(cx->ks, 1);
146     ke4(cx->ks, 2);  ke4(cx->ks, 3);
147     ke4(cx->ks, 4);  ke4(cx->ks, 5);
148     ke4(cx->ks, 6);  ke4(cx->ks, 7);
149     ke4(cx->ks, 8);
150     ke4(cx->ks, 9);
151     cx->inf.l = 0;
152     cx->inf.b[0] = 10 * 16;
153 }
154
155 #define kef6(k,i) \
156 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
157     k[6*(i)+ 7] = ss[1] ^= ss[0]; \
158     k[6*(i)+ 8] = ss[2] ^= ss[1]; \
159     k[6*(i)+ 9] = ss[3] ^= ss[2]; \
160 }
161
162 #define ke6(k,i) \
163 {   kef6(k,i); \
164     k[6*(i)+10] = ss[4] ^= ss[3]; \
165     k[6*(i)+11] = ss[5] ^= ss[4]; \
166 }
167
168 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
169 {   uint_32t    ss[6];
170
171     cx->ks[0] = ss[0] = word_in(key, 0);
172     cx->ks[1] = ss[1] = word_in(key, 1);
173     cx->ks[2] = ss[2] = word_in(key, 2);
174     cx->ks[3] = ss[3] = word_in(key, 3);
175     cx->ks[4] = ss[4] = word_in(key, 4);
176     cx->ks[5] = ss[5] = word_in(key, 5);
177
178     ke6(cx->ks, 0);  ke6(cx->ks, 1);
179     ke6(cx->ks, 2);  ke6(cx->ks, 3);
180     ke6(cx->ks, 4);  ke6(cx->ks, 5);
181     ke6(cx->ks, 6);
182     kef6(cx->ks, 7);
183     cx->inf.l = 0;
184     cx->inf.b[0] = 12 * 16;
185 }
186
187 #define kef8(k,i) \
188 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
189     k[8*(i)+ 9] = ss[1] ^= ss[0]; \
190     k[8*(i)+10] = ss[2] ^= ss[1]; \
191     k[8*(i)+11] = ss[3] ^= ss[2]; \
192 }
193
194 #define ke8(k,i) \
195 {   kef8(k,i); \
196     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
197     k[8*(i)+13] = ss[5] ^= ss[4]; \
198     k[8*(i)+14] = ss[6] ^= ss[5]; \
199     k[8*(i)+15] = ss[7] ^= ss[6]; \
200 }
201
202 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
203 {   uint_32t    ss[8];
204
205     cx->ks[0] = ss[0] = word_in(key, 0);
206     cx->ks[1] = ss[1] = word_in(key, 1);
207     cx->ks[2] = ss[2] = word_in(key, 2);
208     cx->ks[3] = ss[3] = word_in(key, 3);
209     cx->ks[4] = ss[4] = word_in(key, 4);
210     cx->ks[5] = ss[5] = word_in(key, 5);
211     cx->ks[6] = ss[6] = word_in(key, 6);
212     cx->ks[7] = ss[7] = word_in(key, 7);
213
214     ke8(cx->ks, 0); ke8(cx->ks, 1);
215     ke8(cx->ks, 2); ke8(cx->ks, 3);
216     ke8(cx->ks, 4); ke8(cx->ks, 5);
217     kef8(cx->ks, 6);
218     cx->inf.l = 0;
219     cx->inf.b[0] = 14 * 16;
220 }
221
222 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
223 {
224     switch(key_len)
225     {
226     case 16: case 128: aes_encrypt_key128(key, cx); return;
227     case 24: case 192: aes_encrypt_key192(key, cx); return;
228     case 32: case 256: aes_encrypt_key256(key, cx); return;
229     }
230 }
231
232 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
233 #define k4e(k,i) \
234 {   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
235     k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
236     k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
237     k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
238 }
239
240 #define kdf4(k,i) \
241 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
242     ss[1] = ss[1] ^ ss[3]; \
243     ss[2] = ss[2] ^ ss[3]; \
244     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
245     ss[i % 4] ^= ss[4]; \
246     ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
247     ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
248     ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
249     ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
250 }
251
252 #define kd4(k,i) \
253 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
254     ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
255     k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
256     k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
257     k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
258     k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
259 }
260
261 #define kdl4(k,i) \
262 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
263     k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
264     k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
265     k[v(40,(4*(i))+6)] = ss[0]; \
266     k[v(40,(4*(i))+7)] = ss[1]; \
267 }
268
269 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
270 {   uint_32t    ss[5];
271 #if defined( d_vars )
272         d_vars;
273 #endif
274     cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
275     cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
276     cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
277     cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
278
279     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
280      kd4(cx->ks, 2);  kd4(cx->ks, 3);
281      kd4(cx->ks, 4);  kd4(cx->ks, 5);
282      kd4(cx->ks, 6);  kd4(cx->ks, 7);
283      kd4(cx->ks, 8); kdl4(cx->ks, 9);
284     cx->inf.l = 0;
285     cx->inf.b[0] = 10 * 16;
286 }
287
288 #define k6ef(k,i) \
289 {   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
290     k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
291     k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
292     k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
293 }
294
295 #define k6e(k,i) \
296 {   k6ef(k,i); \
297     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
298     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
299 }
300
301 #define kdf6(k,i) \
302 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
303     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
304     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
305     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
306     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
307     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
308 }
309
310 #define kd6(k,i) \
311 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
312     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
313     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
314     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
315     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
316     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
317     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
318 }
319
320 #define kdl6(k,i) \
321 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
322     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
323     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
324     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
325 }
326
327 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
328 {   uint_32t    ss[7];
329 #if defined( d_vars )
330         d_vars;
331 #endif
332     cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
333     cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
334     cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
335     cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
336
337     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
338     cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
339     kdf6(cx->ks, 0); kd6(cx->ks, 1);
340     kd6(cx->ks, 2);  kd6(cx->ks, 3);
341     kd6(cx->ks, 4);  kd6(cx->ks, 5);
342     kd6(cx->ks, 6); kdl6(cx->ks, 7);
343     cx->inf.l = 0;
344     cx->inf.b[0] = 12 * 16;
345 }
346
347 #define k8ef(k,i) \
348 {   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
349     k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
350     k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
351     k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
352 }
353
354 #define k8e(k,i) \
355 {   k8ef(k,i); \
356     k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
357     k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
358     k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
359     k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
360 }
361
362 #define kdf8(k,i) \
363 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
364     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
365     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
366     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
367     ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
368     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
369     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
370     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
371 }
372
373 #define kd8(k,i) \
374 {   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
375     ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
376     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
377     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
378     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
379     ss[8] = ls_box(ss[3],0); \
380     ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
381     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
382     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
383     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
384 }
385
386 #define kdl8(k,i) \
387 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
388     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
389     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
390     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
391 }
392
393 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
394 {   uint_32t    ss[9];
395 #if defined( d_vars )
396         d_vars;
397 #endif
398     cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
399     cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
400     cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
401     cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
402
403     cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
404     cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
405     cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
406     cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
407     kdf8(cx->ks, 0); kd8(cx->ks, 1);
408     kd8(cx->ks, 2);  kd8(cx->ks, 3);
409     kd8(cx->ks, 4);  kd8(cx->ks, 5);
410     kdl8(cx->ks, 6);
411     cx->inf.l = 0;
412     cx->inf.b[0] = 14 * 16;
413 }
414
415 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
416 {
417     switch(key_len)
418     {
419     case 16: case 128: aes_decrypt_key128(key, cx); return;
420     case 24: case 192: aes_decrypt_key192(key, cx); return;
421     case 32: case 256: aes_decrypt_key256(key, cx); return;
422     }
423 }
424
425 #ifndef SILC_ASM_AES
426 /* C version of AES */
427
428 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
429 #define so(y,x,c)   word_out(y, c, s(x,c))
430 #define locals(y,x)     x[4],y[4]
431 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
432                         s(y,2) = s(x,2); s(y,3) = s(x,3);
433 #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)
434 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
435 #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)
436
437 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
438    Pentium optimiation with small code but this is poor for decryption
439    so we need to control this with the following VC++ pragmas
440 */
441
442 #if defined( _MSC_VER ) && !defined( _WIN64 )
443 #pragma optimize( "s", on )
444 #endif
445
446 #define fwd_var(x,r,c)\
447  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
448  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
449  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
450  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
451 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
452 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
453
454 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
455 {   uint_32t         locals(b0, b1);
456     const uint_32t   *kp;
457
458     kp = cx->ks;
459     state_in(b0, in, kp);
460
461     switch(cx->inf.b[0])
462     {
463     case 14 * 16:
464         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
465         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
466         kp += 2 * N_COLS;
467     case 12 * 16:
468         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
469         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
470         kp += 2 * N_COLS;
471     case 10 * 16:
472         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
473         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
474         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
475         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
476         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
477         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
478         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
479         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
480         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
481         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
482     }
483
484     state_out(out, b0);
485 }
486
487 #define inv_var(x,r,c)\
488  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
489  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
490  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
491  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
492
493 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
494 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
495 #define key_ofs     0
496 #define rnd_key(n)  (kp + n * N_COLS)
497
498 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
499 {   uint_32t        locals(b0, b1);
500     const uint_32t *kp;
501
502     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
503     state_in(b0, in, kp);
504
505     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
506     switch(cx->inf.b[0])
507     {
508     case 14 * 16:
509         round(inv_rnd,  b1, b0, rnd_key(-13));
510         round(inv_rnd,  b0, b1, rnd_key(-12));
511     case 12 * 16:
512         round(inv_rnd,  b1, b0, rnd_key(-11));
513         round(inv_rnd,  b0, b1, rnd_key(-10));
514     case 10 * 16:
515         round(inv_rnd,  b1, b0, rnd_key(-9));
516         round(inv_rnd,  b0, b1, rnd_key(-8));
517         round(inv_rnd,  b1, b0, rnd_key(-7));
518         round(inv_rnd,  b0, b1, rnd_key(-6));
519         round(inv_rnd,  b1, b0, rnd_key(-5));
520         round(inv_rnd,  b0, b1, rnd_key(-4));
521         round(inv_rnd,  b1, b0, rnd_key(-3));
522         round(inv_rnd,  b0, b1, rnd_key(-2));
523         round(inv_rnd,  b1, b0, rnd_key(-1));
524         round(inv_lrnd, b0, b1, rnd_key( 0));
525     }
526
527     state_out(out, b0);
528 }
529
530 #if defined(__cplusplus)
531 }
532 #endif
533
534 #endif /* SILC_ASM_AES */