import from branch_1_1:
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_psk / AES.cpp
1 /**\r
2  * AES.cpp\r
3  *\r
4  * The Advanced Encryption Standard (AES, aka AES) block cipher,\r
5  * designed by J. Daemen and V. Rijmen.\r
6  *\r
7  * @author Paulo S. L. M. Barreto\r
8  *\r
9  * This software is hereby placed in the public domain.\r
10  *\r
11  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
12  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
13  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
14  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
15  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
16  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
17  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
18  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
19  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
20  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
21  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
22  */\r
23 \r
24 #include <freeradius-devel/ident.h>\r
25 RCSID("$Id$")\r
26 \r
27 #include <assert.h>\r
28 #include <string.h>\r
29 #include <stdlib.h>\r
30 \r
31 #include "AES.h"\r
32 #include "AES.tab"\r
33 \r
34 #define FULL_UNROLL\r
35 \r
36 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)\r
37 \r
38 #ifdef _MSC_VER\r
39 #define GETWORD(p) SWAP(*((uint *)(p)))\r
40 #define PUTWORD(ct, st) { *((uint *)(ct)) = SWAP((st)); }\r
41 #else\r
42 #define GETWORD(pt) (((uint)(pt)[0] << 24) ^ ((uint)(pt)[1] << 16) ^ ((uint)(pt)[2] <<  8) ^ ((uint)(pt)[3]))\r
43 #define PUTWORD(ct, st) { (ct)[0] = (byte)((st) >> 24); (ct)[1] = (byte)((st) >> 16); (ct)[2] = (byte)((st) >>  8); (ct)[3] = (byte)(st); }\r
44 #endif\r
45 \r
46 //////////////////////////////////////////////////////////////////////\r
47 // Construction/Destruction\r
48 //////////////////////////////////////////////////////////////////////\r
49 \r
50 AES::AES() {\r
51 }\r
52 \r
53 AES::~AES() {\r
54         Nr = 0;\r
55         memset(e_sched, 0, sizeof(e_sched));\r
56         memset(d_sched, 0, sizeof(d_sched));\r
57 }\r
58 \r
59 //////////////////////////////////////////////////////////////////////\r
60 // Support methods\r
61 //////////////////////////////////////////////////////////////////////\r
62 \r
63 void AES::ExpandKey(const byte *cipherKey, uint keyBits) {\r
64     uint *rek = e_sched;\r
65         int i = 0;\r
66         uint temp;\r
67 \r
68         rek[0] = GETWORD(cipherKey     );\r
69         rek[1] = GETWORD(cipherKey +  4);\r
70         rek[2] = GETWORD(cipherKey +  8);\r
71         rek[3] = GETWORD(cipherKey + 12);\r
72         if (keyBits == 128) {\r
73                 for (;;) {\r
74                         temp  = rek[3];\r
75                         rek[4] = rek[0] ^\r
76                                 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
77                                 (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
78                                 (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
79                                 (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
80                                 rcon[i];\r
81                         rek[5] = rek[1] ^ rek[4];\r
82                         rek[6] = rek[2] ^ rek[5];\r
83                         rek[7] = rek[3] ^ rek[6];\r
84                         if (++i == 10) {\r
85                                 Nr = 10;\r
86                                 return;\r
87                         }\r
88                         rek += 4;\r
89                 }\r
90         }\r
91         rek[4] = GETWORD(cipherKey + 16);\r
92         rek[5] = GETWORD(cipherKey + 20);\r
93         if (keyBits == 192) {\r
94                 for (;;) {\r
95                         temp = rek[ 5];\r
96                         rek[ 6] = rek[ 0] ^\r
97                                 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
98                                 (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
99                                 (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
100                                 (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
101                                 rcon[i];\r
102                         rek[ 7] = rek[ 1] ^ rek[ 6];\r
103                         rek[ 8] = rek[ 2] ^ rek[ 7];\r
104                         rek[ 9] = rek[ 3] ^ rek[ 8];\r
105                         if (++i == 8) {\r
106                                 Nr = 12;\r
107                                 return;\r
108                         }\r
109                         rek[10] = rek[ 4] ^ rek[ 9];\r
110                         rek[11] = rek[ 5] ^ rek[10];\r
111                         rek += 6;\r
112                 }\r
113         }\r
114         rek[6] = GETWORD(cipherKey + 24);\r
115         rek[7] = GETWORD(cipherKey + 28);\r
116         if (keyBits == 256) {\r
117         for (;;) {\r
118                 temp = rek[ 7];\r
119                 rek[ 8] = rek[ 0] ^\r
120                         (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
121                         (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
122                         (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
123                         (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
124                         rcon[i];\r
125                 rek[ 9] = rek[ 1] ^ rek[ 8];\r
126                 rek[10] = rek[ 2] ^ rek[ 9];\r
127                 rek[11] = rek[ 3] ^ rek[10];\r
128                         if (++i == 7) {\r
129                                 Nr = 14;\r
130                                 return;\r
131                         }\r
132                 temp = rek[11];\r
133                 rek[12] = rek[ 4] ^\r
134                         (Te4[(temp >> 24)       ] & 0xff000000) ^\r
135                         (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^\r
136                         (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^\r
137                         (Te4[(temp      ) & 0xff] & 0x000000ff);\r
138                 rek[13] = rek[ 5] ^ rek[12];\r
139                 rek[14] = rek[ 6] ^ rek[13];\r
140                 rek[15] = rek[ 7] ^ rek[14];\r
141 \r
142                         rek += 8;\r
143         }\r
144         }\r
145         Nr = 0;\r
146 }\r
147 \r
148 void AES::InvertKey() {\r
149     uint *rek = e_sched;\r
150     uint *rdk = d_sched;\r
151         uint r;\r
152 \r
153     assert(Nr == 10 || Nr == 12 || Nr == 14);\r
154     rek += 4*Nr;\r
155         /* apply the inverse MixColumn transform to all round keys but the first and the last: */\r
156     memcpy(rdk, rek, 16);\r
157         rdk += 4;\r
158         rek -= 4;\r
159         for (r = 1; r < Nr; r++) {\r
160                 rdk[0] =\r
161                         Td0[Te4[(rek[0] >> 24)       ] & 0xff] ^\r
162                         Td1[Te4[(rek[0] >> 16) & 0xff] & 0xff] ^\r
163                         Td2[Te4[(rek[0] >>  8) & 0xff] & 0xff] ^\r
164                         Td3[Te4[(rek[0]      ) & 0xff] & 0xff];\r
165                 rdk[1] =\r
166                         Td0[Te4[(rek[1] >> 24)       ] & 0xff] ^\r
167                         Td1[Te4[(rek[1] >> 16) & 0xff] & 0xff] ^\r
168                         Td2[Te4[(rek[1] >>  8) & 0xff] & 0xff] ^\r
169                         Td3[Te4[(rek[1]      ) & 0xff] & 0xff];\r
170                 rdk[2] =\r
171                         Td0[Te4[(rek[2] >> 24)       ] & 0xff] ^\r
172                         Td1[Te4[(rek[2] >> 16) & 0xff] & 0xff] ^\r
173                         Td2[Te4[(rek[2] >>  8) & 0xff] & 0xff] ^\r
174                         Td3[Te4[(rek[2]      ) & 0xff] & 0xff];\r
175                 rdk[3] =\r
176                         Td0[Te4[(rek[3] >> 24)       ] & 0xff] ^\r
177                         Td1[Te4[(rek[3] >> 16) & 0xff] & 0xff] ^\r
178                         Td2[Te4[(rek[3] >>  8) & 0xff] & 0xff] ^\r
179                         Td3[Te4[(rek[3]      ) & 0xff] & 0xff];\r
180                 rdk += 4;\r
181                 rek -= 4;\r
182         }\r
183     memcpy(rdk, rek, 16);\r
184 }\r
185 \r
186 //////////////////////////////////////////////////////////////////////\r
187 // Public Interface\r
188 //////////////////////////////////////////////////////////////////////\r
189 \r
190 void AES::makeKey(const byte *cipherKey, uint keySize, uint dir) {\r
191     switch (keySize) {\r
192     case  16: case  24: case  32:\r
193         keySize <<= 3; // key size is now in bits\r
194         break;\r
195     case 128: case 192: case 256:\r
196         break;\r
197     default:\r
198         assert(keySize == 16 || keySize == 24 || keySize == 32 || keySize == 128 || keySize == 192 || keySize == 256);\r
199     }\r
200     assert(dir >= DIR_NONE && dir <= DIR_BOTH);\r
201     if (dir != DIR_NONE) {\r
202         ExpandKey(cipherKey, keySize);\r
203             if (dir & DIR_DECRYPT) {\r
204             InvertKey();\r
205             }\r
206     }\r
207 }\r
208 \r
209 void AES::encrypt(const byte *pt, byte *ct) {\r
210     uint *rek = e_sched;\r
211         uint s0, s1, s2, s3, t0, t1, t2, t3;\r
212 #ifndef FULL_UNROLL\r
213     int r;\r
214 #endif /* ?FULL_UNROLL */\r
215 \r
216     /*\r
217          * map byte array block to cipher state\r
218          * and add initial round key:\r
219          */\r
220         s0 = GETWORD(pt     ) ^ rek[0];\r
221         s1 = GETWORD(pt +  4) ^ rek[1];\r
222         s2 = GETWORD(pt +  8) ^ rek[2];\r
223         s3 = GETWORD(pt + 12) ^ rek[3];\r
224 #ifdef FULL_UNROLL\r
225     /* round 1: */\r
226         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[ 4];\r
227         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[ 5];\r
228         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[ 6];\r
229         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[ 7];\r
230         /* round 2: */\r
231         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[ 8];\r
232         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[ 9];\r
233         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[10];\r
234         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[11];\r
235     /* round 3: */\r
236         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[12];\r
237         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[13];\r
238         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[14];\r
239         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[15];\r
240         /* round 4: */\r
241         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[16];\r
242         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[17];\r
243         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[18];\r
244         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[19];\r
245     /* round 5: */\r
246         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[20];\r
247         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[21];\r
248         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[22];\r
249         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[23];\r
250         /* round 6: */\r
251         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[24];\r
252         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[25];\r
253         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[26];\r
254         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[27];\r
255     /* round 7: */\r
256         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[28];\r
257         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[29];\r
258         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[30];\r
259         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[31];\r
260         /* round 8: */\r
261         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[32];\r
262         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[33];\r
263         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[34];\r
264         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[35];\r
265     /* round 9: */\r
266         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[36];\r
267         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[37];\r
268         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[38];\r
269         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[39];\r
270     if (Nr > 10) {\r
271         /* round 10: */\r
272         s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[40];\r
273         s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[41];\r
274         s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[42];\r
275         s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[43];\r
276         /* round 11: */\r
277         t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[44];\r
278         t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[45];\r
279         t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[46];\r
280         t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[47];\r
281         if (Nr > 12) {\r
282             /* round 12: */\r
283             s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[48];\r
284             s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[49];\r
285             s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[50];\r
286             s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[51];\r
287             /* round 13: */\r
288             t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[52];\r
289             t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[53];\r
290             t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[54];\r
291             t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[55];\r
292         }\r
293     }\r
294     rek += Nr << 2;\r
295 #else  /* !FULL_UNROLL */\r
296     /*\r
297          * Nr - 1 full rounds:\r
298          */\r
299     r = Nr >> 1;\r
300     for (;;) {\r
301         t0 =\r
302             Te0[(s0 >> 24)       ] ^\r
303             Te1[(s1 >> 16) & 0xff] ^\r
304             Te2[(s2 >>  8) & 0xff] ^\r
305             Te3[(s3      ) & 0xff] ^\r
306             rek[4];\r
307         t1 =\r
308             Te0[(s1 >> 24)       ] ^\r
309             Te1[(s2 >> 16) & 0xff] ^\r
310             Te2[(s3 >>  8) & 0xff] ^\r
311             Te3[(s0      ) & 0xff] ^\r
312             rek[5];\r
313         t2 =\r
314             Te0[(s2 >> 24)       ] ^\r
315             Te1[(s3 >> 16) & 0xff] ^\r
316             Te2[(s0 >>  8) & 0xff] ^\r
317             Te3[(s1      ) & 0xff] ^\r
318             rek[6];\r
319         t3 =\r
320             Te0[(s3 >> 24)       ] ^\r
321             Te1[(s0 >> 16) & 0xff] ^\r
322             Te2[(s1 >>  8) & 0xff] ^\r
323             Te3[(s2      ) & 0xff] ^\r
324             rek[7];\r
325 \r
326         rek += 8;\r
327         if (--r == 0) {\r
328             break;\r
329         }\r
330 \r
331         s0 =\r
332             Te0[(t0 >> 24)       ] ^\r
333             Te1[(t1 >> 16) & 0xff] ^\r
334             Te2[(t2 >>  8) & 0xff] ^\r
335             Te3[(t3      ) & 0xff] ^\r
336             rek[0];\r
337         s1 =\r
338             Te0[(t1 >> 24)       ] ^\r
339             Te1[(t2 >> 16) & 0xff] ^\r
340             Te2[(t3 >>  8) & 0xff] ^\r
341             Te3[(t0      ) & 0xff] ^\r
342             rek[1];\r
343         s2 =\r
344             Te0[(t2 >> 24)       ] ^\r
345             Te1[(t3 >> 16) & 0xff] ^\r
346             Te2[(t0 >>  8) & 0xff] ^\r
347             Te3[(t1      ) & 0xff] ^\r
348             rek[2];\r
349         s3 =\r
350             Te0[(t3 >> 24)       ] ^\r
351             Te1[(t0 >> 16) & 0xff] ^\r
352             Te2[(t1 >>  8) & 0xff] ^\r
353             Te3[(t2      ) & 0xff] ^\r
354             rek[3];\r
355     }\r
356 #endif /* ?FULL_UNROLL */\r
357     /*\r
358          * apply last round and\r
359          * map cipher state to byte array block:\r
360          */\r
361         s0 =\r
362                 (Te4[(t0 >> 24)       ] & 0xff000000) ^\r
363                 (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
364                 (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^\r
365                 (Te4[(t3      ) & 0xff] & 0x000000ff) ^\r
366                 rek[0];\r
367         PUTWORD(ct     , s0);\r
368         s1 =\r
369                 (Te4[(t1 >> 24)       ] & 0xff000000) ^\r
370                 (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
371                 (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^\r
372                 (Te4[(t0      ) & 0xff] & 0x000000ff) ^\r
373                 rek[1];\r
374         PUTWORD(ct +  4, s1);\r
375         s2 =\r
376                 (Te4[(t2 >> 24)       ] & 0xff000000) ^\r
377                 (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
378                 (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^\r
379                 (Te4[(t1      ) & 0xff] & 0x000000ff) ^\r
380                 rek[2];\r
381         PUTWORD(ct +  8, s2);\r
382         s3 =\r
383                 (Te4[(t3 >> 24)       ] & 0xff000000) ^\r
384                 (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
385                 (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^\r
386                 (Te4[(t2      ) & 0xff] & 0x000000ff) ^\r
387                 rek[3];\r
388         PUTWORD(ct + 12, s3);\r
389 }\r
390 \r
391 void AES::decrypt(const byte *ct, byte *pt) {\r
392     uint *rdk = d_sched;\r
393         uint s0, s1, s2, s3, t0, t1, t2, t3;\r
394 #ifndef FULL_UNROLL\r
395     int r;\r
396 #endif /* ?FULL_UNROLL */\r
397 \r
398     /*\r
399          * map byte array block to cipher state\r
400          * and add initial round key:\r
401          */\r
402     s0 = GETWORD(ct     ) ^ rdk[0];\r
403     s1 = GETWORD(ct +  4) ^ rdk[1];\r
404     s2 = GETWORD(ct +  8) ^ rdk[2];\r
405     s3 = GETWORD(ct + 12) ^ rdk[3];\r
406 #ifdef FULL_UNROLL\r
407     /* round 1: */\r
408     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[ 4];\r
409     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[ 5];\r
410     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[ 6];\r
411     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[ 7];\r
412     /* round 2: */\r
413     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[ 8];\r
414     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[ 9];\r
415     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[10];\r
416     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[11];\r
417     /* round 3: */\r
418     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[12];\r
419     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[13];\r
420     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[14];\r
421     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[15];\r
422     /* round 4: */\r
423     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[16];\r
424     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[17];\r
425     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[18];\r
426     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[19];\r
427     /* round 5: */\r
428     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[20];\r
429     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[21];\r
430     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[22];\r
431     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[23];\r
432     /* round 6: */\r
433     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[24];\r
434     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[25];\r
435     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[26];\r
436     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[27];\r
437     /* round 7: */\r
438     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[28];\r
439     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[29];\r
440     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[30];\r
441     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[31];\r
442     /* round 8: */\r
443     s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[32];\r
444     s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[33];\r
445     s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[34];\r
446     s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[35];\r
447     /* round 9: */\r
448     t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[36];\r
449     t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[37];\r
450     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[38];\r
451     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[39];\r
452     if (Nr > 10) {\r
453         /* round 10: */\r
454         s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[40];\r
455         s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[41];\r
456         s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[42];\r
457         s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[43];\r
458         /* round 11: */\r
459         t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[44];\r
460         t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[45];\r
461         t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[46];\r
462         t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[47];\r
463         if (Nr > 12) {\r
464             /* round 12: */\r
465             s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[48];\r
466             s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[49];\r
467             s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[50];\r
468             s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[51];\r
469             /* round 13: */\r
470             t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[52];\r
471             t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[53];\r
472             t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[54];\r
473             t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[55];\r
474         }\r
475     }\r
476         rdk += Nr << 2;\r
477 #else  /* !FULL_UNROLL */\r
478     /*\r
479      * Nr - 1 full rounds:\r
480      */\r
481     r = Nr >> 1;\r
482     for (;;) {\r
483         t0 =\r
484             Td0[(s0 >> 24)       ] ^\r
485             Td1[(s3 >> 16) & 0xff] ^\r
486             Td2[(s2 >>  8) & 0xff] ^\r
487             Td3[(s1      ) & 0xff] ^\r
488             rdk[4];\r
489         t1 =\r
490             Td0[(s1 >> 24)       ] ^\r
491             Td1[(s0 >> 16) & 0xff] ^\r
492             Td2[(s3 >>  8) & 0xff] ^\r
493             Td3[(s2      ) & 0xff] ^\r
494             rdk[5];\r
495         t2 =\r
496             Td0[(s2 >> 24)       ] ^\r
497             Td1[(s1 >> 16) & 0xff] ^\r
498             Td2[(s0 >>  8) & 0xff] ^\r
499             Td3[(s3      ) & 0xff] ^\r
500             rdk[6];\r
501         t3 =\r
502             Td0[(s3 >> 24)       ] ^\r
503             Td1[(s2 >> 16) & 0xff] ^\r
504             Td2[(s1 >>  8) & 0xff] ^\r
505             Td3[(s0      ) & 0xff] ^\r
506             rdk[7];\r
507 \r
508         rdk += 8;\r
509         if (--r == 0) {\r
510             break;\r
511         }\r
512 \r
513         s0 =\r
514             Td0[(t0 >> 24)       ] ^\r
515             Td1[(t3 >> 16) & 0xff] ^\r
516             Td2[(t2 >>  8) & 0xff] ^\r
517             Td3[(t1      ) & 0xff] ^\r
518             rdk[0];\r
519         s1 =\r
520             Td0[(t1 >> 24)       ] ^\r
521             Td1[(t0 >> 16) & 0xff] ^\r
522             Td2[(t3 >>  8) & 0xff] ^\r
523             Td3[(t2      ) & 0xff] ^\r
524             rdk[1];\r
525         s2 =\r
526             Td0[(t2 >> 24)       ] ^\r
527             Td1[(t1 >> 16) & 0xff] ^\r
528             Td2[(t0 >>  8) & 0xff] ^\r
529             Td3[(t3      ) & 0xff] ^\r
530             rdk[2];\r
531         s3 =\r
532             Td0[(t3 >> 24)       ] ^\r
533             Td1[(t2 >> 16) & 0xff] ^\r
534             Td2[(t1 >>  8) & 0xff] ^\r
535             Td3[(t0      ) & 0xff] ^\r
536             rdk[3];\r
537     }\r
538 #endif /* ?FULL_UNROLL */\r
539     /*\r
540          * apply last round and\r
541          * map cipher state to byte array block:\r
542          */\r
543         s0 =\r
544                 (Td4[(t0 >> 24)       ] & 0xff000000) ^\r
545                 (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
546                 (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^\r
547                 (Td4[(t1      ) & 0xff] & 0x000000ff) ^\r
548                 rdk[0];\r
549         PUTWORD(pt     , s0);\r
550         s1 =\r
551                 (Td4[(t1 >> 24)       ] & 0xff000000) ^\r
552                 (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
553                 (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^\r
554                 (Td4[(t2      ) & 0xff] & 0x000000ff) ^\r
555                 rdk[1];\r
556         PUTWORD(pt +  4, s1);\r
557         s2 =\r
558                 (Td4[(t2 >> 24)       ] & 0xff000000) ^\r
559                 (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
560                 (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^\r
561                 (Td4[(t3      ) & 0xff] & 0x000000ff) ^\r
562                 rdk[2];\r
563         PUTWORD(pt +  8, s2);\r
564         s3 =\r
565                 (Td4[(t3 >> 24)       ] & 0xff000000) ^\r
566                 (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
567                 (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^\r
568                 (Td4[(t0      ) & 0xff] & 0x000000ff) ^\r
569                 rdk[3];\r
570         PUTWORD(pt + 12, s3);\r
571 }\r
572 \r