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