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