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