Added properly working CBC mode implementation to AES.
[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   return aes;
95 }
96
97 /* Unnitialize */
98
99 SILC_CIPHER_API_UNINIT(aes)
100 {
101   AesContext *aes = context;
102   memset(aes, 0, sizeof(*aes));
103   silc_free(aes);
104 }
105
106 /* Encrypts with the cipher. Source and destination buffers maybe one and
107    same. */
108
109 SILC_CIPHER_API_ENCRYPT(aes)
110 {
111   AesContext *aes = context;
112   int i;
113
114   switch (ops->mode) {
115   case SILC_CIPHER_MODE_CTR:
116     SILC_CTR_MSB_128_8(iv, cipher->block, aes->u.enc.inf.b[2], src, dst,
117                        aes_encrypt(iv, cipher->block, &aes->u.enc));
118     break;
119
120   case SILC_CIPHER_MODE_ECB:
121     {
122       SilcUInt32 nb = len >> 4;
123
124       while (nb--) {
125         aes_encrypt(src, dst, &aes->u.enc);
126         src += 16;
127         dst += 16;
128       }
129     }
130     break;
131
132   case SILC_CIPHER_MODE_CBC:
133     SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i,
134                            aes_encrypt(iv, iv, &aes->u.enc));
135     break;
136
137   case SILC_CIPHER_MODE_CFB:
138     SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
139                            aes_encrypt(iv, iv, &aes->u.enc));
140     break;
141
142   default:
143     return FALSE;
144   }
145
146   return TRUE;
147 }
148
149 /* Decrypts with the cipher. Source and destination buffers maybe one
150    and same. */
151
152 SILC_CIPHER_API_DECRYPT(aes)
153 {
154   AesContext *aes = context;
155   unsigned char prev[16];
156   int i;
157
158   switch (ops->mode) {
159   case SILC_CIPHER_MODE_CTR:
160     return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
161     break;
162
163   case SILC_CIPHER_MODE_ECB:
164     {
165       SilcUInt32 nb = len >> 4;
166
167       while (nb--) {
168         aes_decrypt(src, dst, &aes->u.dec);
169         src += 16;
170         dst += 16;
171       }
172     }
173     break;
174
175   case SILC_CIPHER_MODE_CBC:
176     SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i,
177                            aes_decrypt(src, dst, &aes->u.dec));
178     break;
179
180   case SILC_CIPHER_MODE_CFB:
181     SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
182                            aes_encrypt(iv, iv, &aes->u.enc));
183     break;
184
185   default:
186     return FALSE;
187   }
188
189   return TRUE;
190 }
191
192 /****************************************************************************/
193
194 #if defined(__cplusplus)
195 extern "C"
196 {
197 #endif
198
199 #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
200 #  define XP_DIR __cdecl
201 #else
202 #  define XP_DIR
203 #endif
204
205 #define d_1(t,n,b,e)       ALIGN const XP_DIR t n[256]    =   b(e)
206 #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) }
207 ALIGN const uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
208
209 #ifdef SILC_AES_ASM
210 d_1(uint_8t, t_dec(i,box), isb_data, h0);
211 #endif /* SILC_AES_ASM */
212 d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
213 d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
214 d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
215 d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
216 d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
217
218 #define ke4(k,i) \
219 {   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
220     k[4*(i)+5] = ss[1] ^= ss[0]; \
221     k[4*(i)+6] = ss[2] ^= ss[1]; \
222     k[4*(i)+7] = ss[3] ^= ss[2]; \
223 }
224
225 AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
226 {   uint_32t    ss[4];
227
228     cx->ks[0] = ss[0] = word_in(key, 0);
229     cx->ks[1] = ss[1] = word_in(key, 1);
230     cx->ks[2] = ss[2] = word_in(key, 2);
231     cx->ks[3] = ss[3] = word_in(key, 3);
232
233     ke4(cx->ks, 0);  ke4(cx->ks, 1);
234     ke4(cx->ks, 2);  ke4(cx->ks, 3);
235     ke4(cx->ks, 4);  ke4(cx->ks, 5);
236     ke4(cx->ks, 6);  ke4(cx->ks, 7);
237     ke4(cx->ks, 8);
238     ke4(cx->ks, 9);
239     cx->inf.b[0] = 10 * 16;
240 }
241
242 #define kef6(k,i) \
243 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
244     k[6*(i)+ 7] = ss[1] ^= ss[0]; \
245     k[6*(i)+ 8] = ss[2] ^= ss[1]; \
246     k[6*(i)+ 9] = ss[3] ^= ss[2]; \
247 }
248
249 #define ke6(k,i) \
250 {   kef6(k,i); \
251     k[6*(i)+10] = ss[4] ^= ss[3]; \
252     k[6*(i)+11] = ss[5] ^= ss[4]; \
253 }
254
255 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
256 {   uint_32t    ss[6];
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     cx->ks[4] = ss[4] = word_in(key, 4);
263     cx->ks[5] = ss[5] = word_in(key, 5);
264
265     ke6(cx->ks, 0);  ke6(cx->ks, 1);
266     ke6(cx->ks, 2);  ke6(cx->ks, 3);
267     ke6(cx->ks, 4);  ke6(cx->ks, 5);
268     ke6(cx->ks, 6);
269     kef6(cx->ks, 7);
270     cx->inf.b[0] = 12 * 16;
271 }
272
273 #define kef8(k,i) \
274 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
275     k[8*(i)+ 9] = ss[1] ^= ss[0]; \
276     k[8*(i)+10] = ss[2] ^= ss[1]; \
277     k[8*(i)+11] = ss[3] ^= ss[2]; \
278 }
279
280 #define ke8(k,i) \
281 {   kef8(k,i); \
282     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
283     k[8*(i)+13] = ss[5] ^= ss[4]; \
284     k[8*(i)+14] = ss[6] ^= ss[5]; \
285     k[8*(i)+15] = ss[7] ^= ss[6]; \
286 }
287
288 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
289 {   uint_32t    ss[8];
290
291     cx->ks[0] = ss[0] = word_in(key, 0);
292     cx->ks[1] = ss[1] = word_in(key, 1);
293     cx->ks[2] = ss[2] = word_in(key, 2);
294     cx->ks[3] = ss[3] = word_in(key, 3);
295     cx->ks[4] = ss[4] = word_in(key, 4);
296     cx->ks[5] = ss[5] = word_in(key, 5);
297     cx->ks[6] = ss[6] = word_in(key, 6);
298     cx->ks[7] = ss[7] = word_in(key, 7);
299
300     ke8(cx->ks, 0); ke8(cx->ks, 1);
301     ke8(cx->ks, 2); ke8(cx->ks, 3);
302     ke8(cx->ks, 4); ke8(cx->ks, 5);
303     kef8(cx->ks, 6);
304     cx->inf.b[0] = 14 * 16;
305 }
306
307 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
308 {
309     switch(key_len)
310     {
311     case 16: case 128: aes_encrypt_key128(key, cx); return;
312     case 24: case 192: aes_encrypt_key192(key, cx); return;
313     case 32: case 256: aes_encrypt_key256(key, cx); return;
314     }
315 }
316
317 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
318 #define k4e(k,i) \
319 {   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
320     k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
321     k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
322     k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
323 }
324
325 #define kdf4(k,i) \
326 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
327     ss[1] = ss[1] ^ ss[3]; \
328     ss[2] = ss[2] ^ ss[3]; \
329     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
330     ss[i % 4] ^= ss[4]; \
331     ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
332     ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
333     ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
334     ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
335 }
336
337 #define kd4(k,i) \
338 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
339     ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
340     k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
341     k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
342     k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
343     k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
344 }
345
346 #define kdl4(k,i) \
347 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
348     k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
349     k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
350     k[v(40,(4*(i))+6)] = ss[0]; \
351     k[v(40,(4*(i))+7)] = ss[1]; \
352 }
353
354 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
355 {   uint_32t    ss[5];
356 #if defined( d_vars )
357         d_vars;
358 #endif
359     cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
360     cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
361     cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
362     cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
363
364     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
365      kd4(cx->ks, 2);  kd4(cx->ks, 3);
366      kd4(cx->ks, 4);  kd4(cx->ks, 5);
367      kd4(cx->ks, 6);  kd4(cx->ks, 7);
368      kd4(cx->ks, 8); kdl4(cx->ks, 9);
369     cx->inf.b[0] = 10 * 16;
370 }
371
372 #define k6ef(k,i) \
373 {   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
374     k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
375     k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
376     k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
377 }
378
379 #define k6e(k,i) \
380 {   k6ef(k,i); \
381     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
382     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
383 }
384
385 #define kdf6(k,i) \
386 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
387     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
388     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
389     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
390     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
391     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
392 }
393
394 #define kd6(k,i) \
395 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
396     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
397     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
398     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
399     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
400     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
401     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
402 }
403
404 #define kdl6(k,i) \
405 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
406     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
407     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
408     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
409 }
410
411 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
412 {   uint_32t    ss[7];
413 #if defined( d_vars )
414         d_vars;
415 #endif
416     cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
417     cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
418     cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
419     cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
420
421     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
422     cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
423     kdf6(cx->ks, 0); kd6(cx->ks, 1);
424     kd6(cx->ks, 2);  kd6(cx->ks, 3);
425     kd6(cx->ks, 4);  kd6(cx->ks, 5);
426     kd6(cx->ks, 6); kdl6(cx->ks, 7);
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.b[0] = 14 * 16;
495 }
496
497 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
498 {
499     switch(key_len)
500     {
501     case 16: case 128: aes_decrypt_key128(key, cx); return;
502     case 24: case 192: aes_decrypt_key192(key, cx); return;
503     case 32: case 256: aes_decrypt_key256(key, cx); return;
504     }
505 }
506
507 #ifndef SILC_AES_ASM
508 /* C version of AES */
509
510 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
511 #define so(y,x,c)   word_out(y, c, s(x,c))
512 #define locals(y,x)     x[4],y[4]
513 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
514                         s(y,2) = s(x,2); s(y,3) = s(x,3);
515 #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)
516 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
517 #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)
518
519 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
520    Pentium optimiation with small code but this is poor for decryption
521    so we need to control this with the following VC++ pragmas
522 */
523
524 #if defined( _MSC_VER ) && !defined( _WIN64 )
525 #pragma optimize( "s", on )
526 #endif
527
528 #define fwd_var(x,r,c)\
529  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
530  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
531  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
532  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
533 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
534 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
535
536 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
537 {   uint_32t         locals(b0, b1);
538     const uint_32t   *kp;
539
540     kp = cx->ks;
541     state_in(b0, in, kp);
542
543     switch(cx->inf.b[0])
544     {
545     case 14 * 16:
546         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
547         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
548         kp += 2 * N_COLS;
549     case 12 * 16:
550         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
551         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
552         kp += 2 * N_COLS;
553     case 10 * 16:
554         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
555         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
556         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
557         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
558         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
559         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
560         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
561         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
562         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
563         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
564     }
565
566     state_out(out, b0);
567 }
568
569 #define inv_var(x,r,c)\
570  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
571  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
572  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
573  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
574
575 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
576 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
577 #define key_ofs     0
578 #define rnd_key(n)  (kp + n * N_COLS)
579
580 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
581 {   uint_32t        locals(b0, b1);
582     const uint_32t *kp;
583
584     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
585     state_in(b0, in, kp);
586
587     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
588     switch(cx->inf.b[0])
589     {
590     case 14 * 16:
591         round(inv_rnd,  b1, b0, rnd_key(-13));
592         round(inv_rnd,  b0, b1, rnd_key(-12));
593     case 12 * 16:
594         round(inv_rnd,  b1, b0, rnd_key(-11));
595         round(inv_rnd,  b0, b1, rnd_key(-10));
596     case 10 * 16:
597         round(inv_rnd,  b1, b0, rnd_key(-9));
598         round(inv_rnd,  b0, b1, rnd_key(-8));
599         round(inv_rnd,  b1, b0, rnd_key(-7));
600         round(inv_rnd,  b0, b1, rnd_key(-6));
601         round(inv_rnd,  b1, b0, rnd_key(-5));
602         round(inv_rnd,  b0, b1, rnd_key(-4));
603         round(inv_rnd,  b1, b0, rnd_key(-3));
604         round(inv_rnd,  b0, b1, rnd_key(-2));
605         round(inv_rnd,  b1, b0, rnd_key(-1));
606         round(inv_lrnd, b0, b1, rnd_key( 0));
607     }
608
609     state_out(out, b0);
610 }
611
612 #if defined(__cplusplus)
613 }
614 #endif
615
616 #endif /* SILC_AES_ASM */