Added CAST5 (CAST-128) cipher, Added CTR mode to twofish, unified
[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 "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   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     aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
58     break;
59
60   default:
61     return FALSE;
62   }
63   return TRUE;
64 }
65
66 /* Sets IV for the cipher. */
67
68 SILC_CIPHER_API_SET_IV(aes)
69 {
70   if (cipher->mode == SILC_CIPHER_MODE_CTR) {
71     AesContext *aes = context;
72
73     /* Starts new block. */
74     aes->u.enc.inf.b[2] = 0;
75   }
76 }
77
78 /* Returns the size of the cipher context. */
79
80 SILC_CIPHER_API_CONTEXT_LEN(aes)
81 {
82   return sizeof(AesContext);
83 }
84
85 /* Encrypts with the cipher. Source and destination buffers maybe one and
86    same. */
87
88 SILC_CIPHER_API_ENCRYPT(aes)
89 {
90   AesContext *aes = context;
91   int i;
92
93   switch (cipher->mode) {
94   case SILC_CIPHER_MODE_CBC:
95     {
96       int nb = len >> 4;
97
98       SILC_ASSERT((len & (16 - 1)) == 0);
99       if (len & (16 - 1))
100         return FALSE;
101
102       while(nb--) {
103         lp32(iv)[0] ^= lp32(src)[0];
104         lp32(iv)[1] ^= lp32(src)[1];
105         lp32(iv)[2] ^= lp32(src)[2];
106         lp32(iv)[3] ^= lp32(src)[3];
107         aes_encrypt(iv, iv, &aes->u.enc);
108         memcpy(dst, iv, 16);
109         src += 16;
110         dst += 16;
111       }
112     }
113     break;
114
115   case SILC_CIPHER_MODE_CTR:
116     {
117       SilcUInt32 ctr[4];
118
119       SILC_GET32_MSB(ctr[0], iv);
120       SILC_GET32_MSB(ctr[1], iv + 4);
121       SILC_GET32_MSB(ctr[2], iv + 8);
122       SILC_GET32_MSB(ctr[3], iv + 12);
123
124       i = aes->u.enc.inf.b[2];
125       if (!i)
126         i = 16;
127
128       while (len-- > 0) {
129         if (i == 16) {
130           if (++ctr[3] == 0)
131             if (++ctr[2] == 0)
132               if (++ctr[1] == 0)
133                 ++ctr[0];
134
135           SILC_PUT32_MSB(ctr[0], iv);
136           SILC_PUT32_MSB(ctr[1], iv + 4);
137           SILC_PUT32_MSB(ctr[2], iv + 8);
138           SILC_PUT32_MSB(ctr[3], iv + 12);
139
140           aes_encrypt(iv, iv, &aes->u.enc);
141           i = 0;
142         }
143         *dst++ = *src++ ^ iv[i++];
144       }
145       aes->u.enc.inf.b[2] = i;
146
147       SILC_PUT32_MSB(ctr[0], iv);
148       SILC_PUT32_MSB(ctr[1], iv + 4);
149       SILC_PUT32_MSB(ctr[2], iv + 8);
150       SILC_PUT32_MSB(ctr[3], iv + 12);
151     }
152     break;
153
154   default:
155     return FALSE;
156   }
157
158   return TRUE;
159 }
160
161 /* Decrypts with the cipher. Source and destination buffers maybe one
162    and same. */
163
164 SILC_CIPHER_API_DECRYPT(aes)
165 {
166   switch (cipher->mode) {
167   case SILC_CIPHER_MODE_CBC:
168     {
169       unsigned char tmp[16];
170       int nb = len >> 4;
171
172       if (len & (16 - 1))
173         return FALSE;
174
175       while(nb--) {
176         memcpy(tmp, src, 16);
177         aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
178         lp32(dst)[0] ^= lp32(iv)[0];
179         lp32(dst)[1] ^= lp32(iv)[1];
180         lp32(dst)[2] ^= lp32(iv)[2];
181         lp32(dst)[3] ^= lp32(iv)[3];
182         memcpy(iv, tmp, 16);
183         src += 16;
184         dst += 16;
185       }
186     }
187     break;
188
189   case SILC_CIPHER_MODE_CTR:
190     return silc_aes_encrypt(cipher, context, src, dst, len, iv);
191     break;
192
193   default:
194     return FALSE;
195   }
196
197   return TRUE;
198 }
199
200 /****************************************************************************/
201
202 #if defined(__cplusplus)
203 extern "C"
204 {
205 #endif
206
207 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
208 #  define XP_DIR __cdecl
209 #else
210 #  define XP_DIR
211 #endif
212
213 #define d_1(t,n,b,e)       ALIGN const XP_DIR t n[256]    =   b(e)
214 #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) }
215 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
216
217 #ifdef SILC_AES_ASM
218 d_1(uint_8t, t_dec(i,box), isb_data, h0);
219 #endif /* SILC_AES_ASM */
220 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
221 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
222 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
223 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
224 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
225
226 #define ke4(k,i) \
227 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
228     k[4*(i)+5] = ss[1] ^= ss[0]; \
229     k[4*(i)+6] = ss[2] ^= ss[1]; \
230     k[4*(i)+7] = ss[3] ^= ss[2]; \
231 }
232
233 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
234 {   uint_32t    ss[4];
235
236     cx->ks[0] = ss[0] = word_in(key, 0);
237     cx->ks[1] = ss[1] = word_in(key, 1);
238     cx->ks[2] = ss[2] = word_in(key, 2);
239     cx->ks[3] = ss[3] = word_in(key, 3);
240
241     ke4(cx->ks, 0);  ke4(cx->ks, 1);
242     ke4(cx->ks, 2);  ke4(cx->ks, 3);
243     ke4(cx->ks, 4);  ke4(cx->ks, 5);
244     ke4(cx->ks, 6);  ke4(cx->ks, 7);
245     ke4(cx->ks, 8);
246     ke4(cx->ks, 9);
247     cx->inf.l = 0;
248     cx->inf.b[0] = 10 * 16;
249 }
250
251 #define kef6(k,i) \
252 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
253     k[6*(i)+ 7] = ss[1] ^= ss[0]; \
254     k[6*(i)+ 8] = ss[2] ^= ss[1]; \
255     k[6*(i)+ 9] = ss[3] ^= ss[2]; \
256 }
257
258 #define ke6(k,i) \
259 {   kef6(k,i); \
260     k[6*(i)+10] = ss[4] ^= ss[3]; \
261     k[6*(i)+11] = ss[5] ^= ss[4]; \
262 }
263
264 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
265 {   uint_32t    ss[6];
266
267     cx->ks[0] = ss[0] = word_in(key, 0);
268     cx->ks[1] = ss[1] = word_in(key, 1);
269     cx->ks[2] = ss[2] = word_in(key, 2);
270     cx->ks[3] = ss[3] = word_in(key, 3);
271     cx->ks[4] = ss[4] = word_in(key, 4);
272     cx->ks[5] = ss[5] = word_in(key, 5);
273
274     ke6(cx->ks, 0);  ke6(cx->ks, 1);
275     ke6(cx->ks, 2);  ke6(cx->ks, 3);
276     ke6(cx->ks, 4);  ke6(cx->ks, 5);
277     ke6(cx->ks, 6);
278     kef6(cx->ks, 7);
279     cx->inf.l = 0;
280     cx->inf.b[0] = 12 * 16;
281 }
282
283 #define kef8(k,i) \
284 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
285     k[8*(i)+ 9] = ss[1] ^= ss[0]; \
286     k[8*(i)+10] = ss[2] ^= ss[1]; \
287     k[8*(i)+11] = ss[3] ^= ss[2]; \
288 }
289
290 #define ke8(k,i) \
291 {   kef8(k,i); \
292     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
293     k[8*(i)+13] = ss[5] ^= ss[4]; \
294     k[8*(i)+14] = ss[6] ^= ss[5]; \
295     k[8*(i)+15] = ss[7] ^= ss[6]; \
296 }
297
298 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
299 {   uint_32t    ss[8];
300
301     cx->ks[0] = ss[0] = word_in(key, 0);
302     cx->ks[1] = ss[1] = word_in(key, 1);
303     cx->ks[2] = ss[2] = word_in(key, 2);
304     cx->ks[3] = ss[3] = word_in(key, 3);
305     cx->ks[4] = ss[4] = word_in(key, 4);
306     cx->ks[5] = ss[5] = word_in(key, 5);
307     cx->ks[6] = ss[6] = word_in(key, 6);
308     cx->ks[7] = ss[7] = word_in(key, 7);
309
310     ke8(cx->ks, 0); ke8(cx->ks, 1);
311     ke8(cx->ks, 2); ke8(cx->ks, 3);
312     ke8(cx->ks, 4); ke8(cx->ks, 5);
313     kef8(cx->ks, 6);
314     cx->inf.l = 0;
315     cx->inf.b[0] = 14 * 16;
316 }
317
318 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
319 {
320     switch(key_len)
321     {
322     case 16: case 128: aes_encrypt_key128(key, cx); return;
323     case 24: case 192: aes_encrypt_key192(key, cx); return;
324     case 32: case 256: aes_encrypt_key256(key, cx); return;
325     }
326 }
327
328 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
329 #define k4e(k,i) \
330 {   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
331     k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
332     k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
333     k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
334 }
335
336 #define kdf4(k,i) \
337 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
338     ss[1] = ss[1] ^ ss[3]; \
339     ss[2] = ss[2] ^ ss[3]; \
340     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
341     ss[i % 4] ^= ss[4]; \
342     ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
343     ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
344     ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
345     ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
346 }
347
348 #define kd4(k,i) \
349 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
350     ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
351     k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
352     k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
353     k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
354     k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
355 }
356
357 #define kdl4(k,i) \
358 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
359     k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
360     k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
361     k[v(40,(4*(i))+6)] = ss[0]; \
362     k[v(40,(4*(i))+7)] = ss[1]; \
363 }
364
365 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
366 {   uint_32t    ss[5];
367 #if defined( d_vars )
368         d_vars;
369 #endif
370     cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
371     cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
372     cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
373     cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
374
375     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
376      kd4(cx->ks, 2);  kd4(cx->ks, 3);
377      kd4(cx->ks, 4);  kd4(cx->ks, 5);
378      kd4(cx->ks, 6);  kd4(cx->ks, 7);
379      kd4(cx->ks, 8); kdl4(cx->ks, 9);
380     cx->inf.l = 0;
381     cx->inf.b[0] = 10 * 16;
382 }
383
384 #define k6ef(k,i) \
385 {   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
386     k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
387     k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
388     k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
389 }
390
391 #define k6e(k,i) \
392 {   k6ef(k,i); \
393     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
394     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
395 }
396
397 #define kdf6(k,i) \
398 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
399     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
400     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
401     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
402     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
403     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
404 }
405
406 #define kd6(k,i) \
407 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
408     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
409     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
410     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
411     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
412     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
413     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
414 }
415
416 #define kdl6(k,i) \
417 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
418     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
419     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
420     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
421 }
422
423 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
424 {   uint_32t    ss[7];
425 #if defined( d_vars )
426         d_vars;
427 #endif
428     cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
429     cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
430     cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
431     cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
432
433     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
434     cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
435     kdf6(cx->ks, 0); kd6(cx->ks, 1);
436     kd6(cx->ks, 2);  kd6(cx->ks, 3);
437     kd6(cx->ks, 4);  kd6(cx->ks, 5);
438     kd6(cx->ks, 6); kdl6(cx->ks, 7);
439     cx->inf.l = 0;
440     cx->inf.b[0] = 12 * 16;
441 }
442
443 #define k8ef(k,i) \
444 {   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
445     k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
446     k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
447     k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
448 }
449
450 #define k8e(k,i) \
451 {   k8ef(k,i); \
452     k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
453     k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
454     k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
455     k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
456 }
457
458 #define kdf8(k,i) \
459 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
460     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
461     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
462     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
463     ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
464     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
465     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
466     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
467 }
468
469 #define kd8(k,i) \
470 {   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
471     ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
472     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
473     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
474     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
475     ss[8] = ls_box(ss[3],0); \
476     ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
477     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
478     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
479     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
480 }
481
482 #define kdl8(k,i) \
483 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
484     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
485     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
486     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
487 }
488
489 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
490 {   uint_32t    ss[9];
491 #if defined( d_vars )
492         d_vars;
493 #endif
494     cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
495     cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
496     cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
497     cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
498
499     cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
500     cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
501     cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
502     cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
503     kdf8(cx->ks, 0); kd8(cx->ks, 1);
504     kd8(cx->ks, 2);  kd8(cx->ks, 3);
505     kd8(cx->ks, 4);  kd8(cx->ks, 5);
506     kdl8(cx->ks, 6);
507     cx->inf.l = 0;
508     cx->inf.b[0] = 14 * 16;
509 }
510
511 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
512 {
513     switch(key_len)
514     {
515     case 16: case 128: aes_decrypt_key128(key, cx); return;
516     case 24: case 192: aes_decrypt_key192(key, cx); return;
517     case 32: case 256: aes_decrypt_key256(key, cx); return;
518     }
519 }
520
521 #ifndef SILC_AES_ASM
522 /* C version of AES */
523
524 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
525 #define so(y,x,c)   word_out(y, c, s(x,c))
526 #define locals(y,x)     x[4],y[4]
527 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
528                         s(y,2) = s(x,2); s(y,3) = s(x,3);
529 #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)
530 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
531 #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)
532
533 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
534    Pentium optimiation with small code but this is poor for decryption
535    so we need to control this with the following VC++ pragmas
536 */
537
538 #if defined( _MSC_VER ) && !defined( _WIN64 )
539 #pragma optimize( "s", on )
540 #endif
541
542 #define fwd_var(x,r,c)\
543  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
544  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
545  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
546  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
547 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
548 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
549
550 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
551 {   uint_32t         locals(b0, b1);
552     const uint_32t   *kp;
553
554     kp = cx->ks;
555     state_in(b0, in, kp);
556
557     switch(cx->inf.b[0])
558     {
559     case 14 * 16:
560         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
561         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
562         kp += 2 * N_COLS;
563     case 12 * 16:
564         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
565         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
566         kp += 2 * N_COLS;
567     case 10 * 16:
568         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
569         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
570         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
571         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
572         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
573         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
574         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
575         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
576         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
577         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
578     }
579
580     state_out(out, b0);
581 }
582
583 #define inv_var(x,r,c)\
584  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
585  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
586  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
587  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
588
589 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
590 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
591 #define key_ofs     0
592 #define rnd_key(n)  (kp + n * N_COLS)
593
594 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
595 {   uint_32t        locals(b0, b1);
596     const uint_32t *kp;
597
598     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
599     state_in(b0, in, kp);
600
601     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
602     switch(cx->inf.b[0])
603     {
604     case 14 * 16:
605         round(inv_rnd,  b1, b0, rnd_key(-13));
606         round(inv_rnd,  b0, b1, rnd_key(-12));
607     case 12 * 16:
608         round(inv_rnd,  b1, b0, rnd_key(-11));
609         round(inv_rnd,  b0, b1, rnd_key(-10));
610     case 10 * 16:
611         round(inv_rnd,  b1, b0, rnd_key(-9));
612         round(inv_rnd,  b0, b1, rnd_key(-8));
613         round(inv_rnd,  b1, b0, rnd_key(-7));
614         round(inv_rnd,  b0, b1, rnd_key(-6));
615         round(inv_rnd,  b1, b0, rnd_key(-5));
616         round(inv_rnd,  b0, b1, rnd_key(-4));
617         round(inv_rnd,  b1, b0, rnd_key(-3));
618         round(inv_rnd,  b0, b1, rnd_key(-2));
619         round(inv_rnd,  b1, b0, rnd_key(-1));
620         round(inv_lrnd, b0, b1, rnd_key( 0));
621     }
622
623     state_out(out, b0);
624 }
625
626 #if defined(__cplusplus)
627 }
628 #endif
629
630 #endif /* SILC_AES_ASM */