9c5a2f196ee5d93ed7e9c893ea912c8a5e4a7268
[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   SilcUInt32 ctr[4];
194   int i;
195
196   SILC_GET32_MSB(ctr[0], iv);
197   SILC_GET32_MSB(ctr[1], iv + 4);
198   SILC_GET32_MSB(ctr[2], iv + 8);
199   SILC_GET32_MSB(ctr[3], iv + 12);
200
201   i = aes->u.enc.inf.b[2];
202   if (!i)
203     i = 16;
204
205   while (len-- > 0) {
206     if (i == 16) {
207       if (++ctr[3] == 0)
208         if (++ctr[2] == 0)
209           if (++ctr[1] == 0)
210             ++ctr[0];
211
212       SILC_PUT32_MSB(ctr[0], iv);
213       SILC_PUT32_MSB(ctr[1], iv + 4);
214       SILC_PUT32_MSB(ctr[2], iv + 8);
215       SILC_PUT32_MSB(ctr[3], iv + 12);
216
217       aes_encrypt(iv, iv, &aes->u.enc);
218       i = 0;
219     }
220     *dst++ = *src++ ^ iv[i++];
221   }
222   aes->u.enc.inf.b[2] = i;
223
224   SILC_PUT32_MSB(ctr[0], iv);
225   SILC_PUT32_MSB(ctr[1], iv + 4);
226   SILC_PUT32_MSB(ctr[2], iv + 8);
227   SILC_PUT32_MSB(ctr[3], iv + 12);
228
229   return TRUE;
230 }
231
232 /* Decrypts with the cipher in CTR mode. Source and destination buffers
233    maybe one and same. */
234
235 SILC_CIPHER_API_DECRYPT(aes_ctr)
236 {
237   return silc_aes_ctr_encrypt(context, src, dst, len, iv);
238 }
239
240 /****************************************************************************/
241
242 #if defined(__cplusplus)
243 extern "C"
244 {
245 #endif
246
247 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
248 #  define XP_DIR __cdecl
249 #else
250 #  define XP_DIR
251 #endif
252
253 #define d_1(t,n,b,e)       ALIGN const XP_DIR t n[256]    =   b(e)
254 #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) }
255 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
256
257 #ifdef SILC_AES_ASM
258 d_1(uint_8t, t_dec(i,box), isb_data, h0);
259 #endif /* SILC_AES_ASM */
260 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
261 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
262 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
263 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
264 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
265
266 #define ke4(k,i) \
267 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
268     k[4*(i)+5] = ss[1] ^= ss[0]; \
269     k[4*(i)+6] = ss[2] ^= ss[1]; \
270     k[4*(i)+7] = ss[3] ^= ss[2]; \
271 }
272
273 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
274 {   uint_32t    ss[4];
275
276     cx->ks[0] = ss[0] = word_in(key, 0);
277     cx->ks[1] = ss[1] = word_in(key, 1);
278     cx->ks[2] = ss[2] = word_in(key, 2);
279     cx->ks[3] = ss[3] = word_in(key, 3);
280
281     ke4(cx->ks, 0);  ke4(cx->ks, 1);
282     ke4(cx->ks, 2);  ke4(cx->ks, 3);
283     ke4(cx->ks, 4);  ke4(cx->ks, 5);
284     ke4(cx->ks, 6);  ke4(cx->ks, 7);
285     ke4(cx->ks, 8);
286     ke4(cx->ks, 9);
287     cx->inf.l = 0;
288     cx->inf.b[0] = 10 * 16;
289 }
290
291 #define kef6(k,i) \
292 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
293     k[6*(i)+ 7] = ss[1] ^= ss[0]; \
294     k[6*(i)+ 8] = ss[2] ^= ss[1]; \
295     k[6*(i)+ 9] = ss[3] ^= ss[2]; \
296 }
297
298 #define ke6(k,i) \
299 {   kef6(k,i); \
300     k[6*(i)+10] = ss[4] ^= ss[3]; \
301     k[6*(i)+11] = ss[5] ^= ss[4]; \
302 }
303
304 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
305 {   uint_32t    ss[6];
306
307     cx->ks[0] = ss[0] = word_in(key, 0);
308     cx->ks[1] = ss[1] = word_in(key, 1);
309     cx->ks[2] = ss[2] = word_in(key, 2);
310     cx->ks[3] = ss[3] = word_in(key, 3);
311     cx->ks[4] = ss[4] = word_in(key, 4);
312     cx->ks[5] = ss[5] = word_in(key, 5);
313
314     ke6(cx->ks, 0);  ke6(cx->ks, 1);
315     ke6(cx->ks, 2);  ke6(cx->ks, 3);
316     ke6(cx->ks, 4);  ke6(cx->ks, 5);
317     ke6(cx->ks, 6);
318     kef6(cx->ks, 7);
319     cx->inf.l = 0;
320     cx->inf.b[0] = 12 * 16;
321 }
322
323 #define kef8(k,i) \
324 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
325     k[8*(i)+ 9] = ss[1] ^= ss[0]; \
326     k[8*(i)+10] = ss[2] ^= ss[1]; \
327     k[8*(i)+11] = ss[3] ^= ss[2]; \
328 }
329
330 #define ke8(k,i) \
331 {   kef8(k,i); \
332     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
333     k[8*(i)+13] = ss[5] ^= ss[4]; \
334     k[8*(i)+14] = ss[6] ^= ss[5]; \
335     k[8*(i)+15] = ss[7] ^= ss[6]; \
336 }
337
338 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
339 {   uint_32t    ss[8];
340
341     cx->ks[0] = ss[0] = word_in(key, 0);
342     cx->ks[1] = ss[1] = word_in(key, 1);
343     cx->ks[2] = ss[2] = word_in(key, 2);
344     cx->ks[3] = ss[3] = word_in(key, 3);
345     cx->ks[4] = ss[4] = word_in(key, 4);
346     cx->ks[5] = ss[5] = word_in(key, 5);
347     cx->ks[6] = ss[6] = word_in(key, 6);
348     cx->ks[7] = ss[7] = word_in(key, 7);
349
350     ke8(cx->ks, 0); ke8(cx->ks, 1);
351     ke8(cx->ks, 2); ke8(cx->ks, 3);
352     ke8(cx->ks, 4); ke8(cx->ks, 5);
353     kef8(cx->ks, 6);
354     cx->inf.l = 0;
355     cx->inf.b[0] = 14 * 16;
356 }
357
358 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
359 {
360     switch(key_len)
361     {
362     case 16: case 128: aes_encrypt_key128(key, cx); return;
363     case 24: case 192: aes_encrypt_key192(key, cx); return;
364     case 32: case 256: aes_encrypt_key256(key, cx); return;
365     }
366 }
367
368 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
369 #define k4e(k,i) \
370 {   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
371     k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
372     k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
373     k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
374 }
375
376 #define kdf4(k,i) \
377 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
378     ss[1] = ss[1] ^ ss[3]; \
379     ss[2] = ss[2] ^ ss[3]; \
380     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
381     ss[i % 4] ^= ss[4]; \
382     ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
383     ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
384     ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
385     ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
386 }
387
388 #define kd4(k,i) \
389 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
390     ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
391     k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
392     k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
393     k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
394     k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
395 }
396
397 #define kdl4(k,i) \
398 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
399     k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
400     k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
401     k[v(40,(4*(i))+6)] = ss[0]; \
402     k[v(40,(4*(i))+7)] = ss[1]; \
403 }
404
405 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
406 {   uint_32t    ss[5];
407 #if defined( d_vars )
408         d_vars;
409 #endif
410     cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
411     cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
412     cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
413     cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
414
415     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
416      kd4(cx->ks, 2);  kd4(cx->ks, 3);
417      kd4(cx->ks, 4);  kd4(cx->ks, 5);
418      kd4(cx->ks, 6);  kd4(cx->ks, 7);
419      kd4(cx->ks, 8); kdl4(cx->ks, 9);
420     cx->inf.l = 0;
421     cx->inf.b[0] = 10 * 16;
422 }
423
424 #define k6ef(k,i) \
425 {   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
426     k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
427     k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
428     k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
429 }
430
431 #define k6e(k,i) \
432 {   k6ef(k,i); \
433     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
434     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
435 }
436
437 #define kdf6(k,i) \
438 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
439     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
440     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
441     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
442     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
443     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
444 }
445
446 #define kd6(k,i) \
447 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
448     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
449     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
450     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
451     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
452     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
453     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
454 }
455
456 #define kdl6(k,i) \
457 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
458     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
459     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
460     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
461 }
462
463 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
464 {   uint_32t    ss[7];
465 #if defined( d_vars )
466         d_vars;
467 #endif
468     cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
469     cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
470     cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
471     cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
472
473     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
474     cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
475     kdf6(cx->ks, 0); kd6(cx->ks, 1);
476     kd6(cx->ks, 2);  kd6(cx->ks, 3);
477     kd6(cx->ks, 4);  kd6(cx->ks, 5);
478     kd6(cx->ks, 6); kdl6(cx->ks, 7);
479     cx->inf.l = 0;
480     cx->inf.b[0] = 12 * 16;
481 }
482
483 #define k8ef(k,i) \
484 {   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
485     k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
486     k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
487     k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
488 }
489
490 #define k8e(k,i) \
491 {   k8ef(k,i); \
492     k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
493     k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
494     k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
495     k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
496 }
497
498 #define kdf8(k,i) \
499 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
500     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
501     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
502     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
503     ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
504     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
505     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
506     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
507 }
508
509 #define kd8(k,i) \
510 {   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
511     ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
512     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
513     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
514     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
515     ss[8] = ls_box(ss[3],0); \
516     ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
517     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
518     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
519     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
520 }
521
522 #define kdl8(k,i) \
523 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
524     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
525     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
526     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
527 }
528
529 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
530 {   uint_32t    ss[9];
531 #if defined( d_vars )
532         d_vars;
533 #endif
534     cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
535     cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
536     cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
537     cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
538
539     cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
540     cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
541     cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
542     cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
543     kdf8(cx->ks, 0); kd8(cx->ks, 1);
544     kd8(cx->ks, 2);  kd8(cx->ks, 3);
545     kd8(cx->ks, 4);  kd8(cx->ks, 5);
546     kdl8(cx->ks, 6);
547     cx->inf.l = 0;
548     cx->inf.b[0] = 14 * 16;
549 }
550
551 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
552 {
553     switch(key_len)
554     {
555     case 16: case 128: aes_decrypt_key128(key, cx); return;
556     case 24: case 192: aes_decrypt_key192(key, cx); return;
557     case 32: case 256: aes_decrypt_key256(key, cx); return;
558     }
559 }
560
561 #ifndef SILC_AES_ASM
562 /* C version of AES */
563
564 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
565 #define so(y,x,c)   word_out(y, c, s(x,c))
566 #define locals(y,x)     x[4],y[4]
567 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
568                         s(y,2) = s(x,2); s(y,3) = s(x,3);
569 #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)
570 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
571 #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)
572
573 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
574    Pentium optimiation with small code but this is poor for decryption
575    so we need to control this with the following VC++ pragmas
576 */
577
578 #if defined( _MSC_VER ) && !defined( _WIN64 )
579 #pragma optimize( "s", on )
580 #endif
581
582 #define fwd_var(x,r,c)\
583  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
584  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
585  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
586  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
587 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
588 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
589
590 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
591 {   uint_32t         locals(b0, b1);
592     const uint_32t   *kp;
593
594     kp = cx->ks;
595     state_in(b0, in, kp);
596
597     switch(cx->inf.b[0])
598     {
599     case 14 * 16:
600         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
601         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
602         kp += 2 * N_COLS;
603     case 12 * 16:
604         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
605         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
606         kp += 2 * N_COLS;
607     case 10 * 16:
608         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
609         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
610         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
611         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
612         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
613         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
614         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
615         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
616         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
617         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
618     }
619
620     state_out(out, b0);
621 }
622
623 #define inv_var(x,r,c)\
624  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
625  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
626  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
627  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
628
629 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
630 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
631 #define key_ofs     0
632 #define rnd_key(n)  (kp + n * N_COLS)
633
634 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
635 {   uint_32t        locals(b0, b1);
636     const uint_32t *kp;
637
638     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
639     state_in(b0, in, kp);
640
641     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
642     switch(cx->inf.b[0])
643     {
644     case 14 * 16:
645         round(inv_rnd,  b1, b0, rnd_key(-13));
646         round(inv_rnd,  b0, b1, rnd_key(-12));
647     case 12 * 16:
648         round(inv_rnd,  b1, b0, rnd_key(-11));
649         round(inv_rnd,  b0, b1, rnd_key(-10));
650     case 10 * 16:
651         round(inv_rnd,  b1, b0, rnd_key(-9));
652         round(inv_rnd,  b0, b1, rnd_key(-8));
653         round(inv_rnd,  b1, b0, rnd_key(-7));
654         round(inv_rnd,  b0, b1, rnd_key(-6));
655         round(inv_rnd,  b1, b0, rnd_key(-5));
656         round(inv_rnd,  b0, b1, rnd_key(-4));
657         round(inv_rnd,  b1, b0, rnd_key(-3));
658         round(inv_rnd,  b0, b1, rnd_key(-2));
659         round(inv_rnd,  b1, b0, rnd_key(-1));
660         round(inv_lrnd, b0, b1, rnd_key( 0));
661     }
662
663     state_out(out, b0);
664 }
665
666 #if defined(__cplusplus)
667 }
668 #endif
669
670 #endif /* SILC_AES_ASM */