www.usr.com/support/gpl/USR9107_release.1.4.tar.gz
[bcm963xx.git] / userapps / opensource / sshd / libtomcrypt / aes.c
1 /* AES implementation by Tom St Denis 
2  *
3  * Derived from the Public Domain source code by
4  
5 ---  
6   * rijndael-alg-fst.c
7   *
8   * @version 3.0 (December 2000)
9   *
10   * Optimised ANSI C code for the Rijndael cipher (now AES)
11   *
12   * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
13   * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
14   * @author Paulo Barreto <paulo.barreto@terra.com.br>
15 ---
16  */
17
18 #include "mycrypt.h"
19
20 #ifdef RIJNDAEL
21
22 const struct _cipher_descriptor rijndael_desc =
23 {
24     "rijndael",
25     6,
26     16, 32, 16, 10,
27     &rijndael_setup,
28     &rijndael_ecb_encrypt,
29     &rijndael_ecb_decrypt,
30     &rijndael_test,
31     &rijndael_keysize
32 };
33
34 const struct _cipher_descriptor aes_desc =
35 {
36     "aes",
37     6,
38     16, 32, 16, 10,
39     &rijndael_setup,
40     &rijndael_ecb_encrypt,
41     &rijndael_ecb_decrypt,
42     &rijndael_test,
43     &rijndael_keysize
44 };
45
46 #include "aes_tab.c"
47
48 int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
49 {
50     int i = 0, j;
51     unsigned long temp, *rk;
52     
53     _ARGCHK(key != NULL);
54     _ARGCHK(skey != NULL);
55     
56     if (keylen != 16 && keylen != 24 && keylen != 32) {
57        return CRYPT_INVALID_KEYSIZE;
58     }
59     
60     if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) {
61        return CRYPT_INVALID_ROUNDS;
62     }
63     
64     skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
65         
66     /* setup the forward key */
67     rk                = skey->rijndael.eK;
68     LOAD32H(rk[0], key     );
69     LOAD32H(rk[1], key +  4);
70     LOAD32H(rk[2], key +  8);
71     LOAD32H(rk[3], key + 12);
72     if (keylen == 16) {
73         for (;;) {
74             temp  = rk[3];
75             rk[4] = rk[0] ^
76                 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
77                 (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
78                 (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
79                 (Te4[(temp >> 24)       ] & 0x000000ff) ^
80                 rcon[i];
81             rk[5] = rk[1] ^ rk[4];
82             rk[6] = rk[2] ^ rk[5];
83             rk[7] = rk[3] ^ rk[6];
84             if (++i == 10) {
85                 break;
86             }
87             rk += 4;
88         }
89     } else if (keylen == 24) {
90         LOAD32H(rk[4], key + 16);
91         LOAD32H(rk[5], key + 20);
92         for (;;) {
93         #ifdef _MSC_VER
94             temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; 
95         #else
96             temp = rk[5];
97         #endif
98             rk[ 6] = rk[ 0] ^
99                 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
100                 (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
101                 (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
102                 (Te4[(temp >> 24)       ] & 0x000000ff) ^
103                 rcon[i];
104             rk[ 7] = rk[ 1] ^ rk[ 6];
105             rk[ 8] = rk[ 2] ^ rk[ 7];
106             rk[ 9] = rk[ 3] ^ rk[ 8];
107             if (++i == 8) {
108                 break;
109             }
110             rk[10] = rk[ 4] ^ rk[ 9];
111             rk[11] = rk[ 5] ^ rk[10];
112             rk += 6;
113         }
114     } else if (keylen == 32) {
115         LOAD32H(rk[4], key + 16);
116         LOAD32H(rk[5], key + 20);
117         LOAD32H(rk[6], key + 24);
118         LOAD32H(rk[7], key + 28);
119         for (;;) {
120         #ifdef _MSC_VER
121             temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; 
122         #else
123             temp = rk[7];
124         #endif
125             rk[ 8] = rk[ 0] ^
126                 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
127                 (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
128                 (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
129                 (Te4[(temp >> 24)       ] & 0x000000ff) ^
130                 rcon[i];
131             rk[ 9] = rk[ 1] ^ rk[ 8];
132             rk[10] = rk[ 2] ^ rk[ 9];
133             rk[11] = rk[ 3] ^ rk[10];
134             if (++i == 7) {
135                 break;
136             }
137             temp = rk[11];
138             rk[12] = rk[ 4] ^
139                 (Te4[(temp >> 24)       ] & 0xff000000) ^
140                 (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
141                 (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
142                 (Te4[(temp      ) & 0xff] & 0x000000ff);
143             rk[13] = rk[ 5] ^ rk[12];
144             rk[14] = rk[ 6] ^ rk[13];
145             rk[15] = rk[ 7] ^ rk[14];
146             rk += 8;
147         }
148     }
149     
150     /* setup the inverse key now */
151     memcpy(skey->rijndael.dK, skey->rijndael.eK, sizeof(skey->rijndael.eK));
152     rk = skey->rijndael.dK;
153     
154     for (i = 0, j = 4*skey->rijndael.Nr; i < j; i += 4, j -= 4) {
155         temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
156         temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
157         temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
158         temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
159     }
160     /* apply the inverse MixColumn transform to all round keys but the first and the last: */
161     for (i = 1; i < skey->rijndael.Nr; i++) {
162         rk += 4;
163         rk[0] =
164             Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
165             Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
166             Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
167             Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
168         rk[1] =
169             Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
170             Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
171             Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
172             Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
173         rk[2] =
174             Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
175             Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
176             Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
177             Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
178         rk[3] =
179             Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
180             Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
181             Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
182             Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
183     }
184     
185     return CRYPT_OK;   
186 }
187
188 void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
189 {
190     unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
191     int Nr;
192     
193 #ifdef SMALL_CODE
194     int r;
195 #endif 
196
197     _ARGCHK(pt != NULL);
198     _ARGCHK(ct != NULL);
199     _ARGCHK(skey != NULL);
200     
201     Nr = skey->rijndael.Nr;
202     rk = skey->rijndael.eK;
203     
204     /*
205      * map byte array block to cipher state
206      * and add initial round key:
207      */
208     LOAD32H(s0, pt      ); s0 ^= rk[0];
209     LOAD32H(s1, pt  +  4); s1 ^= rk[1];
210     LOAD32H(s2, pt  +  8); s2 ^= rk[2];
211     LOAD32H(s3, pt  + 12); s3 ^= rk[3];
212 #ifndef SMALL_CODE
213     /* round 1: */
214     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
215     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
216     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
217     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
218     /* round 2: */
219     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
220     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
221     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
222     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
223     /* round 3: */
224     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
225     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
226     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
227     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
228     /* round 4: */
229     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
230     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
231     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
232     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
233     /* round 5: */
234     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
235     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
236     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
237     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
238     /* round 6: */
239     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
240     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
241     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
242     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
243     /* round 7: */
244     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
245     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
246     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
247     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
248     /* round 8: */
249     s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
250     s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
251     s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
252     s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
253     /* round 9: */
254     t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
255     t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
256     t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
257     t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
258     if (Nr > 10) {
259         /* round 10: */
260         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
261         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
262         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
263         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
264         /* round 11: */
265         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
266         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
267         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
268         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
269         if (Nr > 12) {
270             /* round 12: */
271             s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
272             s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
273             s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
274             s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
275             /* round 13: */
276             t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
277             t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
278             t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
279             t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
280         }
281     }
282     rk += Nr << 2;
283 #else  /* SMALL_CODE */
284     /*
285      * Nr - 1 full rounds:
286      */
287     r = Nr >> 1;
288     for (;;) {
289
290 /* Both of these blocks are equivalent except the top is more friendlier for x86 processors */
291 #if 1
292         t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7];
293         t1 ^= Te3[(s0      ) & 0xFF]; t2 ^= Te2[(s0 >> 8) & 0xFF]; t3 ^= Te1[(s0 >> 16) & 0xFF]; t0 ^= Te0[(s0 >> 24)];
294         t2 ^= Te3[(s1      ) & 0xFF]; t3 ^= Te2[(s1 >> 8) & 0xFF]; t0 ^= Te1[(s1 >> 16) & 0xFF]; t1 ^= Te0[(s1 >> 24)];
295         t3 ^= Te3[(s2      ) & 0xFF]; t0 ^= Te2[(s2 >> 8) & 0xFF]; t1 ^= Te1[(s2 >> 16) & 0xFF]; t2 ^= Te0[(s2 >> 24)];
296         t0 ^= Te3[(s3      ) & 0xFF]; t1 ^= Te2[(s3 >> 8) & 0xFF]; t2 ^= Te1[(s3 >> 16) & 0xFF]; t3 ^= Te0[(s3 >> 24)];
297 #else
298         t0 =
299             Te0[(s0 >> 24)       ] ^
300             Te1[(s1 >> 16) & 0xff] ^
301             Te2[(s2 >>  8) & 0xff] ^
302             Te3[(s3      ) & 0xff] ^
303             rk[4];
304         t1 =
305             Te0[(s1 >> 24)       ] ^
306             Te1[(s2 >> 16) & 0xff] ^
307             Te2[(s3 >>  8) & 0xff] ^
308             Te3[(s0      ) & 0xff] ^
309             rk[5];
310         t2 =
311             Te0[(s2 >> 24)       ] ^
312             Te1[(s3 >> 16) & 0xff] ^
313             Te2[(s0 >>  8) & 0xff] ^
314             Te3[(s1      ) & 0xff] ^
315             rk[6];
316         t3 =
317             Te0[(s3 >> 24)       ] ^
318             Te1[(s0 >> 16) & 0xff] ^
319             Te2[(s1 >>  8) & 0xff] ^
320             Te3[(s2      ) & 0xff] ^
321             rk[7];
322 #endif
323        
324         rk += 8;
325         if (--r == 0) {
326             break;
327         }
328         
329 /* this second half optimization actually makes it slower on the Athlon, use with caution. */
330 #if 0
331         s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; s0 = rk[0]; 
332         s1 ^= Te3[(t0      ) & 0xFF]; s2 ^= Te2[(t0 >> 8) & 0xFF]; s3 ^= Te1[(t0 >> 16) & 0xFF]; s0 ^= Te0[(t0 >> 24)];
333         s2 ^= Te3[(t1      ) & 0xFF]; s3 ^= Te2[(t1 >> 8) & 0xFF]; s0 ^= Te1[(t1 >> 16) & 0xFF]; s1 ^= Te0[(t1 >> 24)];
334         s3 ^= Te3[(t2      ) & 0xFF]; s0 ^= Te2[(t2 >> 8) & 0xFF]; s1 ^= Te1[(t2 >> 16) & 0xFF]; s2 ^= Te0[(t2 >> 24)];
335         s0 ^= Te3[(t3      ) & 0xFF]; s1 ^= Te2[(t3 >> 8) & 0xFF]; s2 ^= Te1[(t3 >> 16) & 0xFF]; s3 ^= Te0[(t3 >> 24)];
336 #else
337         s0 =
338             Te0[(t0 >> 24)       ] ^
339             Te1[(t1 >> 16) & 0xff] ^
340             Te2[(t2 >>  8) & 0xff] ^
341             Te3[(t3      ) & 0xff] ^
342             rk[0];
343         s1 =
344             Te0[(t1 >> 24)       ] ^
345             Te1[(t2 >> 16) & 0xff] ^
346             Te2[(t3 >>  8) & 0xff] ^
347             Te3[(t0      ) & 0xff] ^
348             rk[1];
349         s2 =
350             Te0[(t2 >> 24)       ] ^
351             Te1[(t3 >> 16) & 0xff] ^
352             Te2[(t0 >>  8) & 0xff] ^
353             Te3[(t1      ) & 0xff] ^
354             rk[2];
355         s3 =
356             Te0[(t3 >> 24)       ] ^
357             Te1[(t0 >> 16) & 0xff] ^
358             Te2[(t1 >>  8) & 0xff] ^
359             Te3[(t2      ) & 0xff] ^
360             rk[3];
361 #endif            
362     }
363 #endif /* SMALL_CODE */
364     /*
365      * apply last round and
366      * map cipher state to byte array block:
367      */
368     s0 =
369         (Te4[(t0 >> 24)       ] & 0xff000000) ^
370         (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
371         (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
372         (Te4[(t3      ) & 0xff] & 0x000000ff) ^
373         rk[0];
374     STORE32H(s0, ct);
375     s1 =
376         (Te4[(t1 >> 24)       ] & 0xff000000) ^
377         (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
378         (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
379         (Te4[(t0      ) & 0xff] & 0x000000ff) ^
380         rk[1];
381     STORE32H(s1, ct+4);
382     s2 =
383         (Te4[(t2 >> 24)       ] & 0xff000000) ^
384         (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
385         (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
386         (Te4[(t1      ) & 0xff] & 0x000000ff) ^
387         rk[2];
388     STORE32H(s2, ct+8);
389     s3 =
390         (Te4[(t3 >> 24)       ] & 0xff000000) ^
391         (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
392         (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
393         (Te4[(t2      ) & 0xff] & 0x000000ff) ^
394         rk[3];
395     STORE32H(s3, ct+12);
396 }
397
398 void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) {
399     unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
400     int Nr;
401 #ifdef SMALL_CODE
402     int r;
403 #endif /* SMALL_CODE */
404
405     _ARGCHK(pt != NULL);
406     _ARGCHK(ct != NULL);
407     _ARGCHK(skey != NULL);
408     
409     Nr = skey->rijndael.Nr;
410     rk = skey->rijndael.dK;
411
412     /*
413      * map byte array block to cipher state
414      * and add initial round key:
415      */
416     LOAD32H(s0, ct      ); s0 ^= rk[0];
417     LOAD32H(s1, ct  +  4); s1 ^= rk[1];
418     LOAD32H(s2, ct  +  8); s2 ^= rk[2];
419     LOAD32H(s3, ct  + 12); s3 ^= rk[3];
420 #ifndef SMALL_CODE
421     /* round 1: */
422     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
423     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
424     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
425     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
426     /* round 2: */
427     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
428     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
429     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
430     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
431     /* round 3: */
432     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
433     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
434     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
435     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
436     /* round 4: */
437     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
438     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
439     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
440     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
441     /* round 5: */
442     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
443     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
444     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
445     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
446     /* round 6: */
447     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
448     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
449     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
450     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
451     /* round 7: */
452     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
453     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
454     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
455     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
456     /* round 8: */
457     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
458     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
459     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
460     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
461     /* round 9: */
462     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
463     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
464     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
465     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
466     if (Nr > 10) {
467         /* round 10: */
468         s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
469         s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
470         s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
471         s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
472         /* round 11: */
473         t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
474         t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
475         t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
476         t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
477         if (Nr > 12) {
478             /* round 12: */
479             s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
480             s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
481             s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
482             s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
483             /* round 13: */
484             t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
485             t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
486             t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
487             t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
488         }
489     }
490     rk += Nr << 2;
491 #else  /* SMALL_CODE */
492     /*
493      * Nr - 1 full rounds:
494      */
495     r = Nr >> 1;
496     for (;;) {
497         t0 =
498             Td0[(s0 >> 24)       ] ^
499             Td1[(s3 >> 16) & 0xff] ^
500             Td2[(s2 >>  8) & 0xff] ^
501             Td3[(s1      ) & 0xff] ^
502             rk[4];
503         t1 =
504             Td0[(s1 >> 24)       ] ^
505             Td1[(s0 >> 16) & 0xff] ^
506             Td2[(s3 >>  8) & 0xff] ^
507             Td3[(s2      ) & 0xff] ^
508             rk[5];
509         t2 =
510             Td0[(s2 >> 24)       ] ^
511             Td1[(s1 >> 16) & 0xff] ^
512             Td2[(s0 >>  8) & 0xff] ^
513             Td3[(s3      ) & 0xff] ^
514             rk[6];
515         t3 =
516             Td0[(s3 >> 24)       ] ^
517             Td1[(s2 >> 16) & 0xff] ^
518             Td2[(s1 >>  8) & 0xff] ^
519             Td3[(s0      ) & 0xff] ^
520             rk[7];
521
522         rk += 8;
523         if (--r == 0) {
524             break;
525         }
526
527         s0 =
528             Td0[(t0 >> 24)       ] ^
529             Td1[(t3 >> 16) & 0xff] ^
530             Td2[(t2 >>  8) & 0xff] ^
531             Td3[(t1      ) & 0xff] ^
532             rk[0];
533         s1 =
534             Td0[(t1 >> 24)       ] ^
535             Td1[(t0 >> 16) & 0xff] ^
536             Td2[(t3 >>  8) & 0xff] ^
537             Td3[(t2      ) & 0xff] ^
538             rk[1];
539         s2 =
540             Td0[(t2 >> 24)       ] ^
541             Td1[(t1 >> 16) & 0xff] ^
542             Td2[(t0 >>  8) & 0xff] ^
543             Td3[(t3      ) & 0xff] ^
544             rk[2];
545         s3 =
546             Td0[(t3 >> 24)       ] ^
547             Td1[(t2 >> 16) & 0xff] ^
548             Td2[(t1 >>  8) & 0xff] ^
549             Td3[(t0      ) & 0xff] ^
550             rk[3];
551     }
552 #endif /* SMALL_CODE */
553     /*
554      * apply last round and
555      * map cipher state to byte array block:
556      */
557     s0 =
558         (Td4[(t0 >> 24)       ] & 0xff000000) ^
559         (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
560         (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
561         (Td4[(t1      ) & 0xff] & 0x000000ff) ^
562         rk[0];
563     STORE32H(s0, pt);
564     s1 =
565         (Td4[(t1 >> 24)       ] & 0xff000000) ^
566         (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
567         (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
568         (Td4[(t2      ) & 0xff] & 0x000000ff) ^
569         rk[1];
570     STORE32H(s1, pt+4);
571     s2 =
572         (Td4[(t2 >> 24)       ] & 0xff000000) ^
573         (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
574         (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
575         (Td4[(t3      ) & 0xff] & 0x000000ff) ^
576         rk[2];
577     STORE32H(s2, pt+8);
578     s3 =
579         (Td4[(t3 >> 24)       ] & 0xff000000) ^
580         (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
581         (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
582         (Td4[(t0      ) & 0xff] & 0x000000ff) ^
583         rk[3];
584     STORE32H(s3, pt+12);
585 }
586
587 int rijndael_test(void)
588 {
589  #ifndef LTC_TEST
590     return CRYPT_NOP;
591  #else    
592  int err;
593  static const struct {
594      int keylen;
595      unsigned char key[32], pt[16], ct[16];
596  } tests[] = {
597     { 16,
598       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
599         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 
600       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
601         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
602       { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 
603         0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
604     }, { 
605       24,
606       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
607         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
608         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
609       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
610         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
611       { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 
612         0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
613     }, {
614       32,
615       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
616         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
617         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
618         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
619       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
620         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
621       { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 
622         0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
623     }
624  };
625  
626  symmetric_key key;
627  unsigned char tmp[2][16];
628  int i;
629  
630  for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
631     zeromem(&key, sizeof(key));
632     if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { 
633        return err;
634     }
635   
636     rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
637     rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
638     if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { 
639 #if 0
640        printf("\n\nTest %d failed\n", i);
641        if (memcmp(tmp[0], tests[i].ct, 16)) {
642           printf("CT: ");
643           for (i = 0; i < 16; i++) {
644              printf("%02x ", tmp[0][i]);
645           }
646           printf("\n");
647        } else {
648           printf("PT: ");
649           for (i = 0; i < 16; i++) {
650              printf("%02x ", tmp[1][i]);
651           }
652           printf("\n");
653        }
654 #endif       
655         return CRYPT_FAIL_TESTVECTOR;
656     }
657  }       
658  return CRYPT_OK;
659  #endif
660 }
661
662 int rijndael_keysize(int *desired_keysize)
663 {
664    _ARGCHK(desired_keysize != NULL);
665
666    if (*desired_keysize < 16)
667       return CRYPT_INVALID_KEYSIZE;
668    if (*desired_keysize < 24) {
669       *desired_keysize = 16;
670       return CRYPT_OK;
671    } else if (*desired_keysize < 32) {
672       *desired_keysize = 24;
673       return CRYPT_OK;
674    } else {
675       *desired_keysize = 32;
676       return CRYPT_OK;
677    }
678 }
679
680 #endif
681