Blob


1 /*
2 * this code is derived from the following source,
3 * and modified to fit into the plan 9 libsec interface.
4 * most of the changes are confined to the top section,
5 * with the exception of converting Te4 and Td4 into u8 rather than u32 arrays.
6 *
7 * rijndael-alg-fst.c
8 *
9 * @version 3.0 (December 2000)
10 *
11 * Optimised ANSI C code for the Rijndael cipher (now AES)
12 *
13 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
14 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
15 * @author Paulo Barreto <paulo.barreto@terra.com.br>
16 *
17 * This code is hereby placed in the public domain.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <u.h>
32 #include <libc.h>
33 #include <libsec.h>
35 typedef uchar u8;
36 typedef u32int u32;
37 #define FULL_UNROLL
39 static const u32 Td0[256];
40 static const u32 Td1[256];
41 static const u32 Td2[256];
42 static const u32 Td3[256];
43 static const u8 Te4[256];
45 static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
46 static int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
47 static int rijndaelKeySetup(u32 erk[/*4*(Nr + 1)*/], u32 drk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits);
48 static void rijndaelEncrypt(const u32int rk[], int Nr, const uchar pt[16], uchar ct[16]);
49 static void rijndaelDecrypt(const u32int rk[], int Nr, const uchar ct[16], uchar pt[16]);
51 void
52 setupAESstate(AESstate *s, uchar key[], int keybytes, uchar *ivec)
53 {
54 memset(s, 0, sizeof(*s));
55 if(keybytes > AESmaxkey)
56 keybytes = AESmaxkey;
57 memmove(s->key, key, keybytes);
58 s->keybytes = keybytes;
59 s->rounds = rijndaelKeySetup(s->ekey, s->dkey, s->key, keybytes * 8);
60 if(ivec != nil)
61 memmove(s->ivec, ivec, AESbsize);
62 if(keybytes==16 || keybytes==24 || keybytes==32)
63 s->setup = 0xcafebabe;
64 // else rijndaelKeySetup was invalid
65 }
67 // Define by analogy with desCBCencrypt; AES modes are not standardized yet.
68 // Because of the way that non-multiple-of-16 buffers are handled,
69 // the decryptor must be fed buffers of the same size as the encryptor.
70 void
71 aesCBCencrypt(uchar *p, int len, AESstate *s)
72 {
73 uchar *p2, *ip, *eip;
74 uchar q[AESbsize];
76 for(; len >= AESbsize; len -= AESbsize){
77 p2 = p;
78 ip = s->ivec;
79 for(eip = ip+AESbsize; ip < eip; )
80 *p2++ ^= *ip++;
81 rijndaelEncrypt(s->ekey, s->rounds, p, q);
82 memmove(s->ivec, q, AESbsize);
83 memmove(p, q, AESbsize);
84 p += AESbsize;
85 }
87 if(len > 0){
88 ip = s->ivec;
89 rijndaelEncrypt(s->ekey, s->rounds, ip, q);
90 memmove(s->ivec, q, AESbsize);
91 for(eip = ip+len; ip < eip; )
92 *p++ ^= *ip++;
93 }
94 }
96 void
97 aesCBCdecrypt(uchar *p, int len, AESstate *s)
98 {
99 uchar *ip, *eip, *tp;
100 uchar tmp[AESbsize], q[AESbsize];
102 for(; len >= AESbsize; len -= AESbsize){
103 memmove(tmp, p, AESbsize);
104 rijndaelDecrypt(s->dkey, s->rounds, p, q);
105 memmove(p, q, AESbsize);
106 tp = tmp;
107 ip = s->ivec;
108 for(eip = ip+AESbsize; ip < eip; ){
109 *p++ ^= *ip;
110 *ip++ = *tp++;
114 if(len > 0){
115 ip = s->ivec;
116 rijndaelEncrypt(s->ekey, s->rounds, ip, q);
117 memmove(s->ivec, q, AESbsize);
118 for(eip = ip+len; ip < eip; )
119 *p++ ^= *ip++;
123 /*
124 * this function has been changed for plan 9.
125 * Expand the cipher key into the encryption and decryption key schedules.
127 * @return the number of rounds for the given cipher key size.
128 */
129 static int rijndaelKeySetup(u32 erk[/*4*(Nr + 1)*/], u32 drk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
130 int Nr, i;
132 /* expand the cipher key: */
133 Nr = rijndaelKeySetupEnc(erk, cipherKey, keyBits);
135 /*
136 * invert the order of the round keys and
137 * apply the inverse MixColumn transform to all round keys but the first and the last
138 */
139 drk[0 ] = erk[4*Nr ];
140 drk[1 ] = erk[4*Nr + 1];
141 drk[2 ] = erk[4*Nr + 2];
142 drk[3 ] = erk[4*Nr + 3];
143 drk[4*Nr ] = erk[0 ];
144 drk[4*Nr + 1] = erk[1 ];
145 drk[4*Nr + 2] = erk[2 ];
146 drk[4*Nr + 3] = erk[3 ];
147 erk += 4 * Nr;
148 for (i = 1; i < Nr; i++) {
149 drk += 4;
150 erk -= 4;
151 drk[0] =
152 Td0[Te4[(erk[0] >> 24) ]] ^
153 Td1[Te4[(erk[0] >> 16) & 0xff]] ^
154 Td2[Te4[(erk[0] >> 8) & 0xff]] ^
155 Td3[Te4[(erk[0] ) & 0xff]];
156 drk[1] =
157 Td0[Te4[(erk[1] >> 24) ]] ^
158 Td1[Te4[(erk[1] >> 16) & 0xff]] ^
159 Td2[Te4[(erk[1] >> 8) & 0xff]] ^
160 Td3[Te4[(erk[1] ) & 0xff]];
161 drk[2] =
162 Td0[Te4[(erk[2] >> 24) ]] ^
163 Td1[Te4[(erk[2] >> 16) & 0xff]] ^
164 Td2[Te4[(erk[2] >> 8) & 0xff]] ^
165 Td3[Te4[(erk[2] ) & 0xff]];
166 drk[3] =
167 Td0[Te4[(erk[3] >> 24) ]] ^
168 Td1[Te4[(erk[3] >> 16) & 0xff]] ^
169 Td2[Te4[(erk[3] >> 8) & 0xff]] ^
170 Td3[Te4[(erk[3] ) & 0xff]];
172 return Nr;
175 /*
176 Te0[x] = S [x].[02, 01, 01, 03];
177 Te1[x] = S [x].[03, 02, 01, 01];
178 Te2[x] = S [x].[01, 03, 02, 01];
179 Te3[x] = S [x].[01, 01, 03, 02];
180 Te4[x] = S [x]
182 Td0[x] = Si[x].[0e, 09, 0d, 0b];
183 Td1[x] = Si[x].[0b, 0e, 09, 0d];
184 Td2[x] = Si[x].[0d, 0b, 0e, 09];
185 Td3[x] = Si[x].[09, 0d, 0b, 0e];
186 Td4[x] = Si[x]
187 */
189 static const u32 Te0[256] = {
190 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
191 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
192 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
193 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
194 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
195 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
196 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
197 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
198 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
199 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
200 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
201 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
202 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
203 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
204 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
205 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
206 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
207 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
208 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
209 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
210 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
211 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
212 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
213 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
214 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
215 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
216 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
217 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
218 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
219 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
220 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
221 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
222 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
223 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
224 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
225 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
226 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
227 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
228 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
229 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
230 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
231 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
232 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
233 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
234 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
235 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
236 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
237 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
238 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
239 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
240 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
241 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
242 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
243 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
244 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
245 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
246 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
247 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
248 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
249 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
250 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
251 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
252 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
253 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
254 };
255 static const u32 Te1[256] = {
256 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
257 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
258 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
259 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
260 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
261 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
262 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
263 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
264 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
265 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
266 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
267 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
268 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
269 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
270 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
271 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
272 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
273 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
274 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
275 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
276 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
277 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
278 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
279 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
280 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
281 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
282 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
283 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
284 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
285 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
286 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
287 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
288 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
289 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
290 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
291 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
292 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
293 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
294 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
295 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
296 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
297 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
298 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
299 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
300 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
301 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
302 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
303 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
304 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
305 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
306 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
307 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
308 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
309 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
310 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
311 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
312 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
313 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
314 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
315 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
316 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
317 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
318 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
319 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
320 };
321 static const u32 Te2[256] = {
322 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
323 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
324 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
325 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
326 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
327 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
328 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
329 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
330 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
331 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
332 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
333 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
334 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
335 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
336 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
337 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
338 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
339 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
340 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
341 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
342 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
343 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
344 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
345 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
346 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
347 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
348 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
349 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
350 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
351 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
352 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
353 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
354 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
355 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
356 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
357 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
358 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
359 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
360 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
361 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
362 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
363 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
364 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
365 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
366 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
367 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
368 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
369 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
370 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
371 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
372 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
373 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
374 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
375 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
376 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
377 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
378 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
379 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
380 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
381 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
382 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
383 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
384 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
385 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
386 };
387 static const u32 Te3[256] = {
389 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
390 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
391 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
392 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
393 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
394 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
395 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
396 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
397 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
398 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
399 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
400 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
401 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
402 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
403 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
404 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
405 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
406 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
407 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
408 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
409 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
410 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
411 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
412 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
413 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
414 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
415 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
416 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
417 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
418 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
419 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
420 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
421 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
422 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
423 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
424 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
425 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
426 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
427 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
428 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
429 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
430 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
431 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
432 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
433 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
434 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
435 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
436 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
437 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
438 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
439 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
440 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
441 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
442 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
443 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
444 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
445 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
446 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
447 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
448 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
449 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
450 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
451 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
452 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
453 };
454 static const u8 Te4[256] = {
455 0x63U, 0x7cU, 0x77U, 0x7bU,
456 0xf2U, 0x6bU, 0x6fU, 0xc5U,
457 0x30U, 0x01U, 0x67U, 0x2bU,
458 0xfeU, 0xd7U, 0xabU, 0x76U,
459 0xcaU, 0x82U, 0xc9U, 0x7dU,
460 0xfaU, 0x59U, 0x47U, 0xf0U,
461 0xadU, 0xd4U, 0xa2U, 0xafU,
462 0x9cU, 0xa4U, 0x72U, 0xc0U,
463 0xb7U, 0xfdU, 0x93U, 0x26U,
464 0x36U, 0x3fU, 0xf7U, 0xccU,
465 0x34U, 0xa5U, 0xe5U, 0xf1U,
466 0x71U, 0xd8U, 0x31U, 0x15U,
467 0x04U, 0xc7U, 0x23U, 0xc3U,
468 0x18U, 0x96U, 0x05U, 0x9aU,
469 0x07U, 0x12U, 0x80U, 0xe2U,
470 0xebU, 0x27U, 0xb2U, 0x75U,
471 0x09U, 0x83U, 0x2cU, 0x1aU,
472 0x1bU, 0x6eU, 0x5aU, 0xa0U,
473 0x52U, 0x3bU, 0xd6U, 0xb3U,
474 0x29U, 0xe3U, 0x2fU, 0x84U,
475 0x53U, 0xd1U, 0x00U, 0xedU,
476 0x20U, 0xfcU, 0xb1U, 0x5bU,
477 0x6aU, 0xcbU, 0xbeU, 0x39U,
478 0x4aU, 0x4cU, 0x58U, 0xcfU,
479 0xd0U, 0xefU, 0xaaU, 0xfbU,
480 0x43U, 0x4dU, 0x33U, 0x85U,
481 0x45U, 0xf9U, 0x02U, 0x7fU,
482 0x50U, 0x3cU, 0x9fU, 0xa8U,
483 0x51U, 0xa3U, 0x40U, 0x8fU,
484 0x92U, 0x9dU, 0x38U, 0xf5U,
485 0xbcU, 0xb6U, 0xdaU, 0x21U,
486 0x10U, 0xffU, 0xf3U, 0xd2U,
487 0xcdU, 0x0cU, 0x13U, 0xecU,
488 0x5fU, 0x97U, 0x44U, 0x17U,
489 0xc4U, 0xa7U, 0x7eU, 0x3dU,
490 0x64U, 0x5dU, 0x19U, 0x73U,
491 0x60U, 0x81U, 0x4fU, 0xdcU,
492 0x22U, 0x2aU, 0x90U, 0x88U,
493 0x46U, 0xeeU, 0xb8U, 0x14U,
494 0xdeU, 0x5eU, 0x0bU, 0xdbU,
495 0xe0U, 0x32U, 0x3aU, 0x0aU,
496 0x49U, 0x06U, 0x24U, 0x5cU,
497 0xc2U, 0xd3U, 0xacU, 0x62U,
498 0x91U, 0x95U, 0xe4U, 0x79U,
499 0xe7U, 0xc8U, 0x37U, 0x6dU,
500 0x8dU, 0xd5U, 0x4eU, 0xa9U,
501 0x6cU, 0x56U, 0xf4U, 0xeaU,
502 0x65U, 0x7aU, 0xaeU, 0x08U,
503 0xbaU, 0x78U, 0x25U, 0x2eU,
504 0x1cU, 0xa6U, 0xb4U, 0xc6U,
505 0xe8U, 0xddU, 0x74U, 0x1fU,
506 0x4bU, 0xbdU, 0x8bU, 0x8aU,
507 0x70U, 0x3eU, 0xb5U, 0x66U,
508 0x48U, 0x03U, 0xf6U, 0x0eU,
509 0x61U, 0x35U, 0x57U, 0xb9U,
510 0x86U, 0xc1U, 0x1dU, 0x9eU,
511 0xe1U, 0xf8U, 0x98U, 0x11U,
512 0x69U, 0xd9U, 0x8eU, 0x94U,
513 0x9bU, 0x1eU, 0x87U, 0xe9U,
514 0xceU, 0x55U, 0x28U, 0xdfU,
515 0x8cU, 0xa1U, 0x89U, 0x0dU,
516 0xbfU, 0xe6U, 0x42U, 0x68U,
517 0x41U, 0x99U, 0x2dU, 0x0fU,
518 0xb0U, 0x54U, 0xbbU, 0x16U,
519 };
520 static const u32 Td0[256] = {
521 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
522 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
523 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
524 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
525 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
526 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
527 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
528 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
529 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
530 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
531 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
532 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
533 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
534 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
535 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
536 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
537 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
538 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
539 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
540 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
541 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
542 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
543 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
544 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
545 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
546 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
547 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
548 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
549 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
550 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
551 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
552 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
553 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
554 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
555 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
556 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
557 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
558 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
559 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
560 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
561 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
562 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
563 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
564 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
565 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
566 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
567 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
568 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
569 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
570 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
571 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
572 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
573 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
574 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
575 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
576 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
577 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
578 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
579 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
580 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
581 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
582 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
583 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
584 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
585 };
586 static const u32 Td1[256] = {
587 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
588 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
589 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
590 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
591 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
592 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
593 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
594 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
595 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
596 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
597 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
598 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
599 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
600 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
601 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
602 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
603 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
604 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
605 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
606 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
607 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
608 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
609 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
610 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
611 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
612 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
613 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
614 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
615 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
616 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
617 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
618 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
619 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
620 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
621 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
622 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
623 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
624 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
625 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
626 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
627 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
628 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
629 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
630 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
631 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
632 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
633 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
634 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
635 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
636 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
637 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
638 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
639 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
640 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
641 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
642 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
643 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
644 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
645 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
646 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
647 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
648 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
649 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
650 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
651 };
652 static const u32 Td2[256] = {
653 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
654 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
655 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
656 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
657 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
658 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
659 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
660 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
661 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
662 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
663 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
664 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
665 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
666 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
667 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
668 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
669 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
670 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
671 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
672 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
674 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
675 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
676 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
677 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
678 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
679 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
680 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
681 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
682 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
683 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
684 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
685 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
686 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
687 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
688 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
689 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
690 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
691 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
692 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
693 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
694 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
695 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
696 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
697 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
698 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
699 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
700 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
701 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
702 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
703 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
704 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
705 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
706 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
707 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
708 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
709 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
710 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
711 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
712 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
713 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
714 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
715 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
716 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
717 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
718 };
719 static const u32 Td3[256] = {
720 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
721 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
722 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
723 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
724 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
725 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
726 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
727 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
728 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
729 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
730 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
731 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
732 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
733 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
734 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
735 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
736 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
737 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
738 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
739 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
740 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
741 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
742 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
743 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
744 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
745 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
746 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
747 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
748 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
749 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
750 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
751 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
752 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
753 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
754 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
755 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
756 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
757 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
758 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
759 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
760 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
761 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
762 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
763 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
764 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
765 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
766 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
767 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
768 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
769 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
770 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
771 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
772 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
773 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
774 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
775 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
776 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
777 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
778 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
779 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
780 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
781 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
782 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
783 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
784 };
785 static const u8 Td4[256] = {
786 0x52U, 0x09U, 0x6aU, 0xd5U,
787 0x30U, 0x36U, 0xa5U, 0x38U,
788 0xbfU, 0x40U, 0xa3U, 0x9eU,
789 0x81U, 0xf3U, 0xd7U, 0xfbU,
790 0x7cU, 0xe3U, 0x39U, 0x82U,
791 0x9bU, 0x2fU, 0xffU, 0x87U,
792 0x34U, 0x8eU, 0x43U, 0x44U,
793 0xc4U, 0xdeU, 0xe9U, 0xcbU,
794 0x54U, 0x7bU, 0x94U, 0x32U,
795 0xa6U, 0xc2U, 0x23U, 0x3dU,
796 0xeeU, 0x4cU, 0x95U, 0x0bU,
797 0x42U, 0xfaU, 0xc3U, 0x4eU,
798 0x08U, 0x2eU, 0xa1U, 0x66U,
799 0x28U, 0xd9U, 0x24U, 0xb2U,
800 0x76U, 0x5bU, 0xa2U, 0x49U,
801 0x6dU, 0x8bU, 0xd1U, 0x25U,
802 0x72U, 0xf8U, 0xf6U, 0x64U,
803 0x86U, 0x68U, 0x98U, 0x16U,
804 0xd4U, 0xa4U, 0x5cU, 0xccU,
805 0x5dU, 0x65U, 0xb6U, 0x92U,
806 0x6cU, 0x70U, 0x48U, 0x50U,
807 0xfdU, 0xedU, 0xb9U, 0xdaU,
808 0x5eU, 0x15U, 0x46U, 0x57U,
809 0xa7U, 0x8dU, 0x9dU, 0x84U,
810 0x90U, 0xd8U, 0xabU, 0x00U,
811 0x8cU, 0xbcU, 0xd3U, 0x0aU,
812 0xf7U, 0xe4U, 0x58U, 0x05U,
813 0xb8U, 0xb3U, 0x45U, 0x06U,
814 0xd0U, 0x2cU, 0x1eU, 0x8fU,
815 0xcaU, 0x3fU, 0x0fU, 0x02U,
816 0xc1U, 0xafU, 0xbdU, 0x03U,
817 0x01U, 0x13U, 0x8aU, 0x6bU,
818 0x3aU, 0x91U, 0x11U, 0x41U,
819 0x4fU, 0x67U, 0xdcU, 0xeaU,
820 0x97U, 0xf2U, 0xcfU, 0xceU,
821 0xf0U, 0xb4U, 0xe6U, 0x73U,
822 0x96U, 0xacU, 0x74U, 0x22U,
823 0xe7U, 0xadU, 0x35U, 0x85U,
824 0xe2U, 0xf9U, 0x37U, 0xe8U,
825 0x1cU, 0x75U, 0xdfU, 0x6eU,
826 0x47U, 0xf1U, 0x1aU, 0x71U,
827 0x1dU, 0x29U, 0xc5U, 0x89U,
828 0x6fU, 0xb7U, 0x62U, 0x0eU,
829 0xaaU, 0x18U, 0xbeU, 0x1bU,
830 0xfcU, 0x56U, 0x3eU, 0x4bU,
831 0xc6U, 0xd2U, 0x79U, 0x20U,
832 0x9aU, 0xdbU, 0xc0U, 0xfeU,
833 0x78U, 0xcdU, 0x5aU, 0xf4U,
834 0x1fU, 0xddU, 0xa8U, 0x33U,
835 0x88U, 0x07U, 0xc7U, 0x31U,
836 0xb1U, 0x12U, 0x10U, 0x59U,
837 0x27U, 0x80U, 0xecU, 0x5fU,
838 0x60U, 0x51U, 0x7fU, 0xa9U,
839 0x19U, 0xb5U, 0x4aU, 0x0dU,
840 0x2dU, 0xe5U, 0x7aU, 0x9fU,
841 0x93U, 0xc9U, 0x9cU, 0xefU,
842 0xa0U, 0xe0U, 0x3bU, 0x4dU,
843 0xaeU, 0x2aU, 0xf5U, 0xb0U,
844 0xc8U, 0xebU, 0xbbU, 0x3cU,
845 0x83U, 0x53U, 0x99U, 0x61U,
846 0x17U, 0x2bU, 0x04U, 0x7eU,
847 0xbaU, 0x77U, 0xd6U, 0x26U,
848 0xe1U, 0x69U, 0x14U, 0x63U,
849 0x55U, 0x21U, 0x0cU, 0x7dU,
850 };
851 static const u32 rcon[] = {
852 0x01000000, 0x02000000, 0x04000000, 0x08000000,
853 0x10000000, 0x20000000, 0x40000000, 0x80000000,
854 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
855 };
857 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
859 #ifdef _MSC_VER
860 #define GETU32(p) SWAP(*((u32 *)(p)))
861 #define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
862 #else
863 #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
864 #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
865 #endif
867 /**
868 * Expand the cipher key into the encryption key schedule.
870 * @return the number of rounds for the given cipher key size.
871 */
872 static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
873 int i = 0;
874 u32 temp;
876 rk[0] = GETU32(cipherKey );
877 rk[1] = GETU32(cipherKey + 4);
878 rk[2] = GETU32(cipherKey + 8);
879 rk[3] = GETU32(cipherKey + 12);
880 if (keyBits == 128) {
881 for (;;) {
882 temp = rk[3];
883 rk[4] = rk[0] ^
884 (Te4[(temp >> 16) & 0xff] << 24) ^
885 (Te4[(temp >> 8) & 0xff] << 16) ^
886 (Te4[(temp ) & 0xff] << 8) ^
887 (Te4[(temp >> 24) ] ) ^
888 rcon[i];
889 rk[5] = rk[1] ^ rk[4];
890 rk[6] = rk[2] ^ rk[5];
891 rk[7] = rk[3] ^ rk[6];
892 if (++i == 10) {
893 return 10;
895 rk += 4;
898 rk[4] = GETU32(cipherKey + 16);
899 rk[5] = GETU32(cipherKey + 20);
900 if (keyBits == 192) {
901 for (;;) {
902 temp = rk[ 5];
903 rk[ 6] = rk[ 0] ^
904 (Te4[(temp >> 16) & 0xff] << 24) ^
905 (Te4[(temp >> 8) & 0xff] << 16) ^
906 (Te4[(temp ) & 0xff] << 8) ^
907 (Te4[(temp >> 24) ] ) ^
908 rcon[i];
909 rk[ 7] = rk[ 1] ^ rk[ 6];
910 rk[ 8] = rk[ 2] ^ rk[ 7];
911 rk[ 9] = rk[ 3] ^ rk[ 8];
912 if (++i == 8) {
913 return 12;
915 rk[10] = rk[ 4] ^ rk[ 9];
916 rk[11] = rk[ 5] ^ rk[10];
917 rk += 6;
920 rk[6] = GETU32(cipherKey + 24);
921 rk[7] = GETU32(cipherKey + 28);
922 if (keyBits == 256) {
923 for (;;) {
924 temp = rk[ 7];
925 rk[ 8] = rk[ 0] ^
926 (Te4[(temp >> 16) & 0xff] << 24) ^
927 (Te4[(temp >> 8) & 0xff] << 16) ^
928 (Te4[(temp ) & 0xff] << 8) ^
929 (Te4[(temp >> 24) ] ) ^
930 rcon[i];
931 rk[ 9] = rk[ 1] ^ rk[ 8];
932 rk[10] = rk[ 2] ^ rk[ 9];
933 rk[11] = rk[ 3] ^ rk[10];
934 if (++i == 7) {
935 return 14;
937 temp = rk[11];
938 rk[12] = rk[ 4] ^
939 (Te4[(temp >> 24) ] << 24) ^
940 (Te4[(temp >> 16) & 0xff] << 16) ^
941 (Te4[(temp >> 8) & 0xff] << 8) ^
942 (Te4[(temp ) & 0xff] );
943 rk[13] = rk[ 5] ^ rk[12];
944 rk[14] = rk[ 6] ^ rk[13];
945 rk[15] = rk[ 7] ^ rk[14];
947 rk += 8;
950 return 0;
953 /**
954 * Expand the cipher key into the decryption key schedule.
956 * @return the number of rounds for the given cipher key size.
957 */
958 static int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
959 int Nr, i, j;
960 u32 temp;
962 /* expand the cipher key: */
963 Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
964 /* invert the order of the round keys: */
965 for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
966 temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
967 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
968 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
969 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
971 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
972 for (i = 1; i < Nr; i++) {
973 rk += 4;
974 rk[0] =
975 Td0[Te4[(rk[0] >> 24) ]] ^
976 Td1[Te4[(rk[0] >> 16) & 0xff]] ^
977 Td2[Te4[(rk[0] >> 8) & 0xff]] ^
978 Td3[Te4[(rk[0] ) & 0xff]];
979 rk[1] =
980 Td0[Te4[(rk[1] >> 24) ]] ^
981 Td1[Te4[(rk[1] >> 16) & 0xff]] ^
982 Td2[Te4[(rk[1] >> 8) & 0xff]] ^
983 Td3[Te4[(rk[1] ) & 0xff]];
984 rk[2] =
985 Td0[Te4[(rk[2] >> 24) ]] ^
986 Td1[Te4[(rk[2] >> 16) & 0xff]] ^
987 Td2[Te4[(rk[2] >> 8) & 0xff]] ^
988 Td3[Te4[(rk[2] ) & 0xff]];
989 rk[3] =
990 Td0[Te4[(rk[3] >> 24) ]] ^
991 Td1[Te4[(rk[3] >> 16) & 0xff]] ^
992 Td2[Te4[(rk[3] >> 8) & 0xff]] ^
993 Td3[Te4[(rk[3] ) & 0xff]];
995 return Nr;
998 static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
999 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1000 #ifndef FULL_UNROLL
1001 int r;
1002 #endif /* ?FULL_UNROLL */
1005 * map byte array block to cipher state
1006 * and add initial round key:
1008 s0 = GETU32(pt ) ^ rk[0];
1009 s1 = GETU32(pt + 4) ^ rk[1];
1010 s2 = GETU32(pt + 8) ^ rk[2];
1011 s3 = GETU32(pt + 12) ^ rk[3];
1012 #ifdef FULL_UNROLL
1013 /* round 1: */
1014 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
1015 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
1016 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
1017 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
1018 /* round 2: */
1019 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
1020 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
1021 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
1022 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
1023 /* round 3: */
1024 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
1025 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
1026 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
1027 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
1028 /* round 4: */
1029 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
1030 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
1031 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
1032 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
1033 /* round 5: */
1034 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
1035 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
1036 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
1037 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
1038 /* round 6: */
1039 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
1040 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
1041 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
1042 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
1043 /* round 7: */
1044 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
1045 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
1046 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
1047 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
1048 /* round 8: */
1049 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
1050 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
1051 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
1052 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
1053 /* round 9: */
1054 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
1055 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
1056 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
1057 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
1058 if (Nr > 10) {
1059 /* round 10: */
1060 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
1061 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
1062 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
1063 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
1064 /* round 11: */
1065 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
1066 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
1067 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
1068 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
1069 if (Nr > 12) {
1070 /* round 12: */
1071 s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
1072 s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
1073 s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
1074 s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
1075 /* round 13: */
1076 t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
1077 t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
1078 t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
1079 t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
1082 rk += Nr << 2;
1083 #else /* !FULL_UNROLL */
1085 * Nr - 1 full rounds:
1087 r = Nr >> 1;
1088 for (;;) {
1089 t0 =
1090 Te0[(s0 >> 24) ] ^
1091 Te1[(s1 >> 16) & 0xff] ^
1092 Te2[(s2 >> 8) & 0xff] ^
1093 Te3[(s3 ) & 0xff] ^
1094 rk[4];
1095 t1 =
1096 Te0[(s1 >> 24) ] ^
1097 Te1[(s2 >> 16) & 0xff] ^
1098 Te2[(s3 >> 8) & 0xff] ^
1099 Te3[(s0 ) & 0xff] ^
1100 rk[5];
1101 t2 =
1102 Te0[(s2 >> 24) ] ^
1103 Te1[(s3 >> 16) & 0xff] ^
1104 Te2[(s0 >> 8) & 0xff] ^
1105 Te3[(s1 ) & 0xff] ^
1106 rk[6];
1107 t3 =
1108 Te0[(s3 >> 24) ] ^
1109 Te1[(s0 >> 16) & 0xff] ^
1110 Te2[(s1 >> 8) & 0xff] ^
1111 Te3[(s2 ) & 0xff] ^
1112 rk[7];
1114 rk += 8;
1115 if (--r == 0) {
1116 break;
1119 s0 =
1120 Te0[(t0 >> 24) ] ^
1121 Te1[(t1 >> 16) & 0xff] ^
1122 Te2[(t2 >> 8) & 0xff] ^
1123 Te3[(t3 ) & 0xff] ^
1124 rk[0];
1125 s1 =
1126 Te0[(t1 >> 24) ] ^
1127 Te1[(t2 >> 16) & 0xff] ^
1128 Te2[(t3 >> 8) & 0xff] ^
1129 Te3[(t0 ) & 0xff] ^
1130 rk[1];
1131 s2 =
1132 Te0[(t2 >> 24) ] ^
1133 Te1[(t3 >> 16) & 0xff] ^
1134 Te2[(t0 >> 8) & 0xff] ^
1135 Te3[(t1 ) & 0xff] ^
1136 rk[2];
1137 s3 =
1138 Te0[(t3 >> 24) ] ^
1139 Te1[(t0 >> 16) & 0xff] ^
1140 Te2[(t1 >> 8) & 0xff] ^
1141 Te3[(t2 ) & 0xff] ^
1142 rk[3];
1144 #endif /* ?FULL_UNROLL */
1146 * apply last round and
1147 * map cipher state to byte array block:
1149 s0 =
1150 (Te4[(t0 >> 24) ] << 24) ^
1151 (Te4[(t1 >> 16) & 0xff] << 16) ^
1152 (Te4[(t2 >> 8) & 0xff] << 8) ^
1153 (Te4[(t3 ) & 0xff] ) ^
1154 rk[0];
1155 PUTU32(ct , s0);
1156 s1 =
1157 (Te4[(t1 >> 24) ] << 24) ^
1158 (Te4[(t2 >> 16) & 0xff] << 16) ^
1159 (Te4[(t3 >> 8) & 0xff] << 8) ^
1160 (Te4[(t0 ) & 0xff] ) ^
1161 rk[1];
1162 PUTU32(ct + 4, s1);
1163 s2 =
1164 (Te4[(t2 >> 24) ] << 24) ^
1165 (Te4[(t3 >> 16) & 0xff] << 16) ^
1166 (Te4[(t0 >> 8) & 0xff] << 8) ^
1167 (Te4[(t1 ) & 0xff] ) ^
1168 rk[2];
1169 PUTU32(ct + 8, s2);
1170 s3 =
1171 (Te4[(t3 >> 24) ] << 24) ^
1172 (Te4[(t0 >> 16) & 0xff] << 16) ^
1173 (Te4[(t1 >> 8) & 0xff] << 8) ^
1174 (Te4[(t2 ) & 0xff] ) ^
1175 rk[3];
1176 PUTU32(ct + 12, s3);
1179 static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) {
1180 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1181 #ifndef FULL_UNROLL
1182 int r;
1183 #endif /* ?FULL_UNROLL */
1186 * map byte array block to cipher state
1187 * and add initial round key:
1189 s0 = GETU32(ct ) ^ rk[0];
1190 s1 = GETU32(ct + 4) ^ rk[1];
1191 s2 = GETU32(ct + 8) ^ rk[2];
1192 s3 = GETU32(ct + 12) ^ rk[3];
1193 #ifdef FULL_UNROLL
1194 /* round 1: */
1195 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
1196 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
1197 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
1198 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
1199 /* round 2: */
1200 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
1201 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
1202 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
1203 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
1204 /* round 3: */
1205 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
1206 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
1207 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
1208 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
1209 /* round 4: */
1210 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
1211 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
1212 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
1213 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
1214 /* round 5: */
1215 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
1216 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
1217 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
1218 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
1219 /* round 6: */
1220 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
1221 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
1222 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
1223 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
1224 /* round 7: */
1225 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
1226 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
1227 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
1228 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
1229 /* round 8: */
1230 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
1231 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
1232 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
1233 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
1234 /* round 9: */
1235 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
1236 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
1237 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
1238 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
1239 if (Nr > 10) {
1240 /* round 10: */
1241 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
1242 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
1243 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
1244 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
1245 /* round 11: */
1246 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
1247 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
1248 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
1249 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
1250 if (Nr > 12) {
1251 /* round 12: */
1252 s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
1253 s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
1254 s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
1255 s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
1256 /* round 13: */
1257 t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
1258 t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
1259 t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
1260 t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
1263 rk += Nr << 2;
1264 #else /* !FULL_UNROLL */
1266 * Nr - 1 full rounds:
1268 r = Nr >> 1;
1269 for (;;) {
1270 t0 =
1271 Td0[(s0 >> 24) ] ^
1272 Td1[(s3 >> 16) & 0xff] ^
1273 Td2[(s2 >> 8) & 0xff] ^
1274 Td3[(s1 ) & 0xff] ^
1275 rk[4];
1276 t1 =
1277 Td0[(s1 >> 24) ] ^
1278 Td1[(s0 >> 16) & 0xff] ^
1279 Td2[(s3 >> 8) & 0xff] ^
1280 Td3[(s2 ) & 0xff] ^
1281 rk[5];
1282 t2 =
1283 Td0[(s2 >> 24) ] ^
1284 Td1[(s1 >> 16) & 0xff] ^
1285 Td2[(s0 >> 8) & 0xff] ^
1286 Td3[(s3 ) & 0xff] ^
1287 rk[6];
1288 t3 =
1289 Td0[(s3 >> 24) ] ^
1290 Td1[(s2 >> 16) & 0xff] ^
1291 Td2[(s1 >> 8) & 0xff] ^
1292 Td3[(s0 ) & 0xff] ^
1293 rk[7];
1295 rk += 8;
1296 if (--r == 0) {
1297 break;
1300 s0 =
1301 Td0[(t0 >> 24) ] ^
1302 Td1[(t3 >> 16) & 0xff] ^
1303 Td2[(t2 >> 8) & 0xff] ^
1304 Td3[(t1 ) & 0xff] ^
1305 rk[0];
1306 s1 =
1307 Td0[(t1 >> 24) ] ^
1308 Td1[(t0 >> 16) & 0xff] ^
1309 Td2[(t3 >> 8) & 0xff] ^
1310 Td3[(t2 ) & 0xff] ^
1311 rk[1];
1312 s2 =
1313 Td0[(t2 >> 24) ] ^
1314 Td1[(t1 >> 16) & 0xff] ^
1315 Td2[(t0 >> 8) & 0xff] ^
1316 Td3[(t3 ) & 0xff] ^
1317 rk[2];
1318 s3 =
1319 Td0[(t3 >> 24) ] ^
1320 Td1[(t2 >> 16) & 0xff] ^
1321 Td2[(t1 >> 8) & 0xff] ^
1322 Td3[(t0 ) & 0xff] ^
1323 rk[3];
1325 #endif /* ?FULL_UNROLL */
1327 * apply last round and
1328 * map cipher state to byte array block:
1330 s0 =
1331 (Td4[(t0 >> 24) ] << 24) ^
1332 (Td4[(t3 >> 16) & 0xff] << 16) ^
1333 (Td4[(t2 >> 8) & 0xff] << 8) ^
1334 (Td4[(t1 ) & 0xff] ) ^
1335 rk[0];
1336 PUTU32(pt , s0);
1337 s1 =
1338 (Td4[(t1 >> 24) ] << 24) ^
1339 (Td4[(t0 >> 16) & 0xff] << 16) ^
1340 (Td4[(t3 >> 8) & 0xff] << 8) ^
1341 (Td4[(t2 ) & 0xff] ) ^
1342 rk[1];
1343 PUTU32(pt + 4, s1);
1344 s2 =
1345 (Td4[(t2 >> 24) ] << 24) ^
1346 (Td4[(t1 >> 16) & 0xff] << 16) ^
1347 (Td4[(t0 >> 8) & 0xff] << 8) ^
1348 (Td4[(t3 ) & 0xff] ) ^
1349 rk[2];
1350 PUTU32(pt + 8, s2);
1351 s3 =
1352 (Td4[(t3 >> 24) ] << 24) ^
1353 (Td4[(t2 >> 16) & 0xff] << 16) ^
1354 (Td4[(t1 >> 8) & 0xff] << 8) ^
1355 (Td4[(t0 ) & 0xff] ) ^
1356 rk[3];
1357 PUTU32(pt + 12, s3);
1360 #ifdef INTERMEDIATE_VALUE_KAT
1362 static void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
1363 int r;
1364 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1367 * map byte array block to cipher state
1368 * and add initial round key:
1370 s0 = GETU32(block ) ^ rk[0];
1371 s1 = GETU32(block + 4) ^ rk[1];
1372 s2 = GETU32(block + 8) ^ rk[2];
1373 s3 = GETU32(block + 12) ^ rk[3];
1374 rk += 4;
1377 * Nr - 1 full rounds:
1379 for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) {
1380 t0 =
1381 Te0[(s0 >> 24) ] ^
1382 Te1[(s1 >> 16) & 0xff] ^
1383 Te2[(s2 >> 8) & 0xff] ^
1384 Te3[(s3 ) & 0xff] ^
1385 rk[0];
1386 t1 =
1387 Te0[(s1 >> 24) ] ^
1388 Te1[(s2 >> 16) & 0xff] ^
1389 Te2[(s3 >> 8) & 0xff] ^
1390 Te3[(s0 ) & 0xff] ^
1391 rk[1];
1392 t2 =
1393 Te0[(s2 >> 24) ] ^
1394 Te1[(s3 >> 16) & 0xff] ^
1395 Te2[(s0 >> 8) & 0xff] ^
1396 Te3[(s1 ) & 0xff] ^
1397 rk[2];
1398 t3 =
1399 Te0[(s3 >> 24) ] ^
1400 Te1[(s0 >> 16) & 0xff] ^
1401 Te2[(s1 >> 8) & 0xff] ^
1402 Te3[(s2 ) & 0xff] ^
1403 rk[3];
1405 s0 = t0;
1406 s1 = t1;
1407 s2 = t2;
1408 s3 = t3;
1409 rk += 4;
1414 * apply last round and
1415 * map cipher state to byte array block:
1417 if (rounds == Nr) {
1418 t0 =
1419 (Te4[(s0 >> 24) ] << 24) ^
1420 (Te4[(s1 >> 16) & 0xff] << 16) ^
1421 (Te4[(s2 >> 8) & 0xff] << 8) ^
1422 (Te4[(s3 ) & 0xff] ) ^
1423 rk[0];
1424 t1 =
1425 (Te4[(s1 >> 24) ] << 24) ^
1426 (Te4[(s2 >> 16) & 0xff] << 16) ^
1427 (Te4[(s3 >> 8) & 0xff] << 8) ^
1428 (Te4[(s0 ) & 0xff] ) ^
1429 rk[1];
1430 t2 =
1431 (Te4[(s2 >> 24) ] << 24) ^
1432 (Te4[(s3 >> 16) & 0xff] << 16) ^
1433 (Te4[(s0 >> 8) & 0xff] << 8) ^
1434 (Te4[(s1 ) & 0xff] ) ^
1435 rk[2];
1436 t3 =
1437 (Te4[(s3 >> 24) ] << 24) ^
1438 (Te4[(s0 >> 16) & 0xff] << 16) ^
1439 (Te4[(s1 >> 8) & 0xff] << 8) ^
1440 (Te4[(s2 ) & 0xff] ) ^
1441 rk[3];
1443 s0 = t0;
1444 s1 = t1;
1445 s2 = t2;
1446 s3 = t3;
1449 PUTU32(block , s0);
1450 PUTU32(block + 4, s1);
1451 PUTU32(block + 8, s2);
1452 PUTU32(block + 12, s3);
1455 static void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
1456 int r;
1457 u32 s0, s1, s2, s3, t0, t1, t2, t3;
1460 * map byte array block to cipher state
1461 * and add initial round key:
1463 s0 = GETU32(block ) ^ rk[0];
1464 s1 = GETU32(block + 4) ^ rk[1];
1465 s2 = GETU32(block + 8) ^ rk[2];
1466 s3 = GETU32(block + 12) ^ rk[3];
1467 rk += 4;
1470 * Nr - 1 full rounds:
1472 for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) {
1473 t0 =
1474 Td0[(s0 >> 24) ] ^
1475 Td1[(s3 >> 16) & 0xff] ^
1476 Td2[(s2 >> 8) & 0xff] ^
1477 Td3[(s1 ) & 0xff] ^
1478 rk[0];
1479 t1 =
1480 Td0[(s1 >> 24) ] ^
1481 Td1[(s0 >> 16) & 0xff] ^
1482 Td2[(s3 >> 8) & 0xff] ^
1483 Td3[(s2 ) & 0xff] ^
1484 rk[1];
1485 t2 =
1486 Td0[(s2 >> 24) ] ^
1487 Td1[(s1 >> 16) & 0xff] ^
1488 Td2[(s0 >> 8) & 0xff] ^
1489 Td3[(s3 ) & 0xff] ^
1490 rk[2];
1491 t3 =
1492 Td0[(s3 >> 24) ] ^
1493 Td1[(s2 >> 16) & 0xff] ^
1494 Td2[(s1 >> 8) & 0xff] ^
1495 Td3[(s0 ) & 0xff] ^
1496 rk[3];
1498 s0 = t0;
1499 s1 = t1;
1500 s2 = t2;
1501 s3 = t3;
1502 rk += 4;
1507 * complete the last round and
1508 * map cipher state to byte array block:
1510 t0 =
1511 (Td4[(s0 >> 24) ] << 24) ^
1512 (Td4[(s3 >> 16) & 0xff] << 16) ^
1513 (Td4[(s2 >> 8) & 0xff] << 8) ^
1514 (Td4[(s1 ) & 0xff] );
1515 t1 =
1516 (Td4[(s1 >> 24) ] << 24) ^
1517 (Td4[(s0 >> 16) & 0xff] << 16) ^
1518 (Td4[(s3 >> 8) & 0xff] << 8) ^
1519 (Td4[(s2 ) & 0xff] );
1520 t2 =
1521 (Td4[(s2 >> 24) ] << 24) ^
1522 (Td4[(s1 >> 16) & 0xff] << 16) ^
1523 (Td4[(s0 >> 8) & 0xff] << 8) ^
1524 (Td4[(s3 ) & 0xff] );
1525 t3 =
1526 (Td4[(s3 >> 24) ] << 24) ^
1527 (Td4[(s2 >> 16) & 0xff] << 16) ^
1528 (Td4[(s1 >> 8) & 0xff] << 8) ^
1529 (Td4[(s0 ) & 0xff] );
1531 if (rounds == Nr) {
1532 t0 ^= rk[0];
1533 t1 ^= rk[1];
1534 t2 ^= rk[2];
1535 t3 ^= rk[3];
1538 PUTU32(block , t0);
1539 PUTU32(block + 4, t1);
1540 PUTU32(block + 8, t2);
1541 PUTU32(block + 12, t3);
1544 #endif /* INTERMEDIATE_VALUE_KAT */