27a47cc95b43731f69c3f5fd33697fcf9811f8d3
[crypto.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 "silccrypto.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   switch (cipher->mode) {
49   case SILC_CIPHER_MODE_CBC:
50     if (encryption)
51       aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
52     else
53       aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
54     break;
55
56   case SILC_CIPHER_MODE_CTR:
57   case SILC_CIPHER_MODE_CFB:
58     aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
59     break;
60
61   default:
62     return FALSE;
63   }
64   return TRUE;
65 }
66
67 /* Sets IV for the cipher. */
68
69 SILC_CIPHER_API_SET_IV(aes)
70 {
71   AesContext *aes = context;
72
73   switch (cipher->mode) {
74
75   case SILC_CIPHER_MODE_CTR:
76     /* Starts new block. */
77     aes->u.enc.inf.b[2] = 0;
78     break;
79
80   case SILC_CIPHER_MODE_CFB:
81     /* Starts new block. */
82     aes->u.enc.inf.b[2] = 16;
83     break;
84
85   default:
86     break;
87   }
88 }
89
90 /* Returns the size of the cipher context. */
91
92 SILC_CIPHER_API_CONTEXT_LEN(aes)
93 {
94   return sizeof(AesContext);
95 }
96
97 /* Encrypts with the cipher. Source and destination buffers maybe one and
98    same. */
99
100 SILC_CIPHER_API_ENCRYPT(aes)
101 {
102   AesContext *aes = context;
103   SilcUInt32 ctr[4];
104
105   switch (cipher->mode) {
106   case SILC_CIPHER_MODE_CBC:
107     {
108       int nb = len >> 4;
109
110       SILC_ASSERT((len & (16 - 1)) == 0);
111       if (len & (16 - 1))
112         return FALSE;
113
114       while(nb--) {
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);
120         memcpy(dst, iv, 16);
121         src += 16;
122         dst += 16;
123       }
124     }
125     break;
126
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));
130     break;
131
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));
135     break;
136
137   default:
138     return FALSE;
139   }
140
141   return TRUE;
142 }
143
144 /* Decrypts with the cipher. Source and destination buffers maybe one
145    and same. */
146
147 SILC_CIPHER_API_DECRYPT(aes)
148 {
149   AesContext *aes = context;
150
151   switch (cipher->mode) {
152   case SILC_CIPHER_MODE_CBC:
153     {
154       unsigned char tmp[16];
155       int nb = len >> 4;
156
157       if (len & (16 - 1))
158         return FALSE;
159
160       while(nb--) {
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];
167         memcpy(iv, tmp, 16);
168         src += 16;
169         dst += 16;
170       }
171     }
172     break;
173
174   case SILC_CIPHER_MODE_CTR:
175     return silc_aes_encrypt(cipher, context, src, dst, len, iv);
176     break;
177
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));
181     break;
182
183   default:
184     return FALSE;
185   }
186
187   return TRUE;
188 }
189
190 /****************************************************************************/
191
192 #if defined(__cplusplus)
193 extern "C"
194 {
195 #endif
196
197 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
198 #  define XP_DIR __cdecl
199 #else
200 #  define XP_DIR
201 #endif
202
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);
206
207 #ifdef SILC_AES_ASM
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);
215
216 #define ke4(k,i) \
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]; \
221 }
222
223 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
224 {   uint_32t    ss[4];
225
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);
230
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);
235     ke4(cx->ks, 8);
236     ke4(cx->ks, 9);
237     cx->inf.b[0] = 10 * 16;
238 }
239
240 #define kef6(k,i) \
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]; \
245 }
246
247 #define ke6(k,i) \
248 {   kef6(k,i); \
249     k[6*(i)+10] = ss[4] ^= ss[3]; \
250     k[6*(i)+11] = ss[5] ^= ss[4]; \
251 }
252
253 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
254 {   uint_32t    ss[6];
255
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);
262
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);
266     ke6(cx->ks, 6);
267     kef6(cx->ks, 7);
268     cx->inf.b[0] = 12 * 16;
269 }
270
271 #define kef8(k,i) \
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]; \
276 }
277
278 #define ke8(k,i) \
279 {   kef8(k,i); \
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]; \
284 }
285
286 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
287 {   uint_32t    ss[8];
288
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);
297
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);
301     kef8(cx->ks, 6);
302     cx->inf.b[0] = 14 * 16;
303 }
304
305 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
306 {
307     switch(key_len)
308     {
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;
312     }
313 }
314
315 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
316 #define k4e(k,i) \
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]; \
321 }
322
323 #define kdf4(k,i) \
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]); \
333 }
334
335 #define kd4(k,i) \
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)]; \
342 }
343
344 #define kdl4(k,i) \
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]; \
350 }
351
352 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
353 {   uint_32t    ss[5];
354 #if defined( d_vars )
355         d_vars;
356 #endif
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);
361
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;
368 }
369
370 #define k6ef(k,i) \
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]; \
375 }
376
377 #define k6e(k,i) \
378 {   k6ef(k,i); \
379     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
380     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
381 }
382
383 #define kdf6(k,i) \
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]); \
390 }
391
392 #define kd6(k,i) \
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)]; \
400 }
401
402 #define kdl6(k,i) \
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]; \
407 }
408
409 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
410 {   uint_32t    ss[7];
411 #if defined( d_vars )
412         d_vars;
413 #endif
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);
418
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;
426 }
427
428 #define k8ef(k,i) \
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]; \
433 }
434
435 #define k8e(k,i) \
436 {   k8ef(k,i); \
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]; \
441 }
442
443 #define kdf8(k,i) \
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]); \
452 }
453
454 #define kd8(k,i) \
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)]; \
465 }
466
467 #define kdl8(k,i) \
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]; \
472 }
473
474 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
475 {   uint_32t    ss[9];
476 #if defined( d_vars )
477         d_vars;
478 #endif
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);
483
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);
491     kdl8(cx->ks, 6);
492     cx->inf.b[0] = 14 * 16;
493 }
494
495 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
496 {
497     switch(key_len)
498     {
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;
502     }
503 }
504
505 #ifndef SILC_AES_ASM
506 /* C version of AES */
507
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)
516
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
520 */
521
522 #if defined( _MSC_VER ) && !defined( _WIN64 )
523 #pragma optimize( "s", on )
524 #endif
525
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))
533
534 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
535 {   uint_32t         locals(b0, b1);
536     const uint_32t   *kp;
537
538     kp = cx->ks;
539     state_in(b0, in, kp);
540
541     switch(cx->inf.b[0])
542     {
543     case 14 * 16:
544         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
545         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
546         kp += 2 * N_COLS;
547     case 12 * 16:
548         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
549         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
550         kp += 2 * N_COLS;
551     case 10 * 16:
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);
562     }
563
564     state_out(out, b0);
565 }
566
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)))
572
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))
575 #define key_ofs     0
576 #define rnd_key(n)  (kp + n * N_COLS)
577
578 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
579 {   uint_32t        locals(b0, b1);
580     const uint_32t *kp;
581
582     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
583     state_in(b0, in, kp);
584
585     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
586     switch(cx->inf.b[0])
587     {
588     case 14 * 16:
589         round(inv_rnd,  b1, b0, rnd_key(-13));
590         round(inv_rnd,  b0, b1, rnd_key(-12));
591     case 12 * 16:
592         round(inv_rnd,  b1, b0, rnd_key(-11));
593         round(inv_rnd,  b0, b1, rnd_key(-10));
594     case 10 * 16:
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));
605     }
606
607     state_out(out, b0);
608 }
609
610 #if defined(__cplusplus)
611 }
612 #endif
613
614 #endif /* SILC_AES_ASM */