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