xref: /plan9-contrib/sys/src/libsec/port/aes.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
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>
34 
35 typedef uchar	u8;
36 typedef u32int	u32;
37 #define FULL_UNROLL
38 
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];
44 
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]);
50 
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 }
66 
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];
75 
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 	}
86 
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 }
95 
96 void
97 aesCBCdecrypt(uchar *p, int len, AESstate *s)
98 {
99 	uchar *ip, *eip, *tp;
100 	uchar tmp[AESbsize], q[AESbsize];
101 
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++;
111 		}
112 	}
113 
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++;
120 	}
121 }
122 
123 /*
124  * this function has been changed for plan 9.
125  * Expand the cipher key into the encryption and decryption key schedules.
126  *
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;
131 
132 	/* expand the cipher key: */
133 	Nr = rijndaelKeySetupEnc(erk, cipherKey, keyBits);
134 
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]];
171 	}
172 	return Nr;
173 }
174 
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]
181 
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 */
188 
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] = {
388 
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,
673 
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 };
856 
857 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
858 
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
866 
867 /**
868  * Expand the cipher key into the encryption key schedule.
869  *
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;
875 
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;
894 			}
895 			rk += 4;
896 		}
897 	}
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;
914 			}
915 			rk[10] = rk[ 4] ^ rk[ 9];
916 			rk[11] = rk[ 5] ^ rk[10];
917 			rk += 6;
918 		}
919 	}
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;
936 			}
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];
946 
947 			rk += 8;
948         }
949 	}
950 	return 0;
951 }
952 
953 /**
954  * Expand the cipher key into the decryption key schedule.
955  *
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;
961 
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;
970 	}
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]];
994 	}
995 	return Nr;
996 }
997 
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 */
1003 
1004     /*
1005 	 * map byte array block to cipher state
1006 	 * and add initial round key:
1007 	 */
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];
1080         }
1081     }
1082     rk += Nr << 2;
1083 #else  /* !FULL_UNROLL */
1084     /*
1085 	 * Nr - 1 full rounds:
1086 	 */
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];
1113 
1114         rk += 8;
1115         if (--r == 0) {
1116             break;
1117         }
1118 
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];
1143     }
1144 #endif /* ?FULL_UNROLL */
1145     /*
1146 	 * apply last round and
1147 	 * map cipher state to byte array block:
1148 	 */
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);
1177 }
1178 
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 */
1184 
1185     /*
1186 	 * map byte array block to cipher state
1187 	 * and add initial round key:
1188 	 */
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];
1261         }
1262     }
1263 	rk += Nr << 2;
1264 #else  /* !FULL_UNROLL */
1265     /*
1266      * Nr - 1 full rounds:
1267      */
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];
1294 
1295         rk += 8;
1296         if (--r == 0) {
1297             break;
1298         }
1299 
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];
1324     }
1325 #endif /* ?FULL_UNROLL */
1326     /*
1327 	 * apply last round and
1328 	 * map cipher state to byte array block:
1329 	 */
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);
1358 }
1359 
1360 #ifdef INTERMEDIATE_VALUE_KAT
1361 
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;
1365 
1366     /*
1367 	 * map byte array block to cipher state
1368 	 * and add initial round key:
1369 	 */
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;
1375 
1376     /*
1377 	 * Nr - 1 full rounds:
1378 	 */
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];
1404 
1405 		s0 = t0;
1406 		s1 = t1;
1407 		s2 = t2;
1408 		s3 = t3;
1409 		rk += 4;
1410 
1411     }
1412 
1413     /*
1414 	 * apply last round and
1415 	 * map cipher state to byte array block:
1416 	 */
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];
1442 
1443 		s0 = t0;
1444 		s1 = t1;
1445 		s2 = t2;
1446 		s3 = t3;
1447 	}
1448 
1449 	PUTU32(block     , s0);
1450 	PUTU32(block +  4, s1);
1451 	PUTU32(block +  8, s2);
1452 	PUTU32(block + 12, s3);
1453 }
1454 
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;
1458 
1459     /*
1460 	 * map byte array block to cipher state
1461 	 * and add initial round key:
1462 	 */
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;
1468 
1469     /*
1470 	 * Nr - 1 full rounds:
1471 	 */
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];
1497 
1498 		s0 = t0;
1499 		s1 = t1;
1500 		s2 = t2;
1501 		s3 = t3;
1502 		rk += 4;
1503 
1504     }
1505 
1506     /*
1507 	 * complete the last round and
1508 	 * map cipher state to byte array block:
1509 	 */
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]      );
1530 
1531 	if (rounds == Nr) {
1532 	    t0 ^= rk[0];
1533 	    t1 ^= rk[1];
1534 	    t2 ^= rk[2];
1535 	    t3 ^= rk[3];
1536 	}
1537 
1538 	PUTU32(block     , t0);
1539 	PUTU32(block +  4, t1);
1540 	PUTU32(block +  8, t2);
1541 	PUTU32(block + 12, t3);
1542 }
1543 
1544 #endif /* INTERMEDIATE_VALUE_KAT */
1545