updates.
[silc.git] / lib / silccrypt / aes.c
1 /* Modified for SILC. -Pekka */
2 /* The AES */
3
4 /* This is an independent implementation of the encryption algorithm:   */
5 /*                                                                      */
6 /*         RIJNDAEL by Joan Daemen and Vincent Rijmen                   */
7 /*                                                                      */
8 /* which is a candidate algorithm in the Advanced Encryption Standard   */
9 /* programme of the US National Institute of Standards and Technology.  */
10 /*                                                                      */
11 /* Copyright in this implementation is held by Dr B R Gladman but I     */
12 /* hereby give permission for its free direct or derivative use subject */
13 /* to acknowledgment of its origin and compliance with any conditions   */
14 /* that the originators of the algorithm place on its exploitation.     */
15 /*                                                                      */
16 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */
17
18 /* Timing data for Rijndael (rijndael.c)
19
20 Algorithm: rijndael (rijndael.c)
21
22 128 bit key:
23 Key Setup:    305/1389 cycles (encrypt/decrypt)
24 Encrypt:       374 cycles =    68.4 mbits/sec
25 Decrypt:       352 cycles =    72.7 mbits/sec
26 Mean:          363 cycles =    70.5 mbits/sec
27
28 192 bit key:
29 Key Setup:    277/1595 cycles (encrypt/decrypt)
30 Encrypt:       439 cycles =    58.3 mbits/sec
31 Decrypt:       425 cycles =    60.2 mbits/sec
32 Mean:          432 cycles =    59.3 mbits/sec
33
34 256 bit key:
35 Key Setup:    374/1960 cycles (encrypt/decrypt)
36 Encrypt:       502 cycles =    51.0 mbits/sec
37 Decrypt:       498 cycles =    51.4 mbits/sec
38 Mean:          500 cycles =    51.2 mbits/sec
39
40 */
41
42 #include "silcincludes.h"
43 #include "aes.h"
44
45 /* 
46  * SILC Crypto API for Rijndael
47  */
48
49 /* Sets the key for the cipher. */
50
51 SILC_CIPHER_API_SET_KEY(aes)
52 {
53   uint32 k[8];
54
55   SILC_GET_WORD_KEY(key, k, keylen);
56   rijndael_set_key((RijndaelContext *)context, k, keylen);
57
58   return TRUE;
59 }
60
61 /* Sets the string as a new key for the cipher. The string is first
62    hashed and then used as a new key. */
63
64 SILC_CIPHER_API_SET_KEY_WITH_STRING(aes)
65 {
66   /*  unsigned char key[md5_hash_len];
67   SilcMarsContext *ctx = (SilcMarsContext *)context;
68
69   make_md5_hash(string, &key);
70   memcpy(&ctx->key, mars_set_key(&key, keylen), keylen);
71   memset(&key, 'F', sizeoof(key));
72   */
73
74   return 1;
75 }
76
77 /* Returns the size of the cipher context. */
78
79 SILC_CIPHER_API_CONTEXT_LEN(aes)
80 {
81   return sizeof(RijndaelContext);
82 }
83
84 /* Encrypts with the cipher in CBC mode. Source and destination buffers
85    maybe one and same. */
86
87 SILC_CIPHER_API_ENCRYPT_CBC(aes)
88 {
89   uint32 tiv[4];
90   int i;
91
92   SILC_CBC_GET_IV(tiv, iv);
93
94   SILC_CBC_ENC_PRE(tiv, src);
95   rijndael_encrypt((RijndaelContext *)context, tiv, tiv);
96   SILC_CBC_ENC_POST(tiv, dst, src);
97
98   for (i = 16; i < len; i += 16) {
99     SILC_CBC_ENC_PRE(tiv, src);
100     rijndael_encrypt((RijndaelContext *)context, tiv, tiv);
101     SILC_CBC_ENC_POST(tiv, dst, src);
102   }
103
104   SILC_CBC_PUT_IV(tiv, iv);
105
106   return TRUE;
107 }
108
109 /* Decrypts with the cipher in CBC mode. Source and destination buffers
110    maybe one and same. */
111
112 SILC_CIPHER_API_DECRYPT_CBC(aes)
113 {
114   uint32 tmp[4], tmp2[4], tiv[4];
115   int i;
116
117   SILC_CBC_GET_IV(tiv, iv);
118
119   SILC_CBC_DEC_PRE(tmp, src);
120   rijndael_decrypt((RijndaelContext *)context, tmp, tmp2);
121   SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
122
123   for (i = 16; i < len; i += 16) {
124     SILC_CBC_DEC_PRE(tmp, src);
125     rijndael_decrypt((RijndaelContext *)context, tmp, tmp2);
126     SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
127   }
128
129   SILC_CBC_PUT_IV(tiv, iv);
130
131   return TRUE;
132 }
133
134 #define LARGE_TABLES
135
136 u1byte  pow_tab[256];
137 u1byte  log_tab[256];
138 u1byte  sbx_tab[256];
139 u1byte  isb_tab[256];
140 u4byte  rco_tab[ 10];
141 u4byte  ft_tab[4][256];
142 u4byte  it_tab[4][256];
143
144 u4byte  fl_tab[4][256];
145 u4byte  il_tab[4][256];
146
147 u4byte  tab_gen = 0;
148
149 #define ff_mult(a,b)    (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
150
151 #define f_rn(bo, bi, n, k)                          \
152     bo[n] =  ft_tab[0][byte(bi[n],0)] ^             \
153              ft_tab[1][byte(bi[(n + 1) & 3],1)] ^   \
154              ft_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
155              ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
156
157 #define i_rn(bo, bi, n, k)                          \
158     bo[n] =  it_tab[0][byte(bi[n],0)] ^             \
159              it_tab[1][byte(bi[(n + 3) & 3],1)] ^   \
160              it_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
161              it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
162
163 #ifdef LARGE_TABLES
164
165 #define ls_box(x)                \
166     ( fl_tab[0][byte(x, 0)] ^    \
167       fl_tab[1][byte(x, 1)] ^    \
168       fl_tab[2][byte(x, 2)] ^    \
169       fl_tab[3][byte(x, 3)] )
170
171 #define f_rl(bo, bi, n, k)                          \
172     bo[n] =  fl_tab[0][byte(bi[n],0)] ^             \
173              fl_tab[1][byte(bi[(n + 1) & 3],1)] ^   \
174              fl_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
175              fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
176
177 #define i_rl(bo, bi, n, k)                          \
178     bo[n] =  il_tab[0][byte(bi[n],0)] ^             \
179              il_tab[1][byte(bi[(n + 3) & 3],1)] ^   \
180              il_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
181              il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
182
183 #else
184
185 #define ls_box(x)                            \
186     ((u4byte)sbx_tab[byte(x, 0)] <<  0) ^    \
187     ((u4byte)sbx_tab[byte(x, 1)] <<  8) ^    \
188     ((u4byte)sbx_tab[byte(x, 2)] << 16) ^    \
189     ((u4byte)sbx_tab[byte(x, 3)] << 24)
190
191 #define f_rl(bo, bi, n, k)                                      \
192     bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^                    \
193         rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]),  8) ^  \
194         rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^  \
195         rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
196
197 #define i_rl(bo, bi, n, k)                                      \
198     bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^                    \
199         rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]),  8) ^  \
200         rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^  \
201         rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
202
203 #endif
204
205 void gen_tabs(void)
206 {   u4byte  i, t;
207     u1byte  p, q;
208
209     /* log and power tables for GF(2**8) finite field with  */
210     /* 0x11b as modular polynomial - the simplest prmitive  */
211     /* root is 0x11, used here to generate the tables       */
212
213     for(i = 0,p = 1; i < 256; ++i)
214     {
215         pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;
216
217         p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
218     }
219
220     log_tab[1] = 0; p = 1;
221
222     for(i = 0; i < 10; ++i)
223     {
224         rco_tab[i] = p; 
225
226         p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
227     }
228
229     /* note that the affine byte transformation matrix in   */
230     /* rijndael specification is in big endian format with  */
231     /* bit 0 as the most significant bit. In the remainder  */
232     /* of the specification the bits are numbered from the  */
233     /* least significant end of a byte.                     */
234
235     for(i = 0; i < 256; ++i)
236     {   
237         p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p; 
238         q = (q >> 7) | (q << 1); p ^= q; 
239         q = (q >> 7) | (q << 1); p ^= q; 
240         q = (q >> 7) | (q << 1); p ^= q; 
241         q = (q >> 7) | (q << 1); p ^= q ^ 0x63; 
242         sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;
243     }
244
245     for(i = 0; i < 256; ++i)
246     {
247         p = sbx_tab[i]; 
248
249 #ifdef  LARGE_TABLES        
250         
251         t = p; fl_tab[0][i] = t;
252         fl_tab[1][i] = rotl(t,  8);
253         fl_tab[2][i] = rotl(t, 16);
254         fl_tab[3][i] = rotl(t, 24);
255 #endif
256         t = ((u4byte)ff_mult(2, p)) |
257             ((u4byte)p <<  8) |
258             ((u4byte)p << 16) |
259             ((u4byte)ff_mult(3, p) << 24);
260         
261         ft_tab[0][i] = t;
262         ft_tab[1][i] = rotl(t,  8);
263         ft_tab[2][i] = rotl(t, 16);
264         ft_tab[3][i] = rotl(t, 24);
265
266         p = isb_tab[i]; 
267
268 #ifdef  LARGE_TABLES        
269         
270         t = p; il_tab[0][i] = t; 
271         il_tab[1][i] = rotl(t,  8); 
272         il_tab[2][i] = rotl(t, 16); 
273         il_tab[3][i] = rotl(t, 24);
274 #endif 
275         t = ((u4byte)ff_mult(14, p)) |
276             ((u4byte)ff_mult( 9, p) <<  8) |
277             ((u4byte)ff_mult(13, p) << 16) |
278             ((u4byte)ff_mult(11, p) << 24);
279         
280         it_tab[0][i] = t; 
281         it_tab[1][i] = rotl(t,  8); 
282         it_tab[2][i] = rotl(t, 16); 
283         it_tab[3][i] = rotl(t, 24); 
284     }
285
286     tab_gen = 1;
287 };
288
289 #define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
290
291 #define imix_col(y,x)       \
292     u   = star_x(x);        \
293     v   = star_x(u);        \
294     w   = star_x(v);        \
295     t   = w ^ (x);          \
296    (y)  = u ^ v ^ w;        \
297    (y) ^= rotr(u ^ t,  8) ^ \
298           rotr(v ^ t, 16) ^ \
299           rotr(t,24)
300
301 /* initialise the key schedule from the user supplied key   */
302
303 #define loop4(i)                                    \
304 { \
305    t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
306     t ^= e_key[4 * i];     e_key[4 * i + 4] = t;    \
307     t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t;    \
308     t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t;    \
309     t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t;    \
310 }
311
312 #define loop6(i)                                    \
313 {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
314     t ^= e_key[6 * i];     e_key[6 * i + 6] = t;    \
315     t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t;    \
316     t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t;    \
317     t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t;    \
318     t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t;   \
319     t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t;   \
320 }
321
322 #define loop8(i)                                    \
323 {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
324     t ^= e_key[8 * i];     e_key[8 * i + 8] = t;    \
325     t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t;    \
326     t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t;   \
327     t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t;   \
328     t  = e_key[8 * i + 4] ^ ls_box(t);              \
329     e_key[8 * i + 12] = t;                          \
330     t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t;   \
331     t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t;   \
332     t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t;   \
333 }
334
335 u4byte *rijndael_set_key(RijndaelContext *ctx,
336                          const u4byte in_key[], const u4byte key_len)
337 {   
338     u4byte  i, t, u, v, w;
339     u4byte *e_key = ctx->e_key;
340     u4byte *d_key = ctx->d_key;
341     u4byte k_len;
342
343     if(!tab_gen)
344         gen_tabs();
345
346     k_len = ctx->k_len = (key_len + 31) / 32;
347
348     e_key[0] = in_key[0]; e_key[1] = in_key[1];
349     e_key[2] = in_key[2]; e_key[3] = in_key[3];
350
351     switch(k_len)
352     {
353         case 4: t = e_key[3];
354                 for(i = 0; i < 10; ++i) 
355                     loop4(i);
356                 break;
357
358         case 6: e_key[4] = in_key[4]; t = e_key[5] = in_key[5];
359                 for(i = 0; i < 8; ++i) 
360                     loop6(i);
361                 break;
362
363         case 8: e_key[4] = in_key[4]; e_key[5] = in_key[5];
364                 e_key[6] = in_key[6]; t = e_key[7] = in_key[7];
365                 for(i = 0; i < 7; ++i) 
366                     loop8(i);
367                 break;
368     }
369
370     d_key[0] = e_key[0]; d_key[1] = e_key[1];
371     d_key[2] = e_key[2]; d_key[3] = e_key[3];
372
373     for(i = 4; i < 4 * k_len + 24; ++i)
374     {
375         imix_col(d_key[i], e_key[i]);
376     }
377
378     return e_key;
379 };
380
381 /* encrypt a block of text  */
382
383 #define f_nround(bo, bi, k) \
384     f_rn(bo, bi, 0, k);     \
385     f_rn(bo, bi, 1, k);     \
386     f_rn(bo, bi, 2, k);     \
387     f_rn(bo, bi, 3, k);     \
388     k += 4
389
390 #define f_lround(bo, bi, k) \
391     f_rl(bo, bi, 0, k);     \
392     f_rl(bo, bi, 1, k);     \
393     f_rl(bo, bi, 2, k);     \
394     f_rl(bo, bi, 3, k)
395
396 void rijndael_encrypt(RijndaelContext *ctx,
397                       const u4byte in_blk[4], u4byte out_blk[4])
398 {   
399     u4byte  b0[4], b1[4], *kp;
400     u4byte *e_key = ctx->e_key;
401     u4byte k_len = ctx->k_len;
402
403     b0[0] = in_blk[0] ^ e_key[0]; b0[1] = in_blk[1] ^ e_key[1];
404     b0[2] = in_blk[2] ^ e_key[2]; b0[3] = in_blk[3] ^ e_key[3];
405
406     kp = e_key + 4;
407
408     if(k_len > 6)
409     {
410         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
411     }
412
413     if(k_len > 4)
414     {
415         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
416     }
417
418     f_nround(b1, b0, kp); f_nround(b0, b1, kp);
419     f_nround(b1, b0, kp); f_nround(b0, b1, kp);
420     f_nround(b1, b0, kp); f_nround(b0, b1, kp);
421     f_nround(b1, b0, kp); f_nround(b0, b1, kp);
422     f_nround(b1, b0, kp); f_lround(b0, b1, kp);
423
424     out_blk[0] = b0[0]; out_blk[1] = b0[1];
425     out_blk[2] = b0[2]; out_blk[3] = b0[3];
426 };
427
428 /* decrypt a block of text  */
429
430 #define i_nround(bo, bi, k) \
431     i_rn(bo, bi, 0, k);     \
432     i_rn(bo, bi, 1, k);     \
433     i_rn(bo, bi, 2, k);     \
434     i_rn(bo, bi, 3, k);     \
435     k -= 4
436
437 #define i_lround(bo, bi, k) \
438     i_rl(bo, bi, 0, k);     \
439     i_rl(bo, bi, 1, k);     \
440     i_rl(bo, bi, 2, k);     \
441     i_rl(bo, bi, 3, k)
442
443 void rijndael_decrypt(RijndaelContext *ctx,
444                       const u4byte in_blk[4], u4byte out_blk[4])
445 {   
446     u4byte  b0[4], b1[4], *kp;
447     u4byte *e_key = ctx->e_key;
448     u4byte *d_key = ctx->d_key;
449     u4byte k_len = ctx->k_len;
450
451     b0[0] = in_blk[0] ^ e_key[4 * k_len + 24]; b0[1] = in_blk[1] ^ e_key[4 * k_len + 25];
452     b0[2] = in_blk[2] ^ e_key[4 * k_len + 26]; b0[3] = in_blk[3] ^ e_key[4 * k_len + 27];
453
454     kp = d_key + 4 * (k_len + 5);
455
456     if(k_len > 6)
457     {
458         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
459     }
460
461     if(k_len > 4)
462     {
463         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
464     }
465
466     i_nround(b1, b0, kp); i_nround(b0, b1, kp);
467     i_nround(b1, b0, kp); i_nround(b0, b1, kp);
468     i_nround(b1, b0, kp); i_nround(b0, b1, kp);
469     i_nround(b1, b0, kp); i_nround(b0, b1, kp);
470     i_nround(b1, b0, kp); i_lround(b0, b1, kp);
471
472     out_blk[0] = b0[0]; out_blk[1] = b0[1];
473     out_blk[2] = b0[2]; out_blk[3] = b0[3];
474 };