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