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