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