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