Static analyzer bug fixes
[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     ss[4] = word_in(key, 4);
457     cx->ks[v(48,(4))] = ff(ss[4]);
458     ss[5] = word_in(key, 5);
459     cx->ks[v(48,(5))] = ff(ss[5]);
460     kdf6(cx->ks, 0); kd6(cx->ks, 1);
461     kd6(cx->ks, 2);  kd6(cx->ks, 3);
462     kd6(cx->ks, 4);  kd6(cx->ks, 5);
463     kd6(cx->ks, 6); kdl6(cx->ks, 7);
464     cx->inf.l = 0;
465     cx->inf.b[0] = 12 * 16;
466 }
467
468 #define k8ef(k,i) \
469 {   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
470     k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
471     k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
472     k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
473 }
474
475 #define k8e(k,i) \
476 {   k8ef(k,i); \
477     k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
478     k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
479     k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
480     k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
481 }
482
483 #define kdf8(k,i) \
484 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
485     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
486     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
487     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
488     ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
489     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
490     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
491     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
492 }
493
494 #define kd8(k,i) \
495 {   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
496     ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
497     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
498     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
499     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
500     ss[8] = ls_box(ss[3],0); \
501     ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
502     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
503     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
504     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
505 }
506
507 #define kdl8(k,i) \
508 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
509     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
510     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
511     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
512 }
513
514 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
515 {   uint_32t    ss[9];
516 #if defined( d_vars )
517         d_vars;
518 #endif
519     cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
520     cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
521     cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
522     cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
523
524     ss[4] = word_in(key, 4);
525     cx->ks[v(56,(4))] = ff(ss[4]);
526     ss[5] = word_in(key, 5);
527     cx->ks[v(56,(5))] = ff(ss[5]);
528     ss[6] = word_in(key, 6);
529     cx->ks[v(56,(6))] = ff(ss[6]);
530     ss[7] = word_in(key, 7);
531     cx->ks[v(56,(7))] = ff(ss[7]);
532     kdf8(cx->ks, 0); kd8(cx->ks, 1);
533     kd8(cx->ks, 2);  kd8(cx->ks, 3);
534     kd8(cx->ks, 4);  kd8(cx->ks, 5);
535     kdl8(cx->ks, 6);
536     cx->inf.l = 0;
537     cx->inf.b[0] = 14 * 16;
538 }
539
540 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
541 {
542     switch(key_len)
543     {
544     case 16: case 128: aes_decrypt_key128(key, cx); return;
545     case 24: case 192: aes_decrypt_key192(key, cx); return;
546     case 32: case 256: aes_decrypt_key256(key, cx); return;
547     }
548 }
549
550 #ifndef SILC_AES_ASM
551 /* C version of AES */
552
553 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
554 #define so(y,x,c)   word_out(y, c, s(x,c))
555 #define locals(y,x)     x[4],y[4]
556 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
557                         s(y,2) = s(x,2); s(y,3) = s(x,3);
558 #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)
559 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
560 #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)
561
562 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
563    Pentium optimiation with small code but this is poor for decryption
564    so we need to control this with the following VC++ pragmas
565 */
566
567 #if defined( _MSC_VER ) && !defined( _WIN64 )
568 #pragma optimize( "s", on )
569 #endif
570
571 #define fwd_var(x,r,c)\
572  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
573  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
574  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
575  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
576 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
577 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
578
579 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
580 {   uint_32t         locals(b0, b1);
581     const uint_32t   *kp;
582
583     kp = cx->ks;
584     state_in(b0, in, kp);
585
586     switch(cx->inf.b[0])
587     {
588     case 14 * 16:
589         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
590         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
591         kp += 2 * N_COLS;
592     case 12 * 16:
593         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
594         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
595         kp += 2 * N_COLS;
596     case 10 * 16:
597         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
598         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
599         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
600         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
601         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
602         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
603         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
604         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
605         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
606         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
607     }
608
609     state_out(out, b0);
610 }
611
612 #define inv_var(x,r,c)\
613  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
614  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
615  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
616  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
617
618 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
619 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
620 #define key_ofs     0
621 #define rnd_key(n)  (kp + n * N_COLS)
622
623 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
624 {   uint_32t        locals(b0, b1);
625     const uint_32t *kp;
626
627     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
628     state_in(b0, in, kp);
629
630     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
631     switch(cx->inf.b[0])
632     {
633     case 14 * 16:
634         round(inv_rnd,  b1, b0, rnd_key(-13));
635         round(inv_rnd,  b0, b1, rnd_key(-12));
636     case 12 * 16:
637         round(inv_rnd,  b1, b0, rnd_key(-11));
638         round(inv_rnd,  b0, b1, rnd_key(-10));
639     case 10 * 16:
640         round(inv_rnd,  b1, b0, rnd_key(-9));
641         round(inv_rnd,  b0, b1, rnd_key(-8));
642         round(inv_rnd,  b1, b0, rnd_key(-7));
643         round(inv_rnd,  b0, b1, rnd_key(-6));
644         round(inv_rnd,  b1, b0, rnd_key(-5));
645         round(inv_rnd,  b0, b1, rnd_key(-4));
646         round(inv_rnd,  b1, b0, rnd_key(-3));
647         round(inv_rnd,  b0, b1, rnd_key(-2));
648         round(inv_rnd,  b1, b0, rnd_key(-1));
649         round(inv_lrnd, b0, b1, rnd_key( 0));
650     }
651
652     state_out(out, b0);
653 }
654
655 #if defined(__cplusplus)
656 }
657 #endif
658
659 #endif /* SILC_AES_ASM */