1
2
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
20Algorithm: rijndael (rijndael.c)
21
22128 bit key:
23Key Setup:    305/1389 cycles (encrypt/decrypt)
24Encrypt:       374 cycles =    68.4 mbits/sec
25Decrypt:       352 cycles =    72.7 mbits/sec
26Mean:          363 cycles =    70.5 mbits/sec
27
28192 bit key:
29Key Setup:    277/1595 cycles (encrypt/decrypt)
30Encrypt:       439 cycles =    58.3 mbits/sec
31Decrypt:       425 cycles =    60.2 mbits/sec
32Mean:          432 cycles =    59.3 mbits/sec
33
34256 bit key:
35Key Setup:    374/1960 cycles (encrypt/decrypt)
36Encrypt:       502 cycles =    51.0 mbits/sec
37Decrypt:       498 cycles =    51.4 mbits/sec
38Mean:          500 cycles =    51.2 mbits/sec
39
40*/
41
42#include "std_defs.h"
43
44/* enable of block/word/byte swapping macros */
45#define USE_SWAP_MACROS	1
46
47static char *alg_name[] = { (char *)"rijndael", (char *)"rijndael.c", (char *)"rijndael" };
48
49char **cipher_name()
50{
51    return alg_name;
52}
53
54#define LARGE_TABLES
55
56u1byte  pow_tab[256];
57u1byte  log_tab[256];
58u1byte  sbx_tab[256];
59u1byte  isb_tab[256];
60u4byte  rco_tab[ 10];
61u4byte  ft_tab[4][256];
62u4byte  it_tab[4][256];
63
64#ifdef  LARGE_TABLES
65  u4byte  fl_tab[4][256];
66  u4byte  il_tab[4][256];
67#endif
68
69u4byte  tab_gen = 0;
70
71u4byte  k_len;
72u4byte  e_key[64];
73u4byte  d_key[64];
74
75#define ff_mult(a,b)    (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
76
77#define f_rn(bo, bi, n, k)                          \
78    bo[n] =  ft_tab[0][byte(bi[n],0)] ^             \
79             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^   \
80             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
81             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
82
83#define i_rn(bo, bi, n, k)                          \
84    bo[n] =  it_tab[0][byte(bi[n],0)] ^             \
85             it_tab[1][byte(bi[(n + 3) & 3],1)] ^   \
86             it_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
87             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
88
89#ifdef LARGE_TABLES
90
91#define ls_box(x)                \
92    ( fl_tab[0][byte(x, 0)] ^    \
93      fl_tab[1][byte(x, 1)] ^    \
94      fl_tab[2][byte(x, 2)] ^    \
95      fl_tab[3][byte(x, 3)] )
96
97#define f_rl(bo, bi, n, k)                          \
98    bo[n] =  fl_tab[0][byte(bi[n],0)] ^             \
99             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^   \
100             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
101             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
102
103#define i_rl(bo, bi, n, k)                          \
104    bo[n] =  il_tab[0][byte(bi[n],0)] ^             \
105             il_tab[1][byte(bi[(n + 3) & 3],1)] ^   \
106             il_tab[2][byte(bi[(n + 2) & 3],2)] ^   \
107             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
108
109#else
110
111#define ls_box(x)                            \
112    ((u4byte)sbx_tab[byte(x, 0)] <<  0) ^    \
113    ((u4byte)sbx_tab[byte(x, 1)] <<  8) ^    \
114    ((u4byte)sbx_tab[byte(x, 2)] << 16) ^    \
115    ((u4byte)sbx_tab[byte(x, 3)] << 24)
116
117#define f_rl(bo, bi, n, k)                                      \
118    bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^                    \
119        rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]),  8) ^  \
120        rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^  \
121        rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
122
123#define i_rl(bo, bi, n, k)                                      \
124    bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^                    \
125        rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]),  8) ^  \
126        rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^  \
127        rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
128
129#endif
130
131void gen_tabs(void)
132{   u4byte  i, t;
133    u1byte  p, q;
134
135    /* log and power tables for GF(2**8) finite field with  */
136    /* 0x11b as modular polynomial - the simplest prmitive  */
137    /* root is 0x11, used here to generate the tables       */
138
139    for(i = 0,p = 1; i < 256; ++i)
140    {
141        pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;
142
143        p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
144    }
145
146    log_tab[1] = 0; p = 1;
147
148    for(i = 0; i < 10; ++i)
149    {
150        rco_tab[i] = p;
151
152        p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
153    }
154
155    /* note that the affine byte transformation matrix in   */
156    /* rijndael specification is in big endian format with  */
157    /* bit 0 as the most significant bit. In the remainder  */
158    /* of the specification the bits are numbered from the  */
159    /* least significant end of a byte.                     */
160
161    for(i = 0; i < 256; ++i)
162    {
163        p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;
164        q = (q >> 7) | (q << 1); p ^= q;
165        q = (q >> 7) | (q << 1); p ^= q;
166        q = (q >> 7) | (q << 1); p ^= q;
167        q = (q >> 7) | (q << 1); p ^= q ^ 0x63;
168        sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;
169    }
170
171    for(i = 0; i < 256; ++i)
172    {
173        p = sbx_tab[i];
174
175#ifdef  LARGE_TABLES
176
177        t = p; fl_tab[0][i] = t;
178        fl_tab[1][i] = rotl(t,  8);
179        fl_tab[2][i] = rotl(t, 16);
180        fl_tab[3][i] = rotl(t, 24);
181#endif
182        t = ((u4byte)ff_mult(2, p)) |
183            ((u4byte)p <<  8) |
184            ((u4byte)p << 16) |
185            ((u4byte)ff_mult(3, p) << 24);
186
187        ft_tab[0][i] = t;
188        ft_tab[1][i] = rotl(t,  8);
189        ft_tab[2][i] = rotl(t, 16);
190        ft_tab[3][i] = rotl(t, 24);
191
192        p = isb_tab[i];
193
194#ifdef  LARGE_TABLES
195
196        t = p; il_tab[0][i] = t;
197        il_tab[1][i] = rotl(t,  8);
198        il_tab[2][i] = rotl(t, 16);
199        il_tab[3][i] = rotl(t, 24);
200#endif
201        t = ((u4byte)ff_mult(14, p)) |
202            ((u4byte)ff_mult( 9, p) <<  8) |
203            ((u4byte)ff_mult(13, p) << 16) |
204            ((u4byte)ff_mult(11, p) << 24);
205
206        it_tab[0][i] = t;
207        it_tab[1][i] = rotl(t,  8);
208        it_tab[2][i] = rotl(t, 16);
209        it_tab[3][i] = rotl(t, 24);
210    }
211
212    tab_gen = 1;
213};
214
215#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
216
217#define imix_col(y,x)       \
218    u   = star_x(x);        \
219    v   = star_x(u);        \
220    w   = star_x(v);        \
221    t   = w ^ (x);          \
222   (y)  = u ^ v ^ w;        \
223   (y) ^= rotr(u ^ t,  8) ^ \
224          rotr(v ^ t, 16) ^ \
225          rotr(t,24)
226
227/* initialise the key schedule from the user supplied key   */
228
229#define loop4(i)                                    \
230{   t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
231    t ^= e_key[4 * i];     e_key[4 * i + 4] = t;    \
232    t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t;    \
233    t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t;    \
234    t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t;    \
235}
236
237#define loop6(i)                                    \
238{   t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
239    t ^= e_key[6 * i];     e_key[6 * i + 6] = t;    \
240    t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t;    \
241    t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t;    \
242    t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t;    \
243    t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t;   \
244    t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t;   \
245}
246
247#define loop8(i)                                    \
248{   t = ls_box(rotr(t,  8)) ^ rco_tab[i];           \
249    t ^= e_key[8 * i];     e_key[8 * i + 8] = t;    \
250    t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t;    \
251    t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t;   \
252    t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t;   \
253    t  = e_key[8 * i + 4] ^ ls_box(t);              \
254    e_key[8 * i + 12] = t;                          \
255    t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t;   \
256    t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t;   \
257    t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t;   \
258}
259
260u4byte *set_key(const u4byte in_key[], const u4byte key_len)
261{   u4byte  i, t, u, v, w;
262
263    if(!tab_gen)
264
265        gen_tabs();
266
267    k_len = (key_len + 31) / 32;
268
269	#if		USE_SWAP_MACROS
270	get_key(e_key, key_len);
271	#else
272    e_key[0] = in_key[0]; e_key[1] = in_key[1];
273    e_key[2] = in_key[2]; e_key[3] = in_key[3];
274	#endif
275
276    switch(k_len)
277    {
278        case 4: t = e_key[3];
279                for(i = 0; i < 10; ++i)
280                    loop4(i);
281                break;
282
283        case 6:
284				#if	USE_SWAP_MACROS
285				t = e_key[5];
286				#else
287				/* done in get_key macros in USE_SWAP_MACROS case */
288				e_key[4] = in_key[4]; t = e_key[5] = in_key[5];
289				#endif
290                for(i = 0; i < 8; ++i)
291                    loop6(i);
292                break;
293
294        case 8:
295				#if	USE_SWAP_MACROS
296				t = e_key[7];
297				#else
298				e_key[4] = in_key[4]; e_key[5] = in_key[5];
299                e_key[6] = in_key[6]; t = e_key[7] = in_key[7];
300				#endif
301                for(i = 0; i < 7; ++i)
302                    loop8(i);
303                break;
304    }
305
306    d_key[0] = e_key[0]; d_key[1] = e_key[1];
307    d_key[2] = e_key[2]; d_key[3] = e_key[3];
308
309    for(i = 4; i < 4 * k_len + 24; ++i)
310    {
311        imix_col(d_key[i], e_key[i]);
312    }
313
314    return e_key;
315};
316
317/* encrypt a block of text  */
318
319#define f_nround(bo, bi, k) \
320    f_rn(bo, bi, 0, k);     \
321    f_rn(bo, bi, 1, k);     \
322    f_rn(bo, bi, 2, k);     \
323    f_rn(bo, bi, 3, k);     \
324    k += 4
325
326#define f_lround(bo, bi, k) \
327    f_rl(bo, bi, 0, k);     \
328    f_rl(bo, bi, 1, k);     \
329    f_rl(bo, bi, 2, k);     \
330    f_rl(bo, bi, 3, k)
331
332void rEncrypt(const u4byte in_blk[4], u4byte out_blk[4])
333{   u4byte  b0[4], b1[4], *kp;
334
335	#if USE_SWAP_MACROS
336	u4byte  swap_block[4];
337	get_block(swap_block);
338    b0[0] = swap_block[0] ^ e_key[0]; b0[1] = swap_block[1] ^ e_key[1];
339    b0[2] = swap_block[2] ^ e_key[2]; b0[3] = swap_block[3] ^ e_key[3];
340	#else
341    b0[0] = in_blk[0] ^ e_key[0]; b0[1] = in_blk[1] ^ e_key[1];
342    b0[2] = in_blk[2] ^ e_key[2]; b0[3] = in_blk[3] ^ e_key[3];
343	#endif
344
345    kp = e_key + 4;
346
347    if(k_len > 6)
348    {
349        f_nround(b1, b0, kp); f_nround(b0, b1, kp);
350    }
351
352    if(k_len > 4)
353    {
354        f_nround(b1, b0, kp); f_nround(b0, b1, kp);
355    }
356
357    f_nround(b1, b0, kp); f_nround(b0, b1, kp);
358    f_nround(b1, b0, kp); f_nround(b0, b1, kp);
359    f_nround(b1, b0, kp); f_nround(b0, b1, kp);
360    f_nround(b1, b0, kp); f_nround(b0, b1, kp);
361    f_nround(b1, b0, kp); f_lround(b0, b1, kp);
362
363	#if USE_SWAP_MACROS
364	put_block(b0);
365	#else
366    out_blk[0] = b0[0]; out_blk[1] = b0[1];
367    out_blk[2] = b0[2]; out_blk[3] = b0[3];
368	#endif
369};
370
371/* decrypt a block of text  */
372
373#define i_nround(bo, bi, k) \
374    i_rn(bo, bi, 0, k);     \
375    i_rn(bo, bi, 1, k);     \
376    i_rn(bo, bi, 2, k);     \
377    i_rn(bo, bi, 3, k);     \
378    k -= 4
379
380#define i_lround(bo, bi, k) \
381    i_rl(bo, bi, 0, k);     \
382    i_rl(bo, bi, 1, k);     \
383    i_rl(bo, bi, 2, k);     \
384    i_rl(bo, bi, 3, k)
385
386void rDecrypt(const u4byte in_blk[4], u4byte out_blk[4])
387{   u4byte  b0[4], b1[4], *kp;
388
389	#if USE_SWAP_MACROS
390	u4byte  swap_block[4];
391	get_block(swap_block);
392    b0[0] = swap_block[0] ^ e_key[4 * k_len + 24];
393	b0[1] = swap_block[1] ^ e_key[4 * k_len + 25];
394    b0[2] = swap_block[2] ^ e_key[4 * k_len + 26];
395	b0[3] = swap_block[3] ^ e_key[4 * k_len + 27];
396	#else
397    b0[0] = in_blk[0] ^ e_key[4 * k_len + 24];
398	b0[1] = in_blk[1] ^ e_key[4 * k_len + 25];
399    b0[2] = in_blk[2] ^ e_key[4 * k_len + 26];
400	b0[3] = in_blk[3] ^ e_key[4 * k_len + 27];
401	#endif
402
403    kp = d_key + 4 * (k_len + 5);
404
405    if(k_len > 6)
406    {
407        i_nround(b1, b0, kp); i_nround(b0, b1, kp);
408    }
409
410    if(k_len > 4)
411    {
412        i_nround(b1, b0, kp); i_nround(b0, b1, kp);
413    }
414
415    i_nround(b1, b0, kp); i_nround(b0, b1, kp);
416    i_nround(b1, b0, kp); i_nround(b0, b1, kp);
417    i_nround(b1, b0, kp); i_nround(b0, b1, kp);
418    i_nround(b1, b0, kp); i_nround(b0, b1, kp);
419    i_nround(b1, b0, kp); i_lround(b0, b1, kp);
420
421	#if USE_SWAP_MACROS
422	put_block(b0);
423	#else
424    out_blk[0] = b0[0]; out_blk[1] = b0[1];
425    out_blk[2] = b0[2]; out_blk[3] = b0[3];
426	#endif
427};
428