Fixed missing return values in cipher initialization functions.
[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     {
134       SilcUInt32 nb = len >> 4;
135
136       SILC_ASSERT((len & (16 - 1)) == 0);
137       if (len & (16 - 1))
138         return FALSE;
139
140       while(nb--) {
141         lp32(iv)[0] ^= lp32(src)[0];
142         lp32(iv)[1] ^= lp32(src)[1];
143         lp32(iv)[2] ^= lp32(src)[2];
144         lp32(iv)[3] ^= lp32(src)[3];
145         aes_encrypt(iv, iv, &aes->u.enc);
146         memcpy(dst, iv, 16);
147         src += 16;
148         dst += 16;
149       }
150     }
151     break;
152
153   case SILC_CIPHER_MODE_CFB:
154     SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
155                            aes_encrypt(iv, iv, &aes->u.enc));
156     break;
157
158   default:
159     return FALSE;
160   }
161
162   return TRUE;
163 }
164
165 /* Decrypts with the cipher. Source and destination buffers maybe one
166    and same. */
167
168 SILC_CIPHER_API_DECRYPT(aes)
169 {
170   AesContext *aes = context;
171
172   switch (ops->mode) {
173   case SILC_CIPHER_MODE_CTR:
174     return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
175     break;
176
177   case SILC_CIPHER_MODE_ECB:
178     {
179       SilcUInt32 nb = len >> 4;
180
181       while (nb--) {
182         aes_decrypt(src, dst, &aes->u.dec);
183         src += 16;
184         dst += 16;
185       }
186     }
187     break;
188
189   case SILC_CIPHER_MODE_CBC:
190     {
191       unsigned char tmp[16];
192       SilcUInt32 nb = len >> 4;
193
194       if (len & (16 - 1))
195         return FALSE;
196
197       while(nb--) {
198         memcpy(tmp, src, 16);
199         aes_decrypt(src, dst, &aes->u.dec);
200         lp32(dst)[0] ^= lp32(iv)[0];
201         lp32(dst)[1] ^= lp32(iv)[1];
202         lp32(dst)[2] ^= lp32(iv)[2];
203         lp32(dst)[3] ^= lp32(iv)[3];
204         memcpy(iv, tmp, 16);
205         src += 16;
206         dst += 16;
207       }
208     }
209     break;
210
211   case SILC_CIPHER_MODE_CFB:
212     SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
213                            aes_encrypt(iv, iv, &aes->u.enc));
214     break;
215
216   default:
217     return FALSE;
218   }
219
220   return TRUE;
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.b[0] = 10 * 16;
271 }
272
273 #define kef6(k,i) \
274 {   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
275     k[6*(i)+ 7] = ss[1] ^= ss[0]; \
276     k[6*(i)+ 8] = ss[2] ^= ss[1]; \
277     k[6*(i)+ 9] = ss[3] ^= ss[2]; \
278 }
279
280 #define ke6(k,i) \
281 {   kef6(k,i); \
282     k[6*(i)+10] = ss[4] ^= ss[3]; \
283     k[6*(i)+11] = ss[5] ^= ss[4]; \
284 }
285
286 AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
287 {   uint_32t    ss[6];
288
289     cx->ks[0] = ss[0] = word_in(key, 0);
290     cx->ks[1] = ss[1] = word_in(key, 1);
291     cx->ks[2] = ss[2] = word_in(key, 2);
292     cx->ks[3] = ss[3] = word_in(key, 3);
293     cx->ks[4] = ss[4] = word_in(key, 4);
294     cx->ks[5] = ss[5] = word_in(key, 5);
295
296     ke6(cx->ks, 0);  ke6(cx->ks, 1);
297     ke6(cx->ks, 2);  ke6(cx->ks, 3);
298     ke6(cx->ks, 4);  ke6(cx->ks, 5);
299     ke6(cx->ks, 6);
300     kef6(cx->ks, 7);
301     cx->inf.b[0] = 12 * 16;
302 }
303
304 #define kef8(k,i) \
305 {   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
306     k[8*(i)+ 9] = ss[1] ^= ss[0]; \
307     k[8*(i)+10] = ss[2] ^= ss[1]; \
308     k[8*(i)+11] = ss[3] ^= ss[2]; \
309 }
310
311 #define ke8(k,i) \
312 {   kef8(k,i); \
313     k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
314     k[8*(i)+13] = ss[5] ^= ss[4]; \
315     k[8*(i)+14] = ss[6] ^= ss[5]; \
316     k[8*(i)+15] = ss[7] ^= ss[6]; \
317 }
318
319 AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
320 {   uint_32t    ss[8];
321
322     cx->ks[0] = ss[0] = word_in(key, 0);
323     cx->ks[1] = ss[1] = word_in(key, 1);
324     cx->ks[2] = ss[2] = word_in(key, 2);
325     cx->ks[3] = ss[3] = word_in(key, 3);
326     cx->ks[4] = ss[4] = word_in(key, 4);
327     cx->ks[5] = ss[5] = word_in(key, 5);
328     cx->ks[6] = ss[6] = word_in(key, 6);
329     cx->ks[7] = ss[7] = word_in(key, 7);
330
331     ke8(cx->ks, 0); ke8(cx->ks, 1);
332     ke8(cx->ks, 2); ke8(cx->ks, 3);
333     ke8(cx->ks, 4); ke8(cx->ks, 5);
334     kef8(cx->ks, 6);
335     cx->inf.b[0] = 14 * 16;
336 }
337
338 AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
339 {
340     switch(key_len)
341     {
342     case 16: case 128: aes_encrypt_key128(key, cx); return;
343     case 24: case 192: aes_encrypt_key192(key, cx); return;
344     case 32: case 256: aes_encrypt_key256(key, cx); return;
345     }
346 }
347
348 #define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
349 #define k4e(k,i) \
350 {   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
351     k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
352     k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
353     k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
354 }
355
356 #define kdf4(k,i) \
357 {   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
358     ss[1] = ss[1] ^ ss[3]; \
359     ss[2] = ss[2] ^ ss[3]; \
360     ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
361     ss[i % 4] ^= ss[4]; \
362     ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
363     ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
364     ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
365     ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
366 }
367
368 #define kd4(k,i) \
369 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
370     ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
371     k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
372     k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
373     k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
374     k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
375 }
376
377 #define kdl4(k,i) \
378 {   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
379     k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
380     k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
381     k[v(40,(4*(i))+6)] = ss[0]; \
382     k[v(40,(4*(i))+7)] = ss[1]; \
383 }
384
385 AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
386 {   uint_32t    ss[5];
387 #if defined( d_vars )
388         d_vars;
389 #endif
390     cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
391     cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
392     cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
393     cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
394
395     kdf4(cx->ks, 0);  kd4(cx->ks, 1);
396      kd4(cx->ks, 2);  kd4(cx->ks, 3);
397      kd4(cx->ks, 4);  kd4(cx->ks, 5);
398      kd4(cx->ks, 6);  kd4(cx->ks, 7);
399      kd4(cx->ks, 8); kdl4(cx->ks, 9);
400     cx->inf.b[0] = 10 * 16;
401 }
402
403 #define k6ef(k,i) \
404 {   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
405     k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
406     k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
407     k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
408 }
409
410 #define k6e(k,i) \
411 {   k6ef(k,i); \
412     k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
413     k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
414 }
415
416 #define kdf6(k,i) \
417 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
418     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
419     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
420     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
421     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
422     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
423 }
424
425 #define kd6(k,i) \
426 {   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
427     ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
428     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
429     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
430     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
431     ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
432     ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
433 }
434
435 #define kdl6(k,i) \
436 {   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
437     ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
438     ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
439     ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
440 }
441
442 AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
443 {   uint_32t    ss[7];
444 #if defined( d_vars )
445         d_vars;
446 #endif
447     cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
448     cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
449     cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
450     cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
451
452     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
453     cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
454     kdf6(cx->ks, 0); kd6(cx->ks, 1);
455     kd6(cx->ks, 2);  kd6(cx->ks, 3);
456     kd6(cx->ks, 4);  kd6(cx->ks, 5);
457     kd6(cx->ks, 6); kdl6(cx->ks, 7);
458     cx->inf.b[0] = 12 * 16;
459 }
460
461 #define k8ef(k,i) \
462 {   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
463     k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
464     k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
465     k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
466 }
467
468 #define k8e(k,i) \
469 {   k8ef(k,i); \
470     k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
471     k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
472     k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
473     k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
474 }
475
476 #define kdf8(k,i) \
477 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
478     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
479     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
480     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
481     ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
482     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
483     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
484     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
485 }
486
487 #define kd8(k,i) \
488 {   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
489     ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
490     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
491     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
492     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
493     ss[8] = ls_box(ss[3],0); \
494     ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
495     ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
496     ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
497     ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
498 }
499
500 #define kdl8(k,i) \
501 {   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
502     ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
503     ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
504     ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
505 }
506
507 AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
508 {   uint_32t    ss[9];
509 #if defined( d_vars )
510         d_vars;
511 #endif
512     cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
513     cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
514     cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
515     cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
516
517     cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
518     cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
519     cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
520     cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
521     kdf8(cx->ks, 0); kd8(cx->ks, 1);
522     kd8(cx->ks, 2);  kd8(cx->ks, 3);
523     kd8(cx->ks, 4);  kd8(cx->ks, 5);
524     kdl8(cx->ks, 6);
525     cx->inf.b[0] = 14 * 16;
526 }
527
528 AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
529 {
530     switch(key_len)
531     {
532     case 16: case 128: aes_decrypt_key128(key, cx); return;
533     case 24: case 192: aes_decrypt_key192(key, cx); return;
534     case 32: case 256: aes_decrypt_key256(key, cx); return;
535     }
536 }
537
538 #ifndef SILC_AES_ASM
539 /* C version of AES */
540
541 #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
542 #define so(y,x,c)   word_out(y, c, s(x,c))
543 #define locals(y,x)     x[4],y[4]
544 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
545                         s(y,2) = s(x,2); s(y,3) = s(x,3);
546 #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)
547 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
548 #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)
549
550 /* Visual C++ .Net v7.1 provides the fastest encryption code when using
551    Pentium optimiation with small code but this is poor for decryption
552    so we need to control this with the following VC++ pragmas
553 */
554
555 #if defined( _MSC_VER ) && !defined( _WIN64 )
556 #pragma optimize( "s", on )
557 #endif
558
559 #define fwd_var(x,r,c)\
560  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
561  : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
562  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
563  :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
564 #define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
565 #define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
566
567 AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
568 {   uint_32t         locals(b0, b1);
569     const uint_32t   *kp;
570
571     kp = cx->ks;
572     state_in(b0, in, kp);
573
574     switch(cx->inf.b[0])
575     {
576     case 14 * 16:
577         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
578         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
579         kp += 2 * N_COLS;
580     case 12 * 16:
581         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
582         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
583         kp += 2 * N_COLS;
584     case 10 * 16:
585         round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
586         round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
587         round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
588         round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
589         round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
590         round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
591         round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
592         round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
593         round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
594         round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
595     }
596
597     state_out(out, b0);
598 }
599
600 #define inv_var(x,r,c)\
601  ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
602  : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
603  : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
604  :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
605
606 #define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
607 #define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
608 #define key_ofs     0
609 #define rnd_key(n)  (kp + n * N_COLS)
610
611 AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
612 {   uint_32t        locals(b0, b1);
613     const uint_32t *kp;
614
615     kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
616     state_in(b0, in, kp);
617
618     kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
619     switch(cx->inf.b[0])
620     {
621     case 14 * 16:
622         round(inv_rnd,  b1, b0, rnd_key(-13));
623         round(inv_rnd,  b0, b1, rnd_key(-12));
624     case 12 * 16:
625         round(inv_rnd,  b1, b0, rnd_key(-11));
626         round(inv_rnd,  b0, b1, rnd_key(-10));
627     case 10 * 16:
628         round(inv_rnd,  b1, b0, rnd_key(-9));
629         round(inv_rnd,  b0, b1, rnd_key(-8));
630         round(inv_rnd,  b1, b0, rnd_key(-7));
631         round(inv_rnd,  b0, b1, rnd_key(-6));
632         round(inv_rnd,  b1, b0, rnd_key(-5));
633         round(inv_rnd,  b0, b1, rnd_key(-4));
634         round(inv_rnd,  b1, b0, rnd_key(-3));
635         round(inv_rnd,  b0, b1, rnd_key(-2));
636         round(inv_rnd,  b1, b0, rnd_key(-1));
637         round(inv_lrnd, b0, b1, rnd_key( 0));
638     }
639
640     state_out(out, b0);
641 }
642
643 #if defined(__cplusplus)
644 }
645 #endif
646
647 #endif /* SILC_AES_ASM */