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