1 /*
2  * aes.c
3  *
4  * An implemnetation of the AES block cipher.
5  *
6  * David A. McGrew
7  * Cisco Systems, Inc.
8  */
9 
10 /*
11  *
12  * Copyright (c) 2001-2017, Cisco Systems, Inc.
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  *
19  *   Redistributions of source code must retain the above copyright
20  *   notice, this list of conditions and the following disclaimer.
21  *
22  *   Redistributions in binary form must reproduce the above
23  *   copyright notice, this list of conditions and the following
24  *   disclaimer in the documentation and/or other materials provided
25  *   with the distribution.
26  *
27  *   Neither the name of the Cisco Systems, Inc. nor the names of its
28  *   contributors may be used to endorse or promote products derived
29  *   from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42  * OF THE POSSIBILITY OF SUCH DAMAGE.
43  *
44  */
45 
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49 
50 #include "aes.h"
51 #include "err.h"
52 
53 /*
54  * we use the tables T0, T1, T2, T3, and T4 to compute AES, and
55  * the tables U0, U1, U2, and U4 to compute its inverse
56  *
57  * different tables are used on little-endian (Intel, VMS) and
58  * big-endian processors (everything else)
59  *
60  * these tables are computed using the program tables/aes_tables; use
61  * this program to generate different tables for porting or
62  * optimization on a different platform
63  */
64 
65 #ifndef WORDS_BIGENDIAN
66 /* clang-format off */
67 static const uint32_t T0[256] = {
68     0xa56363c6, 0x847c7cf8,  0x997777ee,  0x8d7b7bf6,
69     0xdf2f2ff,  0xbd6b6bd6,  0xb16f6fde,  0x54c5c591,
70     0x50303060, 0x3010102,   0xa96767ce,  0x7d2b2b56,
71     0x19fefee7, 0x62d7d7b5,  0xe6abab4d,  0x9a7676ec,
72     0x45caca8f, 0x9d82821f,  0x40c9c989,  0x877d7dfa,
73     0x15fafaef, 0xeb5959b2,  0xc947478e,  0xbf0f0fb,
74     0xecadad41, 0x67d4d4b3,  0xfda2a25f,  0xeaafaf45,
75     0xbf9c9c23, 0xf7a4a453,  0x967272e4,  0x5bc0c09b,
76     0xc2b7b775, 0x1cfdfde1,  0xae93933d,  0x6a26264c,
77     0x5a36366c, 0x413f3f7e,  0x2f7f7f5,   0x4fcccc83,
78     0x5c343468, 0xf4a5a551,  0x34e5e5d1,  0x8f1f1f9,
79     0x937171e2, 0x73d8d8ab,  0x53313162,  0x3f15152a,
80     0xc040408,  0x52c7c795,  0x65232346,  0x5ec3c39d,
81     0x28181830, 0xa1969637,  0xf05050a,   0xb59a9a2f,
82     0x907070e,  0x36121224,  0x9b80801b,  0x3de2e2df,
83     0x26ebebcd, 0x6927274e,  0xcdb2b27f,  0x9f7575ea,
84     0x1b090912, 0x9e83831d,  0x742c2c58,  0x2e1a1a34,
85     0x2d1b1b36, 0xb26e6edc,  0xee5a5ab4,  0xfba0a05b,
86     0xf65252a4, 0x4d3b3b76,  0x61d6d6b7,  0xceb3b37d,
87     0x7b292952, 0x3ee3e3dd,  0x712f2f5e,  0x97848413,
88     0xf55353a6, 0x68d1d1b9,  0x0,         0x2cededc1,
89     0x60202040, 0x1ffcfce3,  0xc8b1b179,  0xed5b5bb6,
90     0xbe6a6ad4, 0x46cbcb8d,  0xd9bebe67,  0x4b393972,
91     0xde4a4a94, 0xd44c4c98,  0xe85858b0,  0x4acfcf85,
92     0x6bd0d0bb, 0x2aefefc5,  0xe5aaaa4f,  0x16fbfbed,
93     0xc5434386, 0xd74d4d9a,  0x55333366,  0x94858511,
94     0xcf45458a, 0x10f9f9e9,  0x6020204,   0x817f7ffe,
95     0xf05050a0, 0x443c3c78,  0xba9f9f25,  0xe3a8a84b,
96     0xf35151a2, 0xfea3a35d,  0xc0404080,  0x8a8f8f05,
97     0xad92923f, 0xbc9d9d21,  0x48383870,  0x4f5f5f1,
98     0xdfbcbc63, 0xc1b6b677,  0x75dadaaf,  0x63212142,
99     0x30101020, 0x1affffe5,  0xef3f3fd,   0x6dd2d2bf,
100     0x4ccdcd81, 0x140c0c18,  0x35131326,  0x2fececc3,
101     0xe15f5fbe, 0xa2979735,  0xcc444488,  0x3917172e,
102     0x57c4c493, 0xf2a7a755,  0x827e7efc,  0x473d3d7a,
103     0xac6464c8, 0xe75d5dba,  0x2b191932,  0x957373e6,
104     0xa06060c0, 0x98818119,  0xd14f4f9e,  0x7fdcdca3,
105     0x66222244, 0x7e2a2a54,  0xab90903b,  0x8388880b,
106     0xca46468c, 0x29eeeec7,  0xd3b8b86b,  0x3c141428,
107     0x79dedea7, 0xe25e5ebc,  0x1d0b0b16,  0x76dbdbad,
108     0x3be0e0db, 0x56323264,  0x4e3a3a74,  0x1e0a0a14,
109     0xdb494992, 0xa06060c,   0x6c242448,  0xe45c5cb8,
110     0x5dc2c29f, 0x6ed3d3bd,  0xefacac43,  0xa66262c4,
111     0xa8919139, 0xa4959531,  0x37e4e4d3,  0x8b7979f2,
112     0x32e7e7d5, 0x43c8c88b,  0x5937376e,  0xb76d6dda,
113     0x8c8d8d01, 0x64d5d5b1,  0xd24e4e9c,  0xe0a9a949,
114     0xb46c6cd8, 0xfa5656ac,  0x7f4f4f3,   0x25eaeacf,
115     0xaf6565ca, 0x8e7a7af4,  0xe9aeae47,  0x18080810,
116     0xd5baba6f, 0x887878f0,  0x6f25254a,  0x722e2e5c,
117     0x241c1c38, 0xf1a6a657,  0xc7b4b473,  0x51c6c697,
118     0x23e8e8cb, 0x7cdddda1,  0x9c7474e8,  0x211f1f3e,
119     0xdd4b4b96, 0xdcbdbd61,  0x868b8b0d,  0x858a8a0f,
120     0x907070e0, 0x423e3e7c,  0xc4b5b571,  0xaa6666cc,
121     0xd8484890, 0x5030306,   0x1f6f6f7,   0x120e0e1c,
122     0xa36161c2, 0x5f35356a,  0xf95757ae,  0xd0b9b969,
123     0x91868617, 0x58c1c199,  0x271d1d3a,  0xb99e9e27,
124     0x38e1e1d9, 0x13f8f8eb,  0xb398982b,  0x33111122,
125     0xbb6969d2, 0x70d9d9a9,  0x898e8e07,  0xa7949433,
126     0xb69b9b2d, 0x221e1e3c,  0x92878715,  0x20e9e9c9,
127     0x49cece87, 0xff5555aa,  0x78282850,  0x7adfdfa5,
128     0x8f8c8c03, 0xf8a1a159,  0x80898909,  0x170d0d1a,
129     0xdabfbf65, 0x31e6e6d7,  0xc6424284,  0xb86868d0,
130     0xc3414182, 0xb0999929,  0x772d2d5a,  0x110f0f1e,
131     0xcbb0b07b, 0xfc5454a8,  0xd6bbbb6d,  0x3a16162c,
132 };
133 /* clang-format on */
134 
135 /* clang-format off */
136 static const uint32_t T1[256] = {
137     0x6363c6a5, 0x7c7cf884,  0x7777ee99,  0x7b7bf68d,
138     0xf2f2ff0d, 0x6b6bd6bd,  0x6f6fdeb1,  0xc5c59154,
139     0x30306050, 0x1010203,   0x6767cea9,  0x2b2b567d,
140     0xfefee719, 0xd7d7b562,  0xabab4de6,  0x7676ec9a,
141     0xcaca8f45, 0x82821f9d,  0xc9c98940,  0x7d7dfa87,
142     0xfafaef15, 0x5959b2eb,  0x47478ec9,  0xf0f0fb0b,
143     0xadad41ec, 0xd4d4b367,  0xa2a25ffd,  0xafaf45ea,
144     0x9c9c23bf, 0xa4a453f7,  0x7272e496,  0xc0c09b5b,
145     0xb7b775c2, 0xfdfde11c,  0x93933dae,  0x26264c6a,
146     0x36366c5a, 0x3f3f7e41,  0xf7f7f502,  0xcccc834f,
147     0x3434685c, 0xa5a551f4,  0xe5e5d134,  0xf1f1f908,
148     0x7171e293, 0xd8d8ab73,  0x31316253,  0x15152a3f,
149     0x404080c,  0xc7c79552,  0x23234665,  0xc3c39d5e,
150     0x18183028, 0x969637a1,  0x5050a0f,   0x9a9a2fb5,
151     0x7070e09,  0x12122436,  0x80801b9b,  0xe2e2df3d,
152     0xebebcd26, 0x27274e69,  0xb2b27fcd,  0x7575ea9f,
153     0x909121b,  0x83831d9e,  0x2c2c5874,  0x1a1a342e,
154     0x1b1b362d, 0x6e6edcb2,  0x5a5ab4ee,  0xa0a05bfb,
155     0x5252a4f6, 0x3b3b764d,  0xd6d6b761,  0xb3b37dce,
156     0x2929527b, 0xe3e3dd3e,  0x2f2f5e71,  0x84841397,
157     0x5353a6f5, 0xd1d1b968,  0x00000000,  0xededc12c,
158     0x20204060, 0xfcfce31f,  0xb1b179c8,  0x5b5bb6ed,
159     0x6a6ad4be, 0xcbcb8d46,  0xbebe67d9,  0x3939724b,
160     0x4a4a94de, 0x4c4c98d4,  0x5858b0e8,  0xcfcf854a,
161     0xd0d0bb6b, 0xefefc52a,  0xaaaa4fe5,  0xfbfbed16,
162     0x434386c5, 0x4d4d9ad7,  0x33336655,  0x85851194,
163     0x45458acf, 0xf9f9e910,  0x2020406,   0x7f7ffe81,
164     0x5050a0f0, 0x3c3c7844,  0x9f9f25ba,  0xa8a84be3,
165     0x5151a2f3, 0xa3a35dfe,  0x404080c0,  0x8f8f058a,
166     0x92923fad, 0x9d9d21bc,  0x38387048,  0xf5f5f104,
167     0xbcbc63df, 0xb6b677c1,  0xdadaaf75,  0x21214263,
168     0x10102030, 0xffffe51a,  0xf3f3fd0e,  0xd2d2bf6d,
169     0xcdcd814c, 0xc0c1814,   0x13132635,  0xececc32f,
170     0x5f5fbee1, 0x979735a2,  0x444488cc,  0x17172e39,
171     0xc4c49357, 0xa7a755f2,  0x7e7efc82,  0x3d3d7a47,
172     0x6464c8ac, 0x5d5dbae7,  0x1919322b,  0x7373e695,
173     0x6060c0a0, 0x81811998,  0x4f4f9ed1,  0xdcdca37f,
174     0x22224466, 0x2a2a547e,  0x90903bab,  0x88880b83,
175     0x46468cca, 0xeeeec729,  0xb8b86bd3,  0x1414283c,
176     0xdedea779, 0x5e5ebce2,  0xb0b161d,   0xdbdbad76,
177     0xe0e0db3b, 0x32326456,  0x3a3a744e,  0xa0a141e,
178     0x494992db, 0x6060c0a,   0x2424486c,  0x5c5cb8e4,
179     0xc2c29f5d, 0xd3d3bd6e,  0xacac43ef,  0x6262c4a6,
180     0x919139a8, 0x959531a4,  0xe4e4d337,  0x7979f28b,
181     0xe7e7d532, 0xc8c88b43,  0x37376e59,  0x6d6ddab7,
182     0x8d8d018c, 0xd5d5b164,  0x4e4e9cd2,  0xa9a949e0,
183     0x6c6cd8b4, 0x5656acfa,  0xf4f4f307,  0xeaeacf25,
184     0x6565caaf, 0x7a7af48e,  0xaeae47e9,  0x8081018,
185     0xbaba6fd5, 0x7878f088,  0x25254a6f,  0x2e2e5c72,
186     0x1c1c3824, 0xa6a657f1,  0xb4b473c7,  0xc6c69751,
187     0xe8e8cb23, 0xdddda17c,  0x7474e89c,  0x1f1f3e21,
188     0x4b4b96dd, 0xbdbd61dc,  0x8b8b0d86,  0x8a8a0f85,
189     0x7070e090, 0x3e3e7c42,  0xb5b571c4,  0x6666ccaa,
190     0x484890d8, 0x3030605,   0xf6f6f701,  0xe0e1c12,
191     0x6161c2a3, 0x35356a5f,  0x5757aef9,  0xb9b969d0,
192     0x86861791, 0xc1c19958,  0x1d1d3a27,  0x9e9e27b9,
193     0xe1e1d938, 0xf8f8eb13,  0x98982bb3,  0x11112233,
194     0x6969d2bb, 0xd9d9a970,  0x8e8e0789,  0x949433a7,
195     0x9b9b2db6, 0x1e1e3c22,  0x87871592,  0xe9e9c920,
196     0xcece8749, 0x5555aaff,  0x28285078,  0xdfdfa57a,
197     0x8c8c038f, 0xa1a159f8,  0x89890980,  0xd0d1a17,
198     0xbfbf65da, 0xe6e6d731,  0x424284c6,  0x6868d0b8,
199     0x414182c3, 0x999929b0,  0x2d2d5a77,  0xf0f1e11,
200     0xb0b07bcb, 0x5454a8fc,  0xbbbb6dd6,  0x16162c3a,
201 };
202 /* clang-format on */
203 
204 /* clang-format off */
205 static const uint32_t T2[256] = {
206     0x63c6a563, 0x7cf8847c,  0x77ee9977,  0x7bf68d7b,
207     0xf2ff0df2, 0x6bd6bd6b,  0x6fdeb16f,  0xc59154c5,
208     0x30605030, 0x1020301,   0x67cea967,  0x2b567d2b,
209     0xfee719fe, 0xd7b562d7,  0xab4de6ab,  0x76ec9a76,
210     0xca8f45ca, 0x821f9d82,  0xc98940c9,  0x7dfa877d,
211     0xfaef15fa, 0x59b2eb59,  0x478ec947,  0xf0fb0bf0,
212     0xad41ecad, 0xd4b367d4,  0xa25ffda2,  0xaf45eaaf,
213     0x9c23bf9c, 0xa453f7a4,  0x72e49672,  0xc09b5bc0,
214     0xb775c2b7, 0xfde11cfd,  0x933dae93,  0x264c6a26,
215     0x366c5a36, 0x3f7e413f,  0xf7f502f7,  0xcc834fcc,
216     0x34685c34, 0xa551f4a5,  0xe5d134e5,  0xf1f908f1,
217     0x71e29371, 0xd8ab73d8,  0x31625331,  0x152a3f15,
218     0x4080c04,  0xc79552c7,  0x23466523,  0xc39d5ec3,
219     0x18302818, 0x9637a196,  0x50a0f05,   0x9a2fb59a,
220     0x70e0907,  0x12243612,  0x801b9b80,  0xe2df3de2,
221     0xebcd26eb, 0x274e6927,  0xb27fcdb2,  0x75ea9f75,
222     0x9121b09,  0x831d9e83,  0x2c58742c,  0x1a342e1a,
223     0x1b362d1b, 0x6edcb26e,  0x5ab4ee5a,  0xa05bfba0,
224     0x52a4f652, 0x3b764d3b,  0xd6b761d6,  0xb37dceb3,
225     0x29527b29, 0xe3dd3ee3,  0x2f5e712f,  0x84139784,
226     0x53a6f553, 0xd1b968d1,  0x0,         0xedc12ced,
227     0x20406020, 0xfce31ffc,  0xb179c8b1,  0x5bb6ed5b,
228     0x6ad4be6a, 0xcb8d46cb,  0xbe67d9be,  0x39724b39,
229     0x4a94de4a, 0x4c98d44c,  0x58b0e858,  0xcf854acf,
230     0xd0bb6bd0, 0xefc52aef,  0xaa4fe5aa,  0xfbed16fb,
231     0x4386c543, 0x4d9ad74d,  0x33665533,  0x85119485,
232     0x458acf45, 0xf9e910f9,  0x2040602,   0x7ffe817f,
233     0x50a0f050, 0x3c78443c,  0x9f25ba9f,  0xa84be3a8,
234     0x51a2f351, 0xa35dfea3,  0x4080c040,  0x8f058a8f,
235     0x923fad92, 0x9d21bc9d,  0x38704838,  0xf5f104f5,
236     0xbc63dfbc, 0xb677c1b6,  0xdaaf75da,  0x21426321,
237     0x10203010, 0xffe51aff,  0xf3fd0ef3,  0xd2bf6dd2,
238     0xcd814ccd, 0xc18140c,   0x13263513,  0xecc32fec,
239     0x5fbee15f, 0x9735a297,  0x4488cc44,  0x172e3917,
240     0xc49357c4, 0xa755f2a7,  0x7efc827e,  0x3d7a473d,
241     0x64c8ac64, 0x5dbae75d,  0x19322b19,  0x73e69573,
242     0x60c0a060, 0x81199881,  0x4f9ed14f,  0xdca37fdc,
243     0x22446622, 0x2a547e2a,  0x903bab90,  0x880b8388,
244     0x468cca46, 0xeec729ee,  0xb86bd3b8,  0x14283c14,
245     0xdea779de, 0x5ebce25e,  0xb161d0b,   0xdbad76db,
246     0xe0db3be0, 0x32645632,  0x3a744e3a,  0xa141e0a,
247     0x4992db49, 0x60c0a06,   0x24486c24,  0x5cb8e45c,
248     0xc29f5dc2, 0xd3bd6ed3,  0xac43efac,  0x62c4a662,
249     0x9139a891, 0x9531a495,  0xe4d337e4,  0x79f28b79,
250     0xe7d532e7, 0xc88b43c8,  0x376e5937,  0x6ddab76d,
251     0x8d018c8d, 0xd5b164d5,  0x4e9cd24e,  0xa949e0a9,
252     0x6cd8b46c, 0x56acfa56,  0xf4f307f4,  0xeacf25ea,
253     0x65caaf65, 0x7af48e7a,  0xae47e9ae,  0x8101808,
254     0xba6fd5ba, 0x78f08878,  0x254a6f25,  0x2e5c722e,
255     0x1c38241c, 0xa657f1a6,  0xb473c7b4,  0xc69751c6,
256     0xe8cb23e8, 0xdda17cdd,  0x74e89c74,  0x1f3e211f,
257     0x4b96dd4b, 0xbd61dcbd,  0x8b0d868b,  0x8a0f858a,
258     0x70e09070, 0x3e7c423e,  0xb571c4b5,  0x66ccaa66,
259     0x4890d848, 0x3060503,   0xf6f701f6,  0xe1c120e,
260     0x61c2a361, 0x356a5f35,  0x57aef957,  0xb969d0b9,
261     0x86179186, 0xc19958c1,  0x1d3a271d,  0x9e27b99e,
262     0xe1d938e1, 0xf8eb13f8,  0x982bb398,  0x11223311,
263     0x69d2bb69, 0xd9a970d9,  0x8e07898e,  0x9433a794,
264     0x9b2db69b, 0x1e3c221e,  0x87159287,  0xe9c920e9,
265     0xce8749ce, 0x55aaff55,  0x28507828,  0xdfa57adf,
266     0x8c038f8c, 0xa159f8a1,  0x89098089,  0xd1a170d,
267     0xbf65dabf, 0xe6d731e6,  0x4284c642,  0x68d0b868,
268     0x4182c341, 0x9929b099,  0x2d5a772d,  0xf1e110f,
269     0xb07bcbb0, 0x54a8fc54,  0xbb6dd6bb,  0x162c3a16,
270 };
271 /* clang-format on */
272 
273 /* clang-format off */
274 static const uint32_t T3[256] = {
275     0xc6a56363, 0xf8847c7c,  0xee997777,  0xf68d7b7b,
276     0xff0df2f2, 0xd6bd6b6b,  0xdeb16f6f,  0x9154c5c5,
277     0x60503030, 0x2030101,   0xcea96767,  0x567d2b2b,
278     0xe719fefe, 0xb562d7d7,  0x4de6abab,  0xec9a7676,
279     0x8f45caca, 0x1f9d8282,  0x8940c9c9,  0xfa877d7d,
280     0xef15fafa, 0xb2eb5959,  0x8ec94747,  0xfb0bf0f0,
281     0x41ecadad, 0xb367d4d4,  0x5ffda2a2,  0x45eaafaf,
282     0x23bf9c9c, 0x53f7a4a4,  0xe4967272,  0x9b5bc0c0,
283     0x75c2b7b7, 0xe11cfdfd,  0x3dae9393,  0x4c6a2626,
284     0x6c5a3636, 0x7e413f3f,  0xf502f7f7,  0x834fcccc,
285     0x685c3434, 0x51f4a5a5,  0xd134e5e5,  0xf908f1f1,
286     0xe2937171, 0xab73d8d8,  0x62533131,  0x2a3f1515,
287     0x80c0404,  0x9552c7c7,  0x46652323,  0x9d5ec3c3,
288     0x30281818, 0x37a19696,  0xa0f0505,   0x2fb59a9a,
289     0xe090707,  0x24361212,  0x1b9b8080,  0xdf3de2e2,
290     0xcd26ebeb, 0x4e692727,  0x7fcdb2b2,  0xea9f7575,
291     0x121b0909, 0x1d9e8383,  0x58742c2c,  0x342e1a1a,
292     0x362d1b1b, 0xdcb26e6e,  0xb4ee5a5a,  0x5bfba0a0,
293     0xa4f65252, 0x764d3b3b,  0xb761d6d6,  0x7dceb3b3,
294     0x527b2929, 0xdd3ee3e3,  0x5e712f2f,  0x13978484,
295     0xa6f55353, 0xb968d1d1,  0x0,         0xc12ceded,
296     0x40602020, 0xe31ffcfc,  0x79c8b1b1,  0xb6ed5b5b,
297     0xd4be6a6a, 0x8d46cbcb,  0x67d9bebe,  0x724b3939,
298     0x94de4a4a, 0x98d44c4c,  0xb0e85858,  0x854acfcf,
299     0xbb6bd0d0, 0xc52aefef,  0x4fe5aaaa,  0xed16fbfb,
300     0x86c54343, 0x9ad74d4d,  0x66553333,  0x11948585,
301     0x8acf4545, 0xe910f9f9,  0x4060202,   0xfe817f7f,
302     0xa0f05050, 0x78443c3c,  0x25ba9f9f,  0x4be3a8a8,
303     0xa2f35151, 0x5dfea3a3,  0x80c04040,  0x58a8f8f,
304     0x3fad9292, 0x21bc9d9d,  0x70483838,  0xf104f5f5,
305     0x63dfbcbc, 0x77c1b6b6,  0xaf75dada,  0x42632121,
306     0x20301010, 0xe51affff,  0xfd0ef3f3,  0xbf6dd2d2,
307     0x814ccdcd, 0x18140c0c,  0x26351313,  0xc32fecec,
308     0xbee15f5f, 0x35a29797,  0x88cc4444,  0x2e391717,
309     0x9357c4c4, 0x55f2a7a7,  0xfc827e7e,  0x7a473d3d,
310     0xc8ac6464, 0xbae75d5d,  0x322b1919,  0xe6957373,
311     0xc0a06060, 0x19988181,  0x9ed14f4f,  0xa37fdcdc,
312     0x44662222, 0x547e2a2a,  0x3bab9090,  0xb838888,
313     0x8cca4646, 0xc729eeee,  0x6bd3b8b8,  0x283c1414,
314     0xa779dede, 0xbce25e5e,  0x161d0b0b,  0xad76dbdb,
315     0xdb3be0e0, 0x64563232,  0x744e3a3a,  0x141e0a0a,
316     0x92db4949, 0xc0a0606,   0x486c2424,  0xb8e45c5c,
317     0x9f5dc2c2, 0xbd6ed3d3,  0x43efacac,  0xc4a66262,
318     0x39a89191, 0x31a49595,  0xd337e4e4,  0xf28b7979,
319     0xd532e7e7, 0x8b43c8c8,  0x6e593737,  0xdab76d6d,
320     0x18c8d8d,  0xb164d5d5,  0x9cd24e4e,  0x49e0a9a9,
321     0xd8b46c6c, 0xacfa5656,  0xf307f4f4,  0xcf25eaea,
322     0xcaaf6565, 0xf48e7a7a,  0x47e9aeae,  0x10180808,
323     0x6fd5baba, 0xf0887878,  0x4a6f2525,  0x5c722e2e,
324     0x38241c1c, 0x57f1a6a6,  0x73c7b4b4,  0x9751c6c6,
325     0xcb23e8e8, 0xa17cdddd,  0xe89c7474,  0x3e211f1f,
326     0x96dd4b4b, 0x61dcbdbd,  0xd868b8b,   0xf858a8a,
327     0xe0907070, 0x7c423e3e,  0x71c4b5b5,  0xccaa6666,
328     0x90d84848, 0x6050303,   0xf701f6f6,  0x1c120e0e,
329     0xc2a36161, 0x6a5f3535,  0xaef95757,  0x69d0b9b9,
330     0x17918686, 0x9958c1c1,  0x3a271d1d,  0x27b99e9e,
331     0xd938e1e1, 0xeb13f8f8,  0x2bb39898,  0x22331111,
332     0xd2bb6969, 0xa970d9d9,  0x7898e8e,   0x33a79494,
333     0x2db69b9b, 0x3c221e1e,  0x15928787,  0xc920e9e9,
334     0x8749cece, 0xaaff5555,  0x50782828,  0xa57adfdf,
335     0x38f8c8c,  0x59f8a1a1,  0x9808989,   0x1a170d0d,
336     0x65dabfbf, 0xd731e6e6,  0x84c64242,  0xd0b86868,
337     0x82c34141, 0x29b09999,  0x5a772d2d,  0x1e110f0f,
338     0x7bcbb0b0, 0xa8fc5454,  0x6dd6bbbb,  0x2c3a1616,
339 };
340 /* clang-format on */
341 
342 /* clang-format off */
343 static const uint32_t U0[256] = {
344     0x50a7f451, 0x5365417e,  0xc3a4171a,  0x965e273a,
345     0xcb6bab3b, 0xf1459d1f,  0xab58faac,  0x9303e34b,
346     0x55fa3020, 0xf66d76ad,  0x9176cc88,  0x254c02f5,
347     0xfcd7e54f, 0xd7cb2ac5,  0x80443526,  0x8fa362b5,
348     0x495ab1de, 0x671bba25,  0x980eea45,  0xe1c0fe5d,
349     0x2752fc3,  0x12f04c81,  0xa397468d,  0xc6f9d36b,
350     0xe75f8f03, 0x959c9215,  0xeb7a6dbf,  0xda595295,
351     0x2d83bed4, 0xd3217458,  0x2969e049,  0x44c8c98e,
352     0x6a89c275, 0x78798ef4,  0x6b3e5899,  0xdd71b927,
353     0xb64fe1be, 0x17ad88f0,  0x66ac20c9,  0xb43ace7d,
354     0x184adf63, 0x82311ae5,  0x60335197,  0x457f5362,
355     0xe07764b1, 0x84ae6bbb,  0x1ca081fe,  0x942b08f9,
356     0x58684870, 0x19fd458f,  0x876cde94,  0xb7f87b52,
357     0x23d373ab, 0xe2024b72,  0x578f1fe3,  0x2aab5566,
358     0x728ebb2,  0x3c2b52f,   0x9a7bc586,  0xa50837d3,
359     0xf2872830, 0xb2a5bf23,  0xba6a0302,  0x5c8216ed,
360     0x2b1ccf8a, 0x92b479a7,  0xf0f207f3,  0xa1e2694e,
361     0xcdf4da65, 0xd5be0506,  0x1f6234d1,  0x8afea6c4,
362     0x9d532e34, 0xa055f3a2,  0x32e18a05,  0x75ebf6a4,
363     0x39ec830b, 0xaaef6040,  0x69f715e,   0x51106ebd,
364     0xf98a213e, 0x3d06dd96,  0xae053edd,  0x46bde64d,
365     0xb58d5491, 0x55dc471,   0x6fd40604,  0xff155060,
366     0x24fb9819, 0x97e9bdd6,  0xcc434089,  0x779ed967,
367     0xbd42e8b0, 0x888b8907,  0x385b19e7,  0xdbeec879,
368     0x470a7ca1, 0xe90f427c,  0xc91e84f8,  0x0,
369     0x83868009, 0x48ed2b32,  0xac70111e,  0x4e725a6c,
370     0xfbff0efd, 0x5638850f,  0x1ed5ae3d,  0x27392d36,
371     0x64d90f0a, 0x21a65c68,  0xd1545b9b,  0x3a2e3624,
372     0xb1670a0c, 0xfe75793,   0xd296eeb4,  0x9e919b1b,
373     0x4fc5c080, 0xa220dc61,  0x694b775a,  0x161a121c,
374     0xaba93e2,  0xe52aa0c0,  0x43e0223c,  0x1d171b12,
375     0xb0d090e,  0xadc78bf2,  0xb9a8b62d,  0xc8a91e14,
376     0x8519f157, 0x4c0775af,  0xbbdd99ee,  0xfd607fa3,
377     0x9f2601f7, 0xbcf5725c,  0xc53b6644,  0x347efb5b,
378     0x7629438b, 0xdcc623cb,  0x68fcedb6,  0x63f1e4b8,
379     0xcadc31d7, 0x10856342,  0x40229713,  0x2011c684,
380     0x7d244a85, 0xf83dbbd2,  0x1132f9ae,  0x6da129c7,
381     0x4b2f9e1d, 0xf330b2dc,  0xec52860d,  0xd0e3c177,
382     0x6c16b32b, 0x99b970a9,  0xfa489411,  0x2264e947,
383     0xc48cfca8, 0x1a3ff0a0,  0xd82c7d56,  0xef903322,
384     0xc74e4987, 0xc1d138d9,  0xfea2ca8c,  0x360bd498,
385     0xcf81f5a6, 0x28de7aa5,  0x268eb7da,  0xa4bfad3f,
386     0xe49d3a2c, 0xd927850,   0x9bcc5f6a,  0x62467e54,
387     0xc2138df6, 0xe8b8d890,  0x5ef7392e,  0xf5afc382,
388     0xbe805d9f, 0x7c93d069,  0xa92dd56f,  0xb31225cf,
389     0x3b99acc8, 0xa77d1810,  0x6e639ce8,  0x7bbb3bdb,
390     0x97826cd,  0xf418596e,  0x1b79aec,   0xa89a4f83,
391     0x656e95e6, 0x7ee6ffaa,  0x8cfbc21,   0xe6e815ef,
392     0xd99be7ba, 0xce366f4a,  0xd4099fea,  0xd67cb029,
393     0xafb2a431, 0x31233f2a,  0x3094a5c6,  0xc066a235,
394     0x37bc4e74, 0xa6ca82fc,  0xb0d090e0,  0x15d8a733,
395     0x4a9804f1, 0xf7daec41,  0xe50cd7f,   0x2ff69117,
396     0x8dd64d76, 0x4db0ef43,  0x544daacc,  0xdf0496e4,
397     0xe3b5d19e, 0x1b886a4c,  0xb81f2cc1,  0x7f516546,
398     0x4ea5e9d,  0x5d358c01,  0x737487fa,  0x2e410bfb,
399     0x5a1d67b3, 0x52d2db92,  0x335610e9,  0x1347d66d,
400     0x8c61d79a, 0x7a0ca137,  0x8e14f859,  0x893c13eb,
401     0xee27a9ce, 0x35c961b7,  0xede51ce1,  0x3cb1477a,
402     0x59dfd29c, 0x3f73f255,  0x79ce1418,  0xbf37c773,
403     0xeacdf753, 0x5baafd5f,  0x146f3ddf,  0x86db4478,
404     0x81f3afca, 0x3ec468b9,  0x2c342438,  0x5f40a3c2,
405     0x72c31d16, 0xc25e2bc,   0x8b493c28,  0x41950dff,
406     0x7101a839, 0xdeb30c08,  0x9ce4b4d8,  0x90c15664,
407     0x6184cb7b, 0x70b632d5,  0x745c6c48,  0x4257b8d0,
408 };
409 /* clang-format on */
410 
411 /* clang-format off */
412 static const uint32_t U1[256] = {
413     0xa7f45150, 0x65417e53,  0xa4171ac3,  0x5e273a96,
414     0x6bab3bcb, 0x459d1ff1,  0x58faacab,  0x3e34b93,
415     0xfa302055, 0x6d76adf6,  0x76cc8891,  0x4c02f525,
416     0xd7e54ffc, 0xcb2ac5d7,  0x44352680,  0xa362b58f,
417     0x5ab1de49, 0x1bba2567,  0xeea4598,   0xc0fe5de1,
418     0x752fc302, 0xf04c8112,  0x97468da3,  0xf9d36bc6,
419     0x5f8f03e7, 0x9c921595,  0x7a6dbfeb,  0x595295da,
420     0x83bed42d, 0x217458d3,  0x69e04929,  0xc8c98e44,
421     0x89c2756a, 0x798ef478,  0x3e58996b,  0x71b927dd,
422     0x4fe1beb6, 0xad88f017,  0xac20c966,  0x3ace7db4,
423     0x4adf6318, 0x311ae582,  0x33519760,  0x7f536245,
424     0x7764b1e0, 0xae6bbb84,  0xa081fe1c,  0x2b08f994,
425     0x68487058, 0xfd458f19,  0x6cde9487,  0xf87b52b7,
426     0xd373ab23, 0x24b72e2,   0x8f1fe357,  0xab55662a,
427     0x28ebb207, 0xc2b52f03,  0x7bc5869a,  0x837d3a5,
428     0x872830f2, 0xa5bf23b2,  0x6a0302ba,  0x8216ed5c,
429     0x1ccf8a2b, 0xb479a792,  0xf207f3f0,  0xe2694ea1,
430     0xf4da65cd, 0xbe0506d5,  0x6234d11f,  0xfea6c48a,
431     0x532e349d, 0x55f3a2a0,  0xe18a0532,  0xebf6a475,
432     0xec830b39, 0xef6040aa,  0x9f715e06,  0x106ebd51,
433     0x8a213ef9, 0x6dd963d,   0x53eddae,   0xbde64d46,
434     0x8d5491b5, 0x5dc47105,  0xd406046f,  0x155060ff,
435     0xfb981924, 0xe9bdd697,  0x434089cc,  0x9ed96777,
436     0x42e8b0bd, 0x8b890788,  0x5b19e738,  0xeec879db,
437     0xa7ca147,  0xf427ce9,   0x1e84f8c9,  0x0,
438     0x86800983, 0xed2b3248,  0x70111eac,  0x725a6c4e,
439     0xff0efdfb, 0x38850f56,  0xd5ae3d1e,  0x392d3627,
440     0xd90f0a64, 0xa65c6821,  0x545b9bd1,  0x2e36243a,
441     0x670a0cb1, 0xe757930f,  0x96eeb4d2,  0x919b1b9e,
442     0xc5c0804f, 0x20dc61a2,  0x4b775a69,  0x1a121c16,
443     0xba93e20a, 0x2aa0c0e5,  0xe0223c43,  0x171b121d,
444     0xd090e0b,  0xc78bf2ad,  0xa8b62db9,  0xa91e14c8,
445     0x19f15785, 0x775af4c,   0xdd99eebb,  0x607fa3fd,
446     0x2601f79f, 0xf5725cbc,  0x3b6644c5,  0x7efb5b34,
447     0x29438b76, 0xc623cbdc,  0xfcedb668,  0xf1e4b863,
448     0xdc31d7ca, 0x85634210,  0x22971340,  0x11c68420,
449     0x244a857d, 0x3dbbd2f8,  0x32f9ae11,  0xa129c76d,
450     0x2f9e1d4b, 0x30b2dcf3,  0x52860dec,  0xe3c177d0,
451     0x16b32b6c, 0xb970a999,  0x489411fa,  0x64e94722,
452     0x8cfca8c4, 0x3ff0a01a,  0x2c7d56d8,  0x903322ef,
453     0x4e4987c7, 0xd138d9c1,  0xa2ca8cfe,  0xbd49836,
454     0x81f5a6cf, 0xde7aa528,  0x8eb7da26,  0xbfad3fa4,
455     0x9d3a2ce4, 0x9278500d,  0xcc5f6a9b,  0x467e5462,
456     0x138df6c2, 0xb8d890e8,  0xf7392e5e,  0xafc382f5,
457     0x805d9fbe, 0x93d0697c,  0x2dd56fa9,  0x1225cfb3,
458     0x99acc83b, 0x7d1810a7,  0x639ce86e,  0xbb3bdb7b,
459     0x7826cd09, 0x18596ef4,  0xb79aec01,  0x9a4f83a8,
460     0x6e95e665, 0xe6ffaa7e,  0xcfbc2108,  0xe815efe6,
461     0x9be7bad9, 0x366f4ace,  0x99fead4,   0x7cb029d6,
462     0xb2a431af, 0x233f2a31,  0x94a5c630,  0x66a235c0,
463     0xbc4e7437, 0xca82fca6,  0xd090e0b0,  0xd8a73315,
464     0x9804f14a, 0xdaec41f7,  0x50cd7f0e,  0xf691172f,
465     0xd64d768d, 0xb0ef434d,  0x4daacc54,  0x496e4df,
466     0xb5d19ee3, 0x886a4c1b,  0x1f2cc1b8,  0x5165467f,
467     0xea5e9d04, 0x358c015d,  0x7487fa73,  0x410bfb2e,
468     0x1d67b35a, 0xd2db9252,  0x5610e933,  0x47d66d13,
469     0x61d79a8c, 0xca1377a,   0x14f8598e,  0x3c13eb89,
470     0x27a9ceee, 0xc961b735,  0xe51ce1ed,  0xb1477a3c,
471     0xdfd29c59, 0x73f2553f,  0xce141879,  0x37c773bf,
472     0xcdf753ea, 0xaafd5f5b,  0x6f3ddf14,  0xdb447886,
473     0xf3afca81, 0xc468b93e,  0x3424382c,  0x40a3c25f,
474     0xc31d1672, 0x25e2bc0c,  0x493c288b,  0x950dff41,
475     0x1a83971,  0xb30c08de,  0xe4b4d89c,  0xc1566490,
476     0x84cb7b61, 0xb632d570,  0x5c6c4874,  0x57b8d042,
477 };
478 /* clang-format on */
479 
480 /* clang-format off */
481 static const uint32_t U2[256] = {
482     0xf45150a7, 0x417e5365,  0x171ac3a4,  0x273a965e,
483     0xab3bcb6b, 0x9d1ff145,  0xfaacab58,  0xe34b9303,
484     0x302055fa, 0x76adf66d,  0xcc889176,  0x2f5254c,
485     0xe54ffcd7, 0x2ac5d7cb,  0x35268044,  0x62b58fa3,
486     0xb1de495a, 0xba25671b,  0xea45980e,  0xfe5de1c0,
487     0x2fc30275, 0x4c8112f0,  0x468da397,  0xd36bc6f9,
488     0x8f03e75f, 0x9215959c,  0x6dbfeb7a,  0x5295da59,
489     0xbed42d83, 0x7458d321,  0xe0492969,  0xc98e44c8,
490     0xc2756a89, 0x8ef47879,  0x58996b3e,  0xb927dd71,
491     0xe1beb64f, 0x88f017ad,  0x20c966ac,  0xce7db43a,
492     0xdf63184a, 0x1ae58231,  0x51976033,  0x5362457f,
493     0x64b1e077, 0x6bbb84ae,  0x81fe1ca0,  0x8f9942b,
494     0x48705868, 0x458f19fd,  0xde94876c,  0x7b52b7f8,
495     0x73ab23d3, 0x4b72e202,  0x1fe3578f,  0x55662aab,
496     0xebb20728, 0xb52f03c2,  0xc5869a7b,  0x37d3a508,
497     0x2830f287, 0xbf23b2a5,  0x302ba6a,   0x16ed5c82,
498     0xcf8a2b1c, 0x79a792b4,  0x7f3f0f2,   0x694ea1e2,
499     0xda65cdf4, 0x506d5be,   0x34d11f62,  0xa6c48afe,
500     0x2e349d53, 0xf3a2a055,  0x8a0532e1,  0xf6a475eb,
501     0x830b39ec, 0x6040aaef,  0x715e069f,  0x6ebd5110,
502     0x213ef98a, 0xdd963d06,  0x3eddae05,  0xe64d46bd,
503     0x5491b58d, 0xc471055d,  0x6046fd4,   0x5060ff15,
504     0x981924fb, 0xbdd697e9,  0x4089cc43,  0xd967779e,
505     0xe8b0bd42, 0x8907888b,  0x19e7385b,  0xc879dbee,
506     0x7ca1470a, 0x427ce90f,  0x84f8c91e,  0x0,
507     0x80098386, 0x2b3248ed,  0x111eac70,  0x5a6c4e72,
508     0xefdfbff,  0x850f5638,  0xae3d1ed5,  0x2d362739,
509     0xf0a64d9,  0x5c6821a6,  0x5b9bd154,  0x36243a2e,
510     0xa0cb167,  0x57930fe7,  0xeeb4d296,  0x9b1b9e91,
511     0xc0804fc5, 0xdc61a220,  0x775a694b,  0x121c161a,
512     0x93e20aba, 0xa0c0e52a,  0x223c43e0,  0x1b121d17,
513     0x90e0b0d,  0x8bf2adc7,  0xb62db9a8,  0x1e14c8a9,
514     0xf1578519, 0x75af4c07,  0x99eebbdd,  0x7fa3fd60,
515     0x1f79f26,  0x725cbcf5,  0x6644c53b,  0xfb5b347e,
516     0x438b7629, 0x23cbdcc6,  0xedb668fc,  0xe4b863f1,
517     0x31d7cadc, 0x63421085,  0x97134022,  0xc6842011,
518     0x4a857d24, 0xbbd2f83d,  0xf9ae1132,  0x29c76da1,
519     0x9e1d4b2f, 0xb2dcf330,  0x860dec52,  0xc177d0e3,
520     0xb32b6c16, 0x70a999b9,  0x9411fa48,  0xe9472264,
521     0xfca8c48c, 0xf0a01a3f,  0x7d56d82c,  0x3322ef90,
522     0x4987c74e, 0x38d9c1d1,  0xca8cfea2,  0xd498360b,
523     0xf5a6cf81, 0x7aa528de,  0xb7da268e,  0xad3fa4bf,
524     0x3a2ce49d, 0x78500d92,  0x5f6a9bcc,  0x7e546246,
525     0x8df6c213, 0xd890e8b8,  0x392e5ef7,  0xc382f5af,
526     0x5d9fbe80, 0xd0697c93,  0xd56fa92d,  0x25cfb312,
527     0xacc83b99, 0x1810a77d,  0x9ce86e63,  0x3bdb7bbb,
528     0x26cd0978, 0x596ef418,  0x9aec01b7,  0x4f83a89a,
529     0x95e6656e, 0xffaa7ee6,  0xbc2108cf,  0x15efe6e8,
530     0xe7bad99b, 0x6f4ace36,  0x9fead409,  0xb029d67c,
531     0xa431afb2, 0x3f2a3123,  0xa5c63094,  0xa235c066,
532     0x4e7437bc, 0x82fca6ca,  0x90e0b0d0,  0xa73315d8,
533     0x4f14a98,  0xec41f7da,  0xcd7f0e50,  0x91172ff6,
534     0x4d768dd6, 0xef434db0,  0xaacc544d,  0x96e4df04,
535     0xd19ee3b5, 0x6a4c1b88,  0x2cc1b81f,  0x65467f51,
536     0x5e9d04ea, 0x8c015d35,  0x87fa7374,  0xbfb2e41,
537     0x67b35a1d, 0xdb9252d2,  0x10e93356,  0xd66d1347,
538     0xd79a8c61, 0xa1377a0c,  0xf8598e14,  0x13eb893c,
539     0xa9ceee27, 0x61b735c9,  0x1ce1ede5,  0x477a3cb1,
540     0xd29c59df, 0xf2553f73,  0x141879ce,  0xc773bf37,
541     0xf753eacd, 0xfd5f5baa,  0x3ddf146f,  0x447886db,
542     0xafca81f3, 0x68b93ec4,  0x24382c34,  0xa3c25f40,
543     0x1d1672c3, 0xe2bc0c25,  0x3c288b49,  0xdff4195,
544     0xa8397101, 0xc08deb3,   0xb4d89ce4,  0x566490c1,
545     0xcb7b6184, 0x32d570b6,  0x6c48745c,  0xb8d04257,
546 };
547 /* clang-format on */
548 
549 /* clang-format off */
550 static const uint32_t U3[256] = {
551     0x5150a7f4, 0x7e536541,  0x1ac3a417,  0x3a965e27,
552     0x3bcb6bab, 0x1ff1459d,  0xacab58fa,  0x4b9303e3,
553     0x2055fa30, 0xadf66d76,  0x889176cc,  0xf5254c02,
554     0x4ffcd7e5, 0xc5d7cb2a,  0x26804435,  0xb58fa362,
555     0xde495ab1, 0x25671bba,  0x45980eea,  0x5de1c0fe,
556     0xc302752f, 0x8112f04c,  0x8da39746,  0x6bc6f9d3,
557     0x3e75f8f,  0x15959c92,  0xbfeb7a6d,  0x95da5952,
558     0xd42d83be, 0x58d32174,  0x492969e0,  0x8e44c8c9,
559     0x756a89c2, 0xf478798e,  0x996b3e58,  0x27dd71b9,
560     0xbeb64fe1, 0xf017ad88,  0xc966ac20,  0x7db43ace,
561     0x63184adf, 0xe582311a,  0x97603351,  0x62457f53,
562     0xb1e07764, 0xbb84ae6b,  0xfe1ca081,  0xf9942b08,
563     0x70586848, 0x8f19fd45,  0x94876cde,  0x52b7f87b,
564     0xab23d373, 0x72e2024b,  0xe3578f1f,  0x662aab55,
565     0xb20728eb, 0x2f03c2b5,  0x869a7bc5,  0xd3a50837,
566     0x30f28728, 0x23b2a5bf,  0x2ba6a03,   0xed5c8216,
567     0x8a2b1ccf, 0xa792b479,  0xf3f0f207,  0x4ea1e269,
568     0x65cdf4da, 0x6d5be05,   0xd11f6234,  0xc48afea6,
569     0x349d532e, 0xa2a055f3,  0x532e18a,   0xa475ebf6,
570     0xb39ec83,  0x40aaef60,  0x5e069f71,  0xbd51106e,
571     0x3ef98a21, 0x963d06dd,  0xddae053e,  0x4d46bde6,
572     0x91b58d54, 0x71055dc4,  0x46fd406,   0x60ff1550,
573     0x1924fb98, 0xd697e9bd,  0x89cc4340,  0x67779ed9,
574     0xb0bd42e8, 0x7888b89,   0xe7385b19,  0x79dbeec8,
575     0xa1470a7c, 0x7ce90f42,  0xf8c91e84,  0x0,
576     0x9838680,  0x3248ed2b,  0x1eac7011,  0x6c4e725a,
577     0xfdfbff0e, 0xf563885,   0x3d1ed5ae,  0x3627392d,
578     0xa64d90f,  0x6821a65c,  0x9bd1545b,  0x243a2e36,
579     0xcb1670a,  0x930fe757,  0xb4d296ee,  0x1b9e919b,
580     0x804fc5c0, 0x61a220dc,  0x5a694b77,  0x1c161a12,
581     0xe20aba93, 0xc0e52aa0,  0x3c43e022,  0x121d171b,
582     0xe0b0d09,  0xf2adc78b,  0x2db9a8b6,  0x14c8a91e,
583     0x578519f1, 0xaf4c0775,  0xeebbdd99,  0xa3fd607f,
584     0xf79f2601, 0x5cbcf572,  0x44c53b66,  0x5b347efb,
585     0x8b762943, 0xcbdcc623,  0xb668fced,  0xb863f1e4,
586     0xd7cadc31, 0x42108563,  0x13402297,  0x842011c6,
587     0x857d244a, 0xd2f83dbb,  0xae1132f9,  0xc76da129,
588     0x1d4b2f9e, 0xdcf330b2,  0xdec5286,   0x77d0e3c1,
589     0x2b6c16b3, 0xa999b970,  0x11fa4894,  0x472264e9,
590     0xa8c48cfc, 0xa01a3ff0,  0x56d82c7d,  0x22ef9033,
591     0x87c74e49, 0xd9c1d138,  0x8cfea2ca,  0x98360bd4,
592     0xa6cf81f5, 0xa528de7a,  0xda268eb7,  0x3fa4bfad,
593     0x2ce49d3a, 0x500d9278,  0x6a9bcc5f,  0x5462467e,
594     0xf6c2138d, 0x90e8b8d8,  0x2e5ef739,  0x82f5afc3,
595     0x9fbe805d, 0x697c93d0,  0x6fa92dd5,  0xcfb31225,
596     0xc83b99ac, 0x10a77d18,  0xe86e639c,  0xdb7bbb3b,
597     0xcd097826, 0x6ef41859,  0xec01b79a,  0x83a89a4f,
598     0xe6656e95, 0xaa7ee6ff,  0x2108cfbc,  0xefe6e815,
599     0xbad99be7, 0x4ace366f,  0xead4099f,  0x29d67cb0,
600     0x31afb2a4, 0x2a31233f,  0xc63094a5,  0x35c066a2,
601     0x7437bc4e, 0xfca6ca82,  0xe0b0d090,  0x3315d8a7,
602     0xf14a9804, 0x41f7daec,  0x7f0e50cd,  0x172ff691,
603     0x768dd64d, 0x434db0ef,  0xcc544daa,  0xe4df0496,
604     0x9ee3b5d1, 0x4c1b886a,  0xc1b81f2c,  0x467f5165,
605     0x9d04ea5e, 0x15d358c,   0xfa737487,  0xfb2e410b,
606     0xb35a1d67, 0x9252d2db,  0xe9335610,  0x6d1347d6,
607     0x9a8c61d7, 0x377a0ca1,  0x598e14f8,  0xeb893c13,
608     0xceee27a9, 0xb735c961,  0xe1ede51c,  0x7a3cb147,
609     0x9c59dfd2, 0x553f73f2,  0x1879ce14,  0x73bf37c7,
610     0x53eacdf7, 0x5f5baafd,  0xdf146f3d,  0x7886db44,
611     0xca81f3af, 0xb93ec468,  0x382c3424,  0xc25f40a3,
612     0x1672c31d, 0xbc0c25e2,  0x288b493c,  0xff41950d,
613     0x397101a8, 0x8deb30c,   0xd89ce4b4,  0x6490c156,
614     0x7b6184cb, 0xd570b632,  0x48745c6c,  0xd04257b8,
615 };
616 /* clang-format on */
617 
618 #else /* assume big endian */
619 /* clang-format off */
620 static const uint32_t T0[256] = {
621     0xc66363a5, 0xf87c7c84,  0xee777799,  0xf67b7b8d,
622     0xfff2f20d, 0xd66b6bbd,  0xde6f6fb1,  0x91c5c554,
623     0x60303050, 0x2010103,   0xce6767a9,  0x562b2b7d,
624     0xe7fefe19, 0xb5d7d762,  0x4dababe6,  0xec76769a,
625     0x8fcaca45, 0x1f82829d,  0x89c9c940,  0xfa7d7d87,
626     0xeffafa15, 0xb25959eb,  0x8e4747c9,  0xfbf0f00b,
627     0x41adadec, 0xb3d4d467,  0x5fa2a2fd,  0x45afafea,
628     0x239c9cbf, 0x53a4a4f7,  0xe4727296,  0x9bc0c05b,
629     0x75b7b7c2, 0xe1fdfd1c,  0x3d9393ae,  0x4c26266a,
630     0x6c36365a, 0x7e3f3f41,  0xf5f7f702,  0x83cccc4f,
631     0x6834345c, 0x51a5a5f4,  0xd1e5e534,  0xf9f1f108,
632     0xe2717193, 0xabd8d873,  0x62313153,  0x2a15153f,
633     0x804040c,  0x95c7c752,  0x46232365,  0x9dc3c35e,
634     0x30181828, 0x379696a1,  0xa05050f,   0x2f9a9ab5,
635     0xe070709,  0x24121236,  0x1b80809b,  0xdfe2e23d,
636     0xcdebeb26, 0x4e272769,  0x7fb2b2cd,  0xea75759f,
637     0x1209091b, 0x1d83839e,  0x582c2c74,  0x341a1a2e,
638     0x361b1b2d, 0xdc6e6eb2,  0xb45a5aee,  0x5ba0a0fb,
639     0xa45252f6, 0x763b3b4d,  0xb7d6d661,  0x7db3b3ce,
640     0x5229297b, 0xdde3e33e,  0x5e2f2f71,  0x13848497,
641     0xa65353f5, 0xb9d1d168,  0x0,         0xc1eded2c,
642     0x40202060, 0xe3fcfc1f,  0x79b1b1c8,  0xb65b5bed,
643     0xd46a6abe, 0x8dcbcb46,  0x67bebed9,  0x7239394b,
644     0x944a4ade, 0x984c4cd4,  0xb05858e8,  0x85cfcf4a,
645     0xbbd0d06b, 0xc5efef2a,  0x4faaaae5,  0xedfbfb16,
646     0x864343c5, 0x9a4d4dd7,  0x66333355,  0x11858594,
647     0x8a4545cf, 0xe9f9f910,  0x4020206,   0xfe7f7f81,
648     0xa05050f0, 0x783c3c44,  0x259f9fba,  0x4ba8a8e3,
649     0xa25151f3, 0x5da3a3fe,  0x804040c0,  0x58f8f8a,
650     0x3f9292ad, 0x219d9dbc,  0x70383848,  0xf1f5f504,
651     0x63bcbcdf, 0x77b6b6c1,  0xafdada75,  0x42212163,
652     0x20101030, 0xe5ffff1a,  0xfdf3f30e,  0xbfd2d26d,
653     0x81cdcd4c, 0x180c0c14,  0x26131335,  0xc3ecec2f,
654     0xbe5f5fe1, 0x359797a2,  0x884444cc,  0x2e171739,
655     0x93c4c457, 0x55a7a7f2,  0xfc7e7e82,  0x7a3d3d47,
656     0xc86464ac, 0xba5d5de7,  0x3219192b,  0xe6737395,
657     0xc06060a0, 0x19818198,  0x9e4f4fd1,  0xa3dcdc7f,
658     0x44222266, 0x542a2a7e,  0x3b9090ab,  0xb888883,
659     0x8c4646ca, 0xc7eeee29,  0x6bb8b8d3,  0x2814143c,
660     0xa7dede79, 0xbc5e5ee2,  0x160b0b1d,  0xaddbdb76,
661     0xdbe0e03b, 0x64323256,  0x743a3a4e,  0x140a0a1e,
662     0x924949db, 0xc06060a,   0x4824246c,  0xb85c5ce4,
663     0x9fc2c25d, 0xbdd3d36e,  0x43acacef,  0xc46262a6,
664     0x399191a8, 0x319595a4,  0xd3e4e437,  0xf279798b,
665     0xd5e7e732, 0x8bc8c843,  0x6e373759,  0xda6d6db7,
666     0x18d8d8c,  0xb1d5d564,  0x9c4e4ed2,  0x49a9a9e0,
667     0xd86c6cb4, 0xac5656fa,  0xf3f4f407,  0xcfeaea25,
668     0xca6565af, 0xf47a7a8e,  0x47aeaee9,  0x10080818,
669     0x6fbabad5, 0xf0787888,  0x4a25256f,  0x5c2e2e72,
670     0x381c1c24, 0x57a6a6f1,  0x73b4b4c7,  0x97c6c651,
671     0xcbe8e823, 0xa1dddd7c,  0xe874749c,  0x3e1f1f21,
672     0x964b4bdd, 0x61bdbddc,  0xd8b8b86,   0xf8a8a85,
673     0xe0707090, 0x7c3e3e42,  0x71b5b5c4,  0xcc6666aa,
674     0x904848d8, 0x6030305,   0xf7f6f601,  0x1c0e0e12,
675     0xc26161a3, 0x6a35355f,  0xae5757f9,  0x69b9b9d0,
676     0x17868691, 0x99c1c158,  0x3a1d1d27,  0x279e9eb9,
677     0xd9e1e138, 0xebf8f813,  0x2b9898b3,  0x22111133,
678     0xd26969bb, 0xa9d9d970,  0x78e8e89,   0x339494a7,
679     0x2d9b9bb6, 0x3c1e1e22,  0x15878792,  0xc9e9e920,
680     0x87cece49, 0xaa5555ff,  0x50282878,  0xa5dfdf7a,
681     0x38c8c8f,  0x59a1a1f8,  0x9898980,   0x1a0d0d17,
682     0x65bfbfda, 0xd7e6e631,  0x844242c6,  0xd06868b8,
683     0x824141c3, 0x299999b0,  0x5a2d2d77,  0x1e0f0f11,
684     0x7bb0b0cb, 0xa85454fc,  0x6dbbbbd6,  0x2c16163a,
685 };
686 /* clang-format on */
687 
688 /* clang-format off */
689 static const uint32_t T1[256] = {
690     0xa5c66363, 0x84f87c7c,  0x99ee7777,  0x8df67b7b,
691     0xdfff2f2,  0xbdd66b6b,  0xb1de6f6f,  0x5491c5c5,
692     0x50603030, 0x3020101,   0xa9ce6767,  0x7d562b2b,
693     0x19e7fefe, 0x62b5d7d7,  0xe64dabab,  0x9aec7676,
694     0x458fcaca, 0x9d1f8282,  0x4089c9c9,  0x87fa7d7d,
695     0x15effafa, 0xebb25959,  0xc98e4747,  0xbfbf0f0,
696     0xec41adad, 0x67b3d4d4,  0xfd5fa2a2,  0xea45afaf,
697     0xbf239c9c, 0xf753a4a4,  0x96e47272,  0x5b9bc0c0,
698     0xc275b7b7, 0x1ce1fdfd,  0xae3d9393,  0x6a4c2626,
699     0x5a6c3636, 0x417e3f3f,  0x2f5f7f7,   0x4f83cccc,
700     0x5c683434, 0xf451a5a5,  0x34d1e5e5,  0x8f9f1f1,
701     0x93e27171, 0x73abd8d8,  0x53623131,  0x3f2a1515,
702     0xc080404,  0x5295c7c7,  0x65462323,  0x5e9dc3c3,
703     0x28301818, 0xa1379696,  0xf0a0505,   0xb52f9a9a,
704     0x90e0707,  0x36241212,  0x9b1b8080,  0x3ddfe2e2,
705     0x26cdebeb, 0x694e2727,  0xcd7fb2b2,  0x9fea7575,
706     0x1b120909, 0x9e1d8383,  0x74582c2c,  0x2e341a1a,
707     0x2d361b1b, 0xb2dc6e6e,  0xeeb45a5a,  0xfb5ba0a0,
708     0xf6a45252, 0x4d763b3b,  0x61b7d6d6,  0xce7db3b3,
709     0x7b522929, 0x3edde3e3,  0x715e2f2f,  0x97138484,
710     0xf5a65353, 0x68b9d1d1,  0x0,         0x2cc1eded,
711     0x60402020, 0x1fe3fcfc,  0xc879b1b1,  0xedb65b5b,
712     0xbed46a6a, 0x468dcbcb,  0xd967bebe,  0x4b723939,
713     0xde944a4a, 0xd4984c4c,  0xe8b05858,  0x4a85cfcf,
714     0x6bbbd0d0, 0x2ac5efef,  0xe54faaaa,  0x16edfbfb,
715     0xc5864343, 0xd79a4d4d,  0x55663333,  0x94118585,
716     0xcf8a4545, 0x10e9f9f9,  0x6040202,   0x81fe7f7f,
717     0xf0a05050, 0x44783c3c,  0xba259f9f,  0xe34ba8a8,
718     0xf3a25151, 0xfe5da3a3,  0xc0804040,  0x8a058f8f,
719     0xad3f9292, 0xbc219d9d,  0x48703838,  0x4f1f5f5,
720     0xdf63bcbc, 0xc177b6b6,  0x75afdada,  0x63422121,
721     0x30201010, 0x1ae5ffff,  0xefdf3f3,   0x6dbfd2d2,
722     0x4c81cdcd, 0x14180c0c,  0x35261313,  0x2fc3ecec,
723     0xe1be5f5f, 0xa2359797,  0xcc884444,  0x392e1717,
724     0x5793c4c4, 0xf255a7a7,  0x82fc7e7e,  0x477a3d3d,
725     0xacc86464, 0xe7ba5d5d,  0x2b321919,  0x95e67373,
726     0xa0c06060, 0x98198181,  0xd19e4f4f,  0x7fa3dcdc,
727     0x66442222, 0x7e542a2a,  0xab3b9090,  0x830b8888,
728     0xca8c4646, 0x29c7eeee,  0xd36bb8b8,  0x3c281414,
729     0x79a7dede, 0xe2bc5e5e,  0x1d160b0b,  0x76addbdb,
730     0x3bdbe0e0, 0x56643232,  0x4e743a3a,  0x1e140a0a,
731     0xdb924949, 0xa0c0606,   0x6c482424,  0xe4b85c5c,
732     0x5d9fc2c2, 0x6ebdd3d3,  0xef43acac,  0xa6c46262,
733     0xa8399191, 0xa4319595,  0x37d3e4e4,  0x8bf27979,
734     0x32d5e7e7, 0x438bc8c8,  0x596e3737,  0xb7da6d6d,
735     0x8c018d8d, 0x64b1d5d5,  0xd29c4e4e,  0xe049a9a9,
736     0xb4d86c6c, 0xfaac5656,  0x7f3f4f4,   0x25cfeaea,
737     0xafca6565, 0x8ef47a7a,  0xe947aeae,  0x18100808,
738     0xd56fbaba, 0x88f07878,  0x6f4a2525,  0x725c2e2e,
739     0x24381c1c, 0xf157a6a6,  0xc773b4b4,  0x5197c6c6,
740     0x23cbe8e8, 0x7ca1dddd,  0x9ce87474,  0x213e1f1f,
741     0xdd964b4b, 0xdc61bdbd,  0x860d8b8b,  0x850f8a8a,
742     0x90e07070, 0x427c3e3e,  0xc471b5b5,  0xaacc6666,
743     0xd8904848, 0x5060303,   0x1f7f6f6,   0x121c0e0e,
744     0xa3c26161, 0x5f6a3535,  0xf9ae5757,  0xd069b9b9,
745     0x91178686, 0x5899c1c1,  0x273a1d1d,  0xb9279e9e,
746     0x38d9e1e1, 0x13ebf8f8,  0xb32b9898,  0x33221111,
747     0xbbd26969, 0x70a9d9d9,  0x89078e8e,  0xa7339494,
748     0xb62d9b9b, 0x223c1e1e,  0x92158787,  0x20c9e9e9,
749     0x4987cece, 0xffaa5555,  0x78502828,  0x7aa5dfdf,
750     0x8f038c8c, 0xf859a1a1,  0x80098989,  0x171a0d0d,
751     0xda65bfbf, 0x31d7e6e6,  0xc6844242,  0xb8d06868,
752     0xc3824141, 0xb0299999,  0x775a2d2d,  0x111e0f0f,
753     0xcb7bb0b0, 0xfca85454,  0xd66dbbbb,  0x3a2c1616,
754 };
755 /* clang-format on */
756 
757 /* clang-format off */
758 static const uint32_t T2[256] = {
759     0x63a5c663, 0x7c84f87c,  0x7799ee77,  0x7b8df67b,
760     0xf20dfff2, 0x6bbdd66b,  0x6fb1de6f,  0xc55491c5,
761     0x30506030, 0x1030201,   0x67a9ce67,  0x2b7d562b,
762     0xfe19e7fe, 0xd762b5d7,  0xabe64dab,  0x769aec76,
763     0xca458fca, 0x829d1f82,  0xc94089c9,  0x7d87fa7d,
764     0xfa15effa, 0x59ebb259,  0x47c98e47,  0xf00bfbf0,
765     0xadec41ad, 0xd467b3d4,  0xa2fd5fa2,  0xafea45af,
766     0x9cbf239c, 0xa4f753a4,  0x7296e472,  0xc05b9bc0,
767     0xb7c275b7, 0xfd1ce1fd,  0x93ae3d93,  0x266a4c26,
768     0x365a6c36, 0x3f417e3f,  0xf702f5f7,  0xcc4f83cc,
769     0x345c6834, 0xa5f451a5,  0xe534d1e5,  0xf108f9f1,
770     0x7193e271, 0xd873abd8,  0x31536231,  0x153f2a15,
771     0x40c0804,  0xc75295c7,  0x23654623,  0xc35e9dc3,
772     0x18283018, 0x96a13796,  0x50f0a05,   0x9ab52f9a,
773     0x7090e07,  0x12362412,  0x809b1b80,  0xe23ddfe2,
774     0xeb26cdeb, 0x27694e27,  0xb2cd7fb2,  0x759fea75,
775     0x91b1209,  0x839e1d83,  0x2c74582c,  0x1a2e341a,
776     0x1b2d361b, 0x6eb2dc6e,  0x5aeeb45a,  0xa0fb5ba0,
777     0x52f6a452, 0x3b4d763b,  0xd661b7d6,  0xb3ce7db3,
778     0x297b5229, 0xe33edde3,  0x2f715e2f,  0x84971384,
779     0x53f5a653, 0xd168b9d1,  0x0,         0xed2cc1ed,
780     0x20604020, 0xfc1fe3fc,  0xb1c879b1,  0x5bedb65b,
781     0x6abed46a, 0xcb468dcb,  0xbed967be,  0x394b7239,
782     0x4ade944a, 0x4cd4984c,  0x58e8b058,  0xcf4a85cf,
783     0xd06bbbd0, 0xef2ac5ef,  0xaae54faa,  0xfb16edfb,
784     0x43c58643, 0x4dd79a4d,  0x33556633,  0x85941185,
785     0x45cf8a45, 0xf910e9f9,  0x2060402,   0x7f81fe7f,
786     0x50f0a050, 0x3c44783c,  0x9fba259f,  0xa8e34ba8,
787     0x51f3a251, 0xa3fe5da3,  0x40c08040,  0x8f8a058f,
788     0x92ad3f92, 0x9dbc219d,  0x38487038,  0xf504f1f5,
789     0xbcdf63bc, 0xb6c177b6,  0xda75afda,  0x21634221,
790     0x10302010, 0xff1ae5ff,  0xf30efdf3,  0xd26dbfd2,
791     0xcd4c81cd, 0xc14180c,   0x13352613,  0xec2fc3ec,
792     0x5fe1be5f, 0x97a23597,  0x44cc8844,  0x17392e17,
793     0xc45793c4, 0xa7f255a7,  0x7e82fc7e,  0x3d477a3d,
794     0x64acc864, 0x5de7ba5d,  0x192b3219,  0x7395e673,
795     0x60a0c060, 0x81981981,  0x4fd19e4f,  0xdc7fa3dc,
796     0x22664422, 0x2a7e542a,  0x90ab3b90,  0x88830b88,
797     0x46ca8c46, 0xee29c7ee,  0xb8d36bb8,  0x143c2814,
798     0xde79a7de, 0x5ee2bc5e,  0xb1d160b,   0xdb76addb,
799     0xe03bdbe0, 0x32566432,  0x3a4e743a,  0xa1e140a,
800     0x49db9249, 0x60a0c06,   0x246c4824,  0x5ce4b85c,
801     0xc25d9fc2, 0xd36ebdd3,  0xacef43ac,  0x62a6c462,
802     0x91a83991, 0x95a43195,  0xe437d3e4,  0x798bf279,
803     0xe732d5e7, 0xc8438bc8,  0x37596e37,  0x6db7da6d,
804     0x8d8c018d, 0xd564b1d5,  0x4ed29c4e,  0xa9e049a9,
805     0x6cb4d86c, 0x56faac56,  0xf407f3f4,  0xea25cfea,
806     0x65afca65, 0x7a8ef47a,  0xaee947ae,  0x8181008,
807     0xbad56fba, 0x7888f078,  0x256f4a25,  0x2e725c2e,
808     0x1c24381c, 0xa6f157a6,  0xb4c773b4,  0xc65197c6,
809     0xe823cbe8, 0xdd7ca1dd,  0x749ce874,  0x1f213e1f,
810     0x4bdd964b, 0xbddc61bd,  0x8b860d8b,  0x8a850f8a,
811     0x7090e070, 0x3e427c3e,  0xb5c471b5,  0x66aacc66,
812     0x48d89048, 0x3050603,   0xf601f7f6,  0xe121c0e,
813     0x61a3c261, 0x355f6a35,  0x57f9ae57,  0xb9d069b9,
814     0x86911786, 0xc15899c1,  0x1d273a1d,  0x9eb9279e,
815     0xe138d9e1, 0xf813ebf8,  0x98b32b98,  0x11332211,
816     0x69bbd269, 0xd970a9d9,  0x8e89078e,  0x94a73394,
817     0x9bb62d9b, 0x1e223c1e,  0x87921587,  0xe920c9e9,
818     0xce4987ce, 0x55ffaa55,  0x28785028,  0xdf7aa5df,
819     0x8c8f038c, 0xa1f859a1,  0x89800989,  0xd171a0d,
820     0xbfda65bf, 0xe631d7e6,  0x42c68442,  0x68b8d068,
821     0x41c38241, 0x99b02999,  0x2d775a2d,  0xf111e0f,
822     0xb0cb7bb0, 0x54fca854,  0xbbd66dbb,  0x163a2c16,
823 };
824 /* clang-format on */
825 
826 /* clang-format off */
827 static const uint32_t T3[256] = {
828     0x6363a5c6, 0x7c7c84f8,  0x777799ee,  0x7b7b8df6,
829     0xf2f20dff, 0x6b6bbdd6,  0x6f6fb1de,  0xc5c55491,
830     0x30305060, 0x1010302,   0x6767a9ce,  0x2b2b7d56,
831     0xfefe19e7, 0xd7d762b5,  0xababe64d,  0x76769aec,
832     0xcaca458f, 0x82829d1f,  0xc9c94089,  0x7d7d87fa,
833     0xfafa15ef, 0x5959ebb2,  0x4747c98e,  0xf0f00bfb,
834     0xadadec41, 0xd4d467b3,  0xa2a2fd5f,  0xafafea45,
835     0x9c9cbf23, 0xa4a4f753,  0x727296e4,  0xc0c05b9b,
836     0xb7b7c275, 0xfdfd1ce1,  0x9393ae3d,  0x26266a4c,
837     0x36365a6c, 0x3f3f417e,  0xf7f702f5,  0xcccc4f83,
838     0x34345c68, 0xa5a5f451,  0xe5e534d1,  0xf1f108f9,
839     0x717193e2, 0xd8d873ab,  0x31315362,  0x15153f2a,
840     0x4040c08,  0xc7c75295,  0x23236546,  0xc3c35e9d,
841     0x18182830, 0x9696a137,  0x5050f0a,   0x9a9ab52f,
842     0x707090e,  0x12123624,  0x80809b1b,  0xe2e23ddf,
843     0xebeb26cd, 0x2727694e,  0xb2b2cd7f,  0x75759fea,
844     0x9091b12,  0x83839e1d,  0x2c2c7458,  0x1a1a2e34,
845     0x1b1b2d36, 0x6e6eb2dc,  0x5a5aeeb4,  0xa0a0fb5b,
846     0x5252f6a4, 0x3b3b4d76,  0xd6d661b7,  0xb3b3ce7d,
847     0x29297b52, 0xe3e33edd,  0x2f2f715e,  0x84849713,
848     0x5353f5a6, 0xd1d168b9,  0x0,         0xeded2cc1,
849     0x20206040, 0xfcfc1fe3,  0xb1b1c879,  0x5b5bedb6,
850     0x6a6abed4, 0xcbcb468d,  0xbebed967,  0x39394b72,
851     0x4a4ade94, 0x4c4cd498,  0x5858e8b0,  0xcfcf4a85,
852     0xd0d06bbb, 0xefef2ac5,  0xaaaae54f,  0xfbfb16ed,
853     0x4343c586, 0x4d4dd79a,  0x33335566,  0x85859411,
854     0x4545cf8a, 0xf9f910e9,  0x2020604,   0x7f7f81fe,
855     0x5050f0a0, 0x3c3c4478,  0x9f9fba25,  0xa8a8e34b,
856     0x5151f3a2, 0xa3a3fe5d,  0x4040c080,  0x8f8f8a05,
857     0x9292ad3f, 0x9d9dbc21,  0x38384870,  0xf5f504f1,
858     0xbcbcdf63, 0xb6b6c177,  0xdada75af,  0x21216342,
859     0x10103020, 0xffff1ae5,  0xf3f30efd,  0xd2d26dbf,
860     0xcdcd4c81, 0xc0c1418,   0x13133526,  0xecec2fc3,
861     0x5f5fe1be, 0x9797a235,  0x4444cc88,  0x1717392e,
862     0xc4c45793, 0xa7a7f255,  0x7e7e82fc,  0x3d3d477a,
863     0x6464acc8, 0x5d5de7ba,  0x19192b32,  0x737395e6,
864     0x6060a0c0, 0x81819819,  0x4f4fd19e,  0xdcdc7fa3,
865     0x22226644, 0x2a2a7e54,  0x9090ab3b,  0x8888830b,
866     0x4646ca8c, 0xeeee29c7,  0xb8b8d36b,  0x14143c28,
867     0xdede79a7, 0x5e5ee2bc,  0xb0b1d16,   0xdbdb76ad,
868     0xe0e03bdb, 0x32325664,  0x3a3a4e74,  0xa0a1e14,
869     0x4949db92, 0x6060a0c,   0x24246c48,  0x5c5ce4b8,
870     0xc2c25d9f, 0xd3d36ebd,  0xacacef43,  0x6262a6c4,
871     0x9191a839, 0x9595a431,  0xe4e437d3,  0x79798bf2,
872     0xe7e732d5, 0xc8c8438b,  0x3737596e,  0x6d6db7da,
873     0x8d8d8c01, 0xd5d564b1,  0x4e4ed29c,  0xa9a9e049,
874     0x6c6cb4d8, 0x5656faac,  0xf4f407f3,  0xeaea25cf,
875     0x6565afca, 0x7a7a8ef4,  0xaeaee947,  0x8081810,
876     0xbabad56f, 0x787888f0,  0x25256f4a,  0x2e2e725c,
877     0x1c1c2438, 0xa6a6f157,  0xb4b4c773,  0xc6c65197,
878     0xe8e823cb, 0xdddd7ca1,  0x74749ce8,  0x1f1f213e,
879     0x4b4bdd96, 0xbdbddc61,  0x8b8b860d,  0x8a8a850f,
880     0x707090e0, 0x3e3e427c,  0xb5b5c471,  0x6666aacc,
881     0x4848d890, 0x3030506,   0xf6f601f7,  0xe0e121c,
882     0x6161a3c2, 0x35355f6a,  0x5757f9ae,  0xb9b9d069,
883     0x86869117, 0xc1c15899,  0x1d1d273a,  0x9e9eb927,
884     0xe1e138d9, 0xf8f813eb,  0x9898b32b,  0x11113322,
885     0x6969bbd2, 0xd9d970a9,  0x8e8e8907,  0x9494a733,
886     0x9b9bb62d, 0x1e1e223c,  0x87879215,  0xe9e920c9,
887     0xcece4987, 0x5555ffaa,  0x28287850,  0xdfdf7aa5,
888     0x8c8c8f03, 0xa1a1f859,  0x89898009,  0xd0d171a,
889     0xbfbfda65, 0xe6e631d7,  0x4242c684,  0x6868b8d0,
890     0x4141c382, 0x9999b029,  0x2d2d775a,  0xf0f111e,
891     0xb0b0cb7b, 0x5454fca8,  0xbbbbd66d,  0x16163a2c,
892 };
893 /* clang-format on */
894 
895 /* clang-format off */
896 static const uint32_t U0[256] = {
897     0x51f4a750, 0x7e416553,  0x1a17a4c3,  0x3a275e96,
898     0x3bab6bcb, 0x1f9d45f1,  0xacfa58ab,  0x4be30393,
899     0x2030fa55, 0xad766df6,  0x88cc7691,  0xf5024c25,
900     0x4fe5d7fc, 0xc52acbd7,  0x26354480,  0xb562a38f,
901     0xdeb15a49, 0x25ba1b67,  0x45ea0e98,  0x5dfec0e1,
902     0xc32f7502, 0x814cf012,  0x8d4697a3,  0x6bd3f9c6,
903     0x38f5fe7,  0x15929c95,  0xbf6d7aeb,  0x955259da,
904     0xd4be832d, 0x587421d3,  0x49e06929,  0x8ec9c844,
905     0x75c2896a, 0xf48e7978,  0x99583e6b,  0x27b971dd,
906     0xbee14fb6, 0xf088ad17,  0xc920ac66,  0x7dce3ab4,
907     0x63df4a18, 0xe51a3182,  0x97513360,  0x62537f45,
908     0xb16477e0, 0xbb6bae84,  0xfe81a01c,  0xf9082b94,
909     0x70486858, 0x8f45fd19,  0x94de6c87,  0x527bf8b7,
910     0xab73d323, 0x724b02e2,  0xe31f8f57,  0x6655ab2a,
911     0xb2eb2807, 0x2fb5c203,  0x86c57b9a,  0xd33708a5,
912     0x302887f2, 0x23bfa5b2,  0x2036aba,   0xed16825c,
913     0x8acf1c2b, 0xa779b492,  0xf307f2f0,  0x4e69e2a1,
914     0x65daf4cd, 0x605bed5,   0xd134621f,  0xc4a6fe8a,
915     0x342e539d, 0xa2f355a0,  0x58ae132,   0xa4f6eb75,
916     0xb83ec39,  0x4060efaa,  0x5e719f06,  0xbd6e1051,
917     0x3e218af9, 0x96dd063d,  0xdd3e05ae,  0x4de6bd46,
918     0x91548db5, 0x71c45d05,  0x406d46f,   0x605015ff,
919     0x1998fb24, 0xd6bde997,  0x894043cc,  0x67d99e77,
920     0xb0e842bd, 0x7898b88,   0xe7195b38,  0x79c8eedb,
921     0xa17c0a47, 0x7c420fe9,  0xf8841ec9,  0x0,
922     0x9808683,  0x322bed48,  0x1e1170ac,  0x6c5a724e,
923     0xfd0efffb, 0xf853856,   0x3daed51e,  0x362d3927,
924     0xa0fd964,  0x685ca621,  0x9b5b54d1,  0x24362e3a,
925     0xc0a67b1,  0x9357e70f,  0xb4ee96d2,  0x1b9b919e,
926     0x80c0c54f, 0x61dc20a2,  0x5a774b69,  0x1c121a16,
927     0xe293ba0a, 0xc0a02ae5,  0x3c22e043,  0x121b171d,
928     0xe090d0b,  0xf28bc7ad,  0x2db6a8b9,  0x141ea9c8,
929     0x57f11985, 0xaf75074c,  0xee99ddbb,  0xa37f60fd,
930     0xf701269f, 0x5c72f5bc,  0x44663bc5,  0x5bfb7e34,
931     0x8b432976, 0xcb23c6dc,  0xb6edfc68,  0xb8e4f163,
932     0xd731dcca, 0x42638510,  0x13972240,  0x84c61120,
933     0x854a247d, 0xd2bb3df8,  0xaef93211,  0xc729a16d,
934     0x1d9e2f4b, 0xdcb230f3,  0xd8652ec,   0x77c1e3d0,
935     0x2bb3166c, 0xa970b999,  0x119448fa,  0x47e96422,
936     0xa8fc8cc4, 0xa0f03f1a,  0x567d2cd8,  0x223390ef,
937     0x87494ec7, 0xd938d1c1,  0x8ccaa2fe,  0x98d40b36,
938     0xa6f581cf, 0xa57ade28,  0xdab78e26,  0x3fadbfa4,
939     0x2c3a9de4, 0x5078920d,  0x6a5fcc9b,  0x547e4662,
940     0xf68d13c2, 0x90d8b8e8,  0x2e39f75e,  0x82c3aff5,
941     0x9f5d80be, 0x69d0937c,  0x6fd52da9,  0xcf2512b3,
942     0xc8ac993b, 0x10187da7,  0xe89c636e,  0xdb3bbb7b,
943     0xcd267809, 0x6e5918f4,  0xec9ab701,  0x834f9aa8,
944     0xe6956e65, 0xaaffe67e,  0x21bccf08,  0xef15e8e6,
945     0xbae79bd9, 0x4a6f36ce,  0xea9f09d4,  0x29b07cd6,
946     0x31a4b2af, 0x2a3f2331,  0xc6a59430,  0x35a266c0,
947     0x744ebc37, 0xfc82caa6,  0xe090d0b0,  0x33a7d815,
948     0xf104984a, 0x41ecdaf7,  0x7fcd500e,  0x1791f62f,
949     0x764dd68d, 0x43efb04d,  0xccaa4d54,  0xe49604df,
950     0x9ed1b5e3, 0x4c6a881b,  0xc12c1fb8,  0x4665517f,
951     0x9d5eea04, 0x18c355d,   0xfa877473,  0xfb0b412e,
952     0xb3671d5a, 0x92dbd252,  0xe9105633,  0x6dd64713,
953     0x9ad7618c, 0x37a10c7a,  0x59f8148e,  0xeb133c89,
954     0xcea927ee, 0xb761c935,  0xe11ce5ed,  0x7a47b13c,
955     0x9cd2df59, 0x55f2733f,  0x1814ce79,  0x73c737bf,
956     0x53f7cdea, 0x5ffdaa5b,  0xdf3d6f14,  0x7844db86,
957     0xcaaff381, 0xb968c43e,  0x3824342c,  0xc2a3405f,
958     0x161dc372, 0xbce2250c,  0x283c498b,  0xff0d9541,
959     0x39a80171, 0x80cb3de,   0xd8b4e49c,  0x6456c190,
960     0x7bcb8461, 0xd532b670,  0x486c5c74,  0xd0b85742
961 };
962 /* clang-format on */
963 
964 /* clang-format off */
965 static const uint32_t U1[256] = {
966     0x5051f4a7, 0x537e4165,  0xc31a17a4,  0x963a275e,
967     0xcb3bab6b, 0xf11f9d45,  0xabacfa58,  0x934be303,
968     0x552030fa, 0xf6ad766d,  0x9188cc76,  0x25f5024c,
969     0xfc4fe5d7, 0xd7c52acb,  0x80263544,  0x8fb562a3,
970     0x49deb15a, 0x6725ba1b,  0x9845ea0e,  0xe15dfec0,
971     0x2c32f75,  0x12814cf0,  0xa38d4697,  0xc66bd3f9,
972     0xe7038f5f, 0x9515929c,  0xebbf6d7a,  0xda955259,
973     0x2dd4be83, 0xd3587421,  0x2949e069,  0x448ec9c8,
974     0x6a75c289, 0x78f48e79,  0x6b99583e,  0xdd27b971,
975     0xb6bee14f, 0x17f088ad,  0x66c920ac,  0xb47dce3a,
976     0x1863df4a, 0x82e51a31,  0x60975133,  0x4562537f,
977     0xe0b16477, 0x84bb6bae,  0x1cfe81a0,  0x94f9082b,
978     0x58704868, 0x198f45fd,  0x8794de6c,  0xb7527bf8,
979     0x23ab73d3, 0xe2724b02,  0x57e31f8f,  0x2a6655ab,
980     0x7b2eb28,  0x32fb5c2,   0x9a86c57b,  0xa5d33708,
981     0xf2302887, 0xb223bfa5,  0xba02036a,  0x5ced1682,
982     0x2b8acf1c, 0x92a779b4,  0xf0f307f2,  0xa14e69e2,
983     0xcd65daf4, 0xd50605be,  0x1fd13462,  0x8ac4a6fe,
984     0x9d342e53, 0xa0a2f355,  0x32058ae1,  0x75a4f6eb,
985     0x390b83ec, 0xaa4060ef,  0x65e719f,   0x51bd6e10,
986     0xf93e218a, 0x3d96dd06,  0xaedd3e05,  0x464de6bd,
987     0xb591548d, 0x571c45d,   0x6f0406d4,  0xff605015,
988     0x241998fb, 0x97d6bde9,  0xcc894043,  0x7767d99e,
989     0xbdb0e842, 0x8807898b,  0x38e7195b,  0xdb79c8ee,
990     0x47a17c0a, 0xe97c420f,  0xc9f8841e,  0x0,
991     0x83098086, 0x48322bed,  0xac1e1170,  0x4e6c5a72,
992     0xfbfd0eff, 0x560f8538,  0x1e3daed5,  0x27362d39,
993     0x640a0fd9, 0x21685ca6,  0xd19b5b54,  0x3a24362e,
994     0xb10c0a67, 0xf9357e7,   0xd2b4ee96,  0x9e1b9b91,
995     0x4f80c0c5, 0xa261dc20,  0x695a774b,  0x161c121a,
996     0xae293ba,  0xe5c0a02a,  0x433c22e0,  0x1d121b17,
997     0xb0e090d,  0xadf28bc7,  0xb92db6a8,  0xc8141ea9,
998     0x8557f119, 0x4caf7507,  0xbbee99dd,  0xfda37f60,
999     0x9ff70126, 0xbc5c72f5,  0xc544663b,  0x345bfb7e,
1000     0x768b4329, 0xdccb23c6,  0x68b6edfc,  0x63b8e4f1,
1001     0xcad731dc, 0x10426385,  0x40139722,  0x2084c611,
1002     0x7d854a24, 0xf8d2bb3d,  0x11aef932,  0x6dc729a1,
1003     0x4b1d9e2f, 0xf3dcb230,  0xec0d8652,  0xd077c1e3,
1004     0x6c2bb316, 0x99a970b9,  0xfa119448,  0x2247e964,
1005     0xc4a8fc8c, 0x1aa0f03f,  0xd8567d2c,  0xef223390,
1006     0xc787494e, 0xc1d938d1,  0xfe8ccaa2,  0x3698d40b,
1007     0xcfa6f581, 0x28a57ade,  0x26dab78e,  0xa43fadbf,
1008     0xe42c3a9d, 0xd507892,   0x9b6a5fcc,  0x62547e46,
1009     0xc2f68d13, 0xe890d8b8,  0x5e2e39f7,  0xf582c3af,
1010     0xbe9f5d80, 0x7c69d093,  0xa96fd52d,  0xb3cf2512,
1011     0x3bc8ac99, 0xa710187d,  0x6ee89c63,  0x7bdb3bbb,
1012     0x9cd2678,  0xf46e5918,  0x1ec9ab7,   0xa8834f9a,
1013     0x65e6956e, 0x7eaaffe6,  0x821bccf,   0xe6ef15e8,
1014     0xd9bae79b, 0xce4a6f36,  0xd4ea9f09,  0xd629b07c,
1015     0xaf31a4b2, 0x312a3f23,  0x30c6a594,  0xc035a266,
1016     0x37744ebc, 0xa6fc82ca,  0xb0e090d0,  0x1533a7d8,
1017     0x4af10498, 0xf741ecda,  0xe7fcd50,   0x2f1791f6,
1018     0x8d764dd6, 0x4d43efb0,  0x54ccaa4d,  0xdfe49604,
1019     0xe39ed1b5, 0x1b4c6a88,  0xb8c12c1f,  0x7f466551,
1020     0x49d5eea,  0x5d018c35,  0x73fa8774,  0x2efb0b41,
1021     0x5ab3671d, 0x5292dbd2,  0x33e91056,  0x136dd647,
1022     0x8c9ad761, 0x7a37a10c,  0x8e59f814,  0x89eb133c,
1023     0xeecea927, 0x35b761c9,  0xede11ce5,  0x3c7a47b1,
1024     0x599cd2df, 0x3f55f273,  0x791814ce,  0xbf73c737,
1025     0xea53f7cd, 0x5b5ffdaa,  0x14df3d6f,  0x867844db,
1026     0x81caaff3, 0x3eb968c4,  0x2c382434,  0x5fc2a340,
1027     0x72161dc3, 0xcbce225,   0x8b283c49,  0x41ff0d95,
1028     0x7139a801, 0xde080cb3,  0x9cd8b4e4,  0x906456c1,
1029     0x617bcb84, 0x70d532b6,  0x74486c5c,  0x42d0b857
1030 };
1031 /* clang-format on */
1032 
1033 /* clang-format off */
1034 static const uint32_t U2[256] = {
1035     0xa75051f4, 0x65537e41,  0xa4c31a17,  0x5e963a27,
1036     0x6bcb3bab, 0x45f11f9d,  0x58abacfa,  0x3934be3,
1037     0xfa552030, 0x6df6ad76,  0x769188cc,  0x4c25f502,
1038     0xd7fc4fe5, 0xcbd7c52a,  0x44802635,  0xa38fb562,
1039     0x5a49deb1, 0x1b6725ba,  0xe9845ea,   0xc0e15dfe,
1040     0x7502c32f, 0xf012814c,  0x97a38d46,  0xf9c66bd3,
1041     0x5fe7038f, 0x9c951592,  0x7aebbf6d,  0x59da9552,
1042     0x832dd4be, 0x21d35874,  0x692949e0,  0xc8448ec9,
1043     0x896a75c2, 0x7978f48e,  0x3e6b9958,  0x71dd27b9,
1044     0x4fb6bee1, 0xad17f088,  0xac66c920,  0x3ab47dce,
1045     0x4a1863df, 0x3182e51a,  0x33609751,  0x7f456253,
1046     0x77e0b164, 0xae84bb6b,  0xa01cfe81,  0x2b94f908,
1047     0x68587048, 0xfd198f45,  0x6c8794de,  0xf8b7527b,
1048     0xd323ab73, 0x2e2724b,   0x8f57e31f,  0xab2a6655,
1049     0x2807b2eb, 0xc2032fb5,  0x7b9a86c5,  0x8a5d337,
1050     0x87f23028, 0xa5b223bf,  0x6aba0203,  0x825ced16,
1051     0x1c2b8acf, 0xb492a779,  0xf2f0f307,  0xe2a14e69,
1052     0xf4cd65da, 0xbed50605,  0x621fd134,  0xfe8ac4a6,
1053     0x539d342e, 0x55a0a2f3,  0xe132058a,  0xeb75a4f6,
1054     0xec390b83, 0xefaa4060,  0x9f065e71,  0x1051bd6e,
1055     0x8af93e21, 0x63d96dd,   0x5aedd3e,   0xbd464de6,
1056     0x8db59154, 0x5d0571c4,  0xd46f0406,  0x15ff6050,
1057     0xfb241998, 0xe997d6bd,  0x43cc8940,  0x9e7767d9,
1058     0x42bdb0e8, 0x8b880789,  0x5b38e719,  0xeedb79c8,
1059     0xa47a17c,  0xfe97c42,   0x1ec9f884,  0x0,
1060     0x86830980, 0xed48322b,  0x70ac1e11,  0x724e6c5a,
1061     0xfffbfd0e, 0x38560f85,  0xd51e3dae,  0x3927362d,
1062     0xd9640a0f, 0xa621685c,  0x54d19b5b,  0x2e3a2436,
1063     0x67b10c0a, 0xe70f9357,  0x96d2b4ee,  0x919e1b9b,
1064     0xc54f80c0, 0x20a261dc,  0x4b695a77,  0x1a161c12,
1065     0xba0ae293, 0x2ae5c0a0,  0xe0433c22,  0x171d121b,
1066     0xd0b0e09,  0xc7adf28b,  0xa8b92db6,  0xa9c8141e,
1067     0x198557f1, 0x74caf75,   0xddbbee99,  0x60fda37f,
1068     0x269ff701, 0xf5bc5c72,  0x3bc54466,  0x7e345bfb,
1069     0x29768b43, 0xc6dccb23,  0xfc68b6ed,  0xf163b8e4,
1070     0xdccad731, 0x85104263,  0x22401397,  0x112084c6,
1071     0x247d854a, 0x3df8d2bb,  0x3211aef9,  0xa16dc729,
1072     0x2f4b1d9e, 0x30f3dcb2,  0x52ec0d86,  0xe3d077c1,
1073     0x166c2bb3, 0xb999a970,  0x48fa1194,  0x642247e9,
1074     0x8cc4a8fc, 0x3f1aa0f0,  0x2cd8567d,  0x90ef2233,
1075     0x4ec78749, 0xd1c1d938,  0xa2fe8cca,  0xb3698d4,
1076     0x81cfa6f5, 0xde28a57a,  0x8e26dab7,  0xbfa43fad,
1077     0x9de42c3a, 0x920d5078,  0xcc9b6a5f,  0x4662547e,
1078     0x13c2f68d, 0xb8e890d8,  0xf75e2e39,  0xaff582c3,
1079     0x80be9f5d, 0x937c69d0,  0x2da96fd5,  0x12b3cf25,
1080     0x993bc8ac, 0x7da71018,  0x636ee89c,  0xbb7bdb3b,
1081     0x7809cd26, 0x18f46e59,  0xb701ec9a,  0x9aa8834f,
1082     0x6e65e695, 0xe67eaaff,  0xcf0821bc,  0xe8e6ef15,
1083     0x9bd9bae7, 0x36ce4a6f,  0x9d4ea9f,   0x7cd629b0,
1084     0xb2af31a4, 0x23312a3f,  0x9430c6a5,  0x66c035a2,
1085     0xbc37744e, 0xcaa6fc82,  0xd0b0e090,  0xd81533a7,
1086     0x984af104, 0xdaf741ec,  0x500e7fcd,  0xf62f1791,
1087     0xd68d764d, 0xb04d43ef,  0x4d54ccaa,  0x4dfe496,
1088     0xb5e39ed1, 0x881b4c6a,  0x1fb8c12c,  0x517f4665,
1089     0xea049d5e, 0x355d018c,  0x7473fa87,  0x412efb0b,
1090     0x1d5ab367, 0xd25292db,  0x5633e910,  0x47136dd6,
1091     0x618c9ad7, 0xc7a37a1,   0x148e59f8,  0x3c89eb13,
1092     0x27eecea9, 0xc935b761,  0xe5ede11c,  0xb13c7a47,
1093     0xdf599cd2, 0x733f55f2,  0xce791814,  0x37bf73c7,
1094     0xcdea53f7, 0xaa5b5ffd,  0x6f14df3d,  0xdb867844,
1095     0xf381caaf, 0xc43eb968,  0x342c3824,  0x405fc2a3,
1096     0xc372161d, 0x250cbce2,  0x498b283c,  0x9541ff0d,
1097     0x17139a8,  0xb3de080c,  0xe49cd8b4,  0xc1906456,
1098     0x84617bcb, 0xb670d532,  0x5c74486c,  0x5742d0b8
1099 };
1100 /* clang-format on */
1101 
1102 /* clang-format off */
1103 static const uint32_t U3[256] = {
1104     0xf4a75051, 0x4165537e,  0x17a4c31a,  0x275e963a,
1105     0xab6bcb3b, 0x9d45f11f,  0xfa58abac,  0xe303934b,
1106     0x30fa5520, 0x766df6ad,  0xcc769188,  0x24c25f5,
1107     0xe5d7fc4f, 0x2acbd7c5,  0x35448026,  0x62a38fb5,
1108     0xb15a49de, 0xba1b6725,  0xea0e9845,  0xfec0e15d,
1109     0x2f7502c3, 0x4cf01281,  0x4697a38d,  0xd3f9c66b,
1110     0x8f5fe703, 0x929c9515,  0x6d7aebbf,  0x5259da95,
1111     0xbe832dd4, 0x7421d358,  0xe0692949,  0xc9c8448e,
1112     0xc2896a75, 0x8e7978f4,  0x583e6b99,  0xb971dd27,
1113     0xe14fb6be, 0x88ad17f0,  0x20ac66c9,  0xce3ab47d,
1114     0xdf4a1863, 0x1a3182e5,  0x51336097,  0x537f4562,
1115     0x6477e0b1, 0x6bae84bb,  0x81a01cfe,  0x82b94f9,
1116     0x48685870, 0x45fd198f,  0xde6c8794,  0x7bf8b752,
1117     0x73d323ab, 0x4b02e272,  0x1f8f57e3,  0x55ab2a66,
1118     0xeb2807b2, 0xb5c2032f,  0xc57b9a86,  0x3708a5d3,
1119     0x2887f230, 0xbfa5b223,  0x36aba02,   0x16825ced,
1120     0xcf1c2b8a, 0x79b492a7,  0x7f2f0f3,   0x69e2a14e,
1121     0xdaf4cd65, 0x5bed506,   0x34621fd1,  0xa6fe8ac4,
1122     0x2e539d34, 0xf355a0a2,  0x8ae13205,  0xf6eb75a4,
1123     0x83ec390b, 0x60efaa40,  0x719f065e,  0x6e1051bd,
1124     0x218af93e, 0xdd063d96,  0x3e05aedd,  0xe6bd464d,
1125     0x548db591, 0xc45d0571,  0x6d46f04,   0x5015ff60,
1126     0x98fb2419, 0xbde997d6,  0x4043cc89,  0xd99e7767,
1127     0xe842bdb0, 0x898b8807,  0x195b38e7,  0xc8eedb79,
1128     0x7c0a47a1, 0x420fe97c,  0x841ec9f8,  0x0,
1129     0x80868309, 0x2bed4832,  0x1170ac1e,  0x5a724e6c,
1130     0xefffbfd,  0x8538560f,  0xaed51e3d,  0x2d392736,
1131     0xfd9640a,  0x5ca62168,  0x5b54d19b,  0x362e3a24,
1132     0xa67b10c,  0x57e70f93,  0xee96d2b4,  0x9b919e1b,
1133     0xc0c54f80, 0xdc20a261,  0x774b695a,  0x121a161c,
1134     0x93ba0ae2, 0xa02ae5c0,  0x22e0433c,  0x1b171d12,
1135     0x90d0b0e,  0x8bc7adf2,  0xb6a8b92d,  0x1ea9c814,
1136     0xf1198557, 0x75074caf,  0x99ddbbee,  0x7f60fda3,
1137     0x1269ff7,  0x72f5bc5c,  0x663bc544,  0xfb7e345b,
1138     0x4329768b, 0x23c6dccb,  0xedfc68b6,  0xe4f163b8,
1139     0x31dccad7, 0x63851042,  0x97224013,  0xc6112084,
1140     0x4a247d85, 0xbb3df8d2,  0xf93211ae,  0x29a16dc7,
1141     0x9e2f4b1d, 0xb230f3dc,  0x8652ec0d,  0xc1e3d077,
1142     0xb3166c2b, 0x70b999a9,  0x9448fa11,  0xe9642247,
1143     0xfc8cc4a8, 0xf03f1aa0,  0x7d2cd856,  0x3390ef22,
1144     0x494ec787, 0x38d1c1d9,  0xcaa2fe8c,  0xd40b3698,
1145     0xf581cfa6, 0x7ade28a5,  0xb78e26da,  0xadbfa43f,
1146     0x3a9de42c, 0x78920d50,  0x5fcc9b6a,  0x7e466254,
1147     0x8d13c2f6, 0xd8b8e890,  0x39f75e2e,  0xc3aff582,
1148     0x5d80be9f, 0xd0937c69,  0xd52da96f,  0x2512b3cf,
1149     0xac993bc8, 0x187da710,  0x9c636ee8,  0x3bbb7bdb,
1150     0x267809cd, 0x5918f46e,  0x9ab701ec,  0x4f9aa883,
1151     0x956e65e6, 0xffe67eaa,  0xbccf0821,  0x15e8e6ef,
1152     0xe79bd9ba, 0x6f36ce4a,  0x9f09d4ea,  0xb07cd629,
1153     0xa4b2af31, 0x3f23312a,  0xa59430c6,  0xa266c035,
1154     0x4ebc3774, 0x82caa6fc,  0x90d0b0e0,  0xa7d81533,
1155     0x4984af1,  0xecdaf741,  0xcd500e7f,  0x91f62f17,
1156     0x4dd68d76, 0xefb04d43,  0xaa4d54cc,  0x9604dfe4,
1157     0xd1b5e39e, 0x6a881b4c,  0x2c1fb8c1,  0x65517f46,
1158     0x5eea049d, 0x8c355d01,  0x877473fa,  0xb412efb,
1159     0x671d5ab3, 0xdbd25292,  0x105633e9,  0xd647136d,
1160     0xd7618c9a, 0xa10c7a37,  0xf8148e59,  0x133c89eb,
1161     0xa927eece, 0x61c935b7,  0x1ce5ede1,  0x47b13c7a,
1162     0xd2df599c, 0xf2733f55,  0x14ce7918,  0xc737bf73,
1163     0xf7cdea53, 0xfdaa5b5f,  0x3d6f14df,  0x44db8678,
1164     0xaff381ca, 0x68c43eb9,  0x24342c38,  0xa3405fc2,
1165     0x1dc37216, 0xe2250cbc,  0x3c498b28,  0xd9541ff,
1166     0xa8017139, 0xcb3de08,   0xb4e49cd8,  0x56c19064,
1167     0xcb84617b, 0x32b670d5,  0x6c5c7448,  0xb85742d0
1168 };
1169 /* clang-format on */
1170 #endif
1171 
1172 /*
1173  * the following tables (aes_sbox, aes_inv_sbox, T4, U4) are
1174  * endian-neutral
1175  */
1176 /* clang-format off */
1177 static const uint8_t aes_sbox[256] = {
1178     0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
1179     0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
1180     0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
1181     0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
1182     0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
1183     0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
1184     0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
1185     0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
1186     0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
1187     0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
1188     0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
1189     0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
1190     0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
1191     0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
1192     0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
1193     0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
1194     0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
1195     0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
1196     0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
1197     0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
1198     0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
1199     0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
1200     0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
1201     0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
1202     0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
1203     0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
1204     0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
1205     0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
1206     0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
1207     0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
1208     0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
1209     0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
1210 };
1211 /* clang-format on */
1212 
1213 #ifndef CPU_RISC
1214 /* clang-format off */
1215 static const uint8_t aes_inv_sbox[256] = {
1216     0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
1217     0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
1218     0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
1219     0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
1220     0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
1221     0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
1222     0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
1223     0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
1224     0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
1225     0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
1226     0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
1227     0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
1228     0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
1229     0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
1230     0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
1231     0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
1232     0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
1233     0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
1234     0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
1235     0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
1236     0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
1237     0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
1238     0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
1239     0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
1240     0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
1241     0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
1242     0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
1243     0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
1244     0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
1245     0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
1246     0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
1247     0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
1248 };
1249 /* clang-format on */
1250 #endif /* ! CPU_RISC */
1251 
1252 #ifdef CPU_RISC
1253 /* clang-format off */
1254 static const uint32_t T4[256] = {
1255     0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
1256     0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
1257     0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
1258     0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
1259     0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
1260     0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
1261     0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
1262     0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
1263     0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
1264     0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
1265     0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
1266     0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
1267     0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
1268     0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
1269     0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
1270     0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
1271     0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
1272     0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
1273     0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
1274     0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
1275     0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
1276     0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
1277     0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
1278     0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
1279     0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
1280     0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
1281     0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
1282     0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
1283     0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
1284     0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
1285     0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
1286     0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
1287     0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
1288     0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
1289     0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
1290     0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
1291     0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
1292     0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
1293     0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
1294     0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
1295     0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
1296     0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
1297     0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
1298     0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
1299     0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
1300     0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
1301     0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
1302     0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
1303     0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
1304     0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
1305     0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
1306     0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
1307     0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
1308     0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
1309     0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
1310     0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
1311     0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
1312     0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
1313     0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
1314     0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
1315     0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
1316     0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
1317     0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
1318     0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
1319 };
1320 /* clang-format on */
1321 
1322 /* clang-format off */
1323 static const uint32_t U4[256] = {
1324     0x52525252, 0x9090909,   0x6a6a6a6a,  0xd5d5d5d5,
1325     0x30303030, 0x36363636,  0xa5a5a5a5,  0x38383838,
1326     0xbfbfbfbf, 0x40404040,  0xa3a3a3a3,  0x9e9e9e9e,
1327     0x81818181, 0xf3f3f3f3,  0xd7d7d7d7,  0xfbfbfbfb,
1328     0x7c7c7c7c, 0xe3e3e3e3,  0x39393939,  0x82828282,
1329     0x9b9b9b9b, 0x2f2f2f2f,  0xffffffff,  0x87878787,
1330     0x34343434, 0x8e8e8e8e,  0x43434343,  0x44444444,
1331     0xc4c4c4c4, 0xdededede,  0xe9e9e9e9,  0xcbcbcbcb,
1332     0x54545454, 0x7b7b7b7b,  0x94949494,  0x32323232,
1333     0xa6a6a6a6, 0xc2c2c2c2,  0x23232323,  0x3d3d3d3d,
1334     0xeeeeeeee, 0x4c4c4c4c,  0x95959595,  0xb0b0b0b,
1335     0x42424242, 0xfafafafa,  0xc3c3c3c3,  0x4e4e4e4e,
1336     0x8080808,  0x2e2e2e2e,  0xa1a1a1a1,  0x66666666,
1337     0x28282828, 0xd9d9d9d9,  0x24242424,  0xb2b2b2b2,
1338     0x76767676, 0x5b5b5b5b,  0xa2a2a2a2,  0x49494949,
1339     0x6d6d6d6d, 0x8b8b8b8b,  0xd1d1d1d1,  0x25252525,
1340     0x72727272, 0xf8f8f8f8,  0xf6f6f6f6,  0x64646464,
1341     0x86868686, 0x68686868,  0x98989898,  0x16161616,
1342     0xd4d4d4d4, 0xa4a4a4a4,  0x5c5c5c5c,  0xcccccccc,
1343     0x5d5d5d5d, 0x65656565,  0xb6b6b6b6,  0x92929292,
1344     0x6c6c6c6c, 0x70707070,  0x48484848,  0x50505050,
1345     0xfdfdfdfd, 0xedededed,  0xb9b9b9b9,  0xdadadada,
1346     0x5e5e5e5e, 0x15151515,  0x46464646,  0x57575757,
1347     0xa7a7a7a7, 0x8d8d8d8d,  0x9d9d9d9d,  0x84848484,
1348     0x90909090, 0xd8d8d8d8,  0xabababab,  0x0,
1349     0x8c8c8c8c, 0xbcbcbcbc,  0xd3d3d3d3,  0xa0a0a0a,
1350     0xf7f7f7f7, 0xe4e4e4e4,  0x58585858,  0x5050505,
1351     0xb8b8b8b8, 0xb3b3b3b3,  0x45454545,  0x6060606,
1352     0xd0d0d0d0, 0x2c2c2c2c,  0x1e1e1e1e,  0x8f8f8f8f,
1353     0xcacacaca, 0x3f3f3f3f,  0xf0f0f0f,   0x2020202,
1354     0xc1c1c1c1, 0xafafafaf,  0xbdbdbdbd,  0x3030303,
1355     0x1010101,  0x13131313,  0x8a8a8a8a,  0x6b6b6b6b,
1356     0x3a3a3a3a, 0x91919191,  0x11111111,  0x41414141,
1357     0x4f4f4f4f, 0x67676767,  0xdcdcdcdc,  0xeaeaeaea,
1358     0x97979797, 0xf2f2f2f2,  0xcfcfcfcf,  0xcececece,
1359     0xf0f0f0f0, 0xb4b4b4b4,  0xe6e6e6e6,  0x73737373,
1360     0x96969696, 0xacacacac,  0x74747474,  0x22222222,
1361     0xe7e7e7e7, 0xadadadad,  0x35353535,  0x85858585,
1362     0xe2e2e2e2, 0xf9f9f9f9,  0x37373737,  0xe8e8e8e8,
1363     0x1c1c1c1c, 0x75757575,  0xdfdfdfdf,  0x6e6e6e6e,
1364     0x47474747, 0xf1f1f1f1,  0x1a1a1a1a,  0x71717171,
1365     0x1d1d1d1d, 0x29292929,  0xc5c5c5c5,  0x89898989,
1366     0x6f6f6f6f, 0xb7b7b7b7,  0x62626262,  0xe0e0e0e,
1367     0xaaaaaaaa, 0x18181818,  0xbebebebe,  0x1b1b1b1b,
1368     0xfcfcfcfc, 0x56565656,  0x3e3e3e3e,  0x4b4b4b4b,
1369     0xc6c6c6c6, 0xd2d2d2d2,  0x79797979,  0x20202020,
1370     0x9a9a9a9a, 0xdbdbdbdb,  0xc0c0c0c0,  0xfefefefe,
1371     0x78787878, 0xcdcdcdcd,  0x5a5a5a5a,  0xf4f4f4f4,
1372     0x1f1f1f1f, 0xdddddddd,  0xa8a8a8a8,  0x33333333,
1373     0x88888888, 0x7070707,   0xc7c7c7c7,  0x31313131,
1374     0xb1b1b1b1, 0x12121212,  0x10101010,  0x59595959,
1375     0x27272727, 0x80808080,  0xecececec,  0x5f5f5f5f,
1376     0x60606060, 0x51515151,  0x7f7f7f7f,  0xa9a9a9a9,
1377     0x19191919, 0xb5b5b5b5,  0x4a4a4a4a,  0xd0d0d0d,
1378     0x2d2d2d2d, 0xe5e5e5e5,  0x7a7a7a7a,  0x9f9f9f9f,
1379     0x93939393, 0xc9c9c9c9,  0x9c9c9c9c,  0xefefefef,
1380     0xa0a0a0a0, 0xe0e0e0e0,  0x3b3b3b3b,  0x4d4d4d4d,
1381     0xaeaeaeae, 0x2a2a2a2a,  0xf5f5f5f5,  0xb0b0b0b0,
1382     0xc8c8c8c8, 0xebebebeb,  0xbbbbbbbb,  0x3c3c3c3c,
1383     0x83838383, 0x53535353,  0x99999999,  0x61616161,
1384     0x17171717, 0x2b2b2b2b,  0x4040404,   0x7e7e7e7e,
1385     0xbabababa, 0x77777777,  0xd6d6d6d6,  0x26262626,
1386     0xe1e1e1e1, 0x69696969,  0x14141414,  0x63636363,
1387     0x55555555, 0x21212121,  0xc0c0c0c,   0x7d7d7d7d
1388 };
1389 /* clang-format on */
1390 #endif /* CPU_RISC */
1391 
1392 #define gf2_8_field_polynomial 0x1B
1393 /*
1394  * gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x'
1395  * operation, using the field representation from AES; that is, the
1396  * next gf2_8 value in the cyclic representation of that field.  The
1397  * value z should be an uint8_t.
1398  */
1399 #define gf2_8_shift(z)                                                         \
1400     (((z)&128) ? (((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1))
1401 
1402 /* aes internals */
1403 
aes_128_expand_encryption_key(const uint8_t * key,srtp_aes_expanded_key_t * expanded_key)1404 static void aes_128_expand_encryption_key(const uint8_t *key,
1405                                           srtp_aes_expanded_key_t *expanded_key)
1406 {
1407     int i;
1408     uint8_t rc;
1409 
1410     /* initialize round constant */
1411     rc = 1;
1412 
1413     expanded_key->num_rounds = 10;
1414 
1415     v128_copy_octet_string(&expanded_key->round[0], key);
1416 
1417     /* loop over round keys */
1418     for (i = 1; i < 11; i++) {
1419         /* munge first word of round key */
1420         expanded_key->round[i].v8[0] =
1421             aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
1422         expanded_key->round[i].v8[1] =
1423             aes_sbox[expanded_key->round[i - 1].v8[14]];
1424         expanded_key->round[i].v8[2] =
1425             aes_sbox[expanded_key->round[i - 1].v8[15]];
1426         expanded_key->round[i].v8[3] =
1427             aes_sbox[expanded_key->round[i - 1].v8[12]];
1428 
1429         expanded_key->round[i].v32[0] ^= expanded_key->round[i - 1].v32[0];
1430 
1431         /* set remaining 32 bit words to the exor of the one previous with
1432          * the one four words previous */
1433 
1434         expanded_key->round[i].v32[1] =
1435             expanded_key->round[i].v32[0] ^ expanded_key->round[i - 1].v32[1];
1436 
1437         expanded_key->round[i].v32[2] =
1438             expanded_key->round[i].v32[1] ^ expanded_key->round[i - 1].v32[2];
1439 
1440         expanded_key->round[i].v32[3] =
1441             expanded_key->round[i].v32[2] ^ expanded_key->round[i - 1].v32[3];
1442 
1443         /* modify round constant */
1444         rc = gf2_8_shift(rc);
1445     }
1446 }
1447 
aes_256_expand_encryption_key(const unsigned char * key,srtp_aes_expanded_key_t * expanded_key)1448 static void aes_256_expand_encryption_key(const unsigned char *key,
1449                                           srtp_aes_expanded_key_t *expanded_key)
1450 {
1451     int i;
1452     uint8_t rc;
1453 
1454     /* initialize round constant */
1455     rc = 1;
1456 
1457     expanded_key->num_rounds = 14;
1458 
1459     v128_copy_octet_string(&expanded_key->round[0], key);
1460     v128_copy_octet_string(&expanded_key->round[1], key + 16);
1461 
1462     /* loop over rest of round keys */
1463     for (i = 2; i < 15; i++) {
1464         /* munge first word of round key */
1465         if ((i & 1) == 0) {
1466             expanded_key->round[i].v8[0] =
1467                 aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
1468             expanded_key->round[i].v8[1] =
1469                 aes_sbox[expanded_key->round[i - 1].v8[14]];
1470             expanded_key->round[i].v8[2] =
1471                 aes_sbox[expanded_key->round[i - 1].v8[15]];
1472             expanded_key->round[i].v8[3] =
1473                 aes_sbox[expanded_key->round[i - 1].v8[12]];
1474 
1475             /* modify round constant */
1476             rc = gf2_8_shift(rc);
1477         } else {
1478             expanded_key->round[i].v8[0] =
1479                 aes_sbox[expanded_key->round[i - 1].v8[12]];
1480             expanded_key->round[i].v8[1] =
1481                 aes_sbox[expanded_key->round[i - 1].v8[13]];
1482             expanded_key->round[i].v8[2] =
1483                 aes_sbox[expanded_key->round[i - 1].v8[14]];
1484             expanded_key->round[i].v8[3] =
1485                 aes_sbox[expanded_key->round[i - 1].v8[15]];
1486         }
1487 
1488         expanded_key->round[i].v32[0] ^= expanded_key->round[i - 2].v32[0];
1489 
1490         /* set remaining 32 bit words to the exor of the one previous with
1491          * the one eight words previous */
1492 
1493         expanded_key->round[i].v32[1] =
1494             expanded_key->round[i].v32[0] ^ expanded_key->round[i - 2].v32[1];
1495 
1496         expanded_key->round[i].v32[2] =
1497             expanded_key->round[i].v32[1] ^ expanded_key->round[i - 2].v32[2];
1498 
1499         expanded_key->round[i].v32[3] =
1500             expanded_key->round[i].v32[2] ^ expanded_key->round[i - 2].v32[3];
1501     }
1502 }
1503 
srtp_aes_expand_encryption_key(const uint8_t * key,int key_len,srtp_aes_expanded_key_t * expanded_key)1504 srtp_err_status_t srtp_aes_expand_encryption_key(
1505     const uint8_t *key,
1506     int key_len,
1507     srtp_aes_expanded_key_t *expanded_key)
1508 {
1509     if (key_len == 16) {
1510         aes_128_expand_encryption_key(key, expanded_key);
1511         return srtp_err_status_ok;
1512     } else if (key_len == 24) {
1513         /* AES-192 not yet supported */
1514         return srtp_err_status_bad_param;
1515     } else if (key_len == 32) {
1516         aes_256_expand_encryption_key(key, expanded_key);
1517         return srtp_err_status_ok;
1518     } else {
1519         return srtp_err_status_bad_param;
1520     }
1521 }
1522 
srtp_aes_expand_decryption_key(const uint8_t * key,int key_len,srtp_aes_expanded_key_t * expanded_key)1523 srtp_err_status_t srtp_aes_expand_decryption_key(
1524     const uint8_t *key,
1525     int key_len,
1526     srtp_aes_expanded_key_t *expanded_key)
1527 {
1528     int i;
1529     srtp_err_status_t status;
1530     int num_rounds = expanded_key->num_rounds;
1531 
1532     status = srtp_aes_expand_encryption_key(key, key_len, expanded_key);
1533     if (status) {
1534         return status;
1535     }
1536 
1537     /* invert the order of the round keys */
1538     for (i = 0; i < num_rounds / 2; i++) {
1539         v128_t tmp;
1540         v128_copy(&tmp, &expanded_key->round[num_rounds - i]);
1541         v128_copy(&expanded_key->round[num_rounds - i],
1542                   &expanded_key->round[i]);
1543         v128_copy(&expanded_key->round[i], &tmp);
1544     }
1545 
1546     /*
1547      * apply the inverse mixColumn transform to the round keys (except
1548      * for the first and the last)
1549      *
1550      * mixColumn is implemented by using the tables U0, U1, U2, U3,
1551      * followed by the T4 table (which cancels out the use of the sbox
1552      * in the U-tables)
1553      */
1554     for (i = 1; i < num_rounds; i++) {
1555 #ifdef CPU_RISC
1556         uint32_t tmp;
1557 
1558 #ifdef WORDS_BIGENDIAN
1559         /* clang-format off */
1560         tmp = expanded_key->round[i].v32[0];
1561         expanded_key->round[i].v32[0] =
1562             U0[T4[(tmp >> 24)       ] & 0xff] ^
1563             U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
1564             U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1565             U3[T4[(tmp)       & 0xff] & 0xff];
1566 
1567         tmp = expanded_key->round[i].v32[1];
1568         expanded_key->round[i].v32[1] =
1569             U0[T4[(tmp >> 24)       ] & 0xff] ^
1570             U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
1571             U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1572             U3[T4[(tmp)       & 0xff] & 0xff];
1573 
1574         tmp = expanded_key->round[i].v32[2];
1575         expanded_key->round[i].v32[2] =
1576             U0[T4[(tmp >> 24)       ] & 0xff] ^
1577             U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
1578             U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1579             U3[T4[(tmp)       & 0xff] & 0xff];
1580 
1581         tmp = expanded_key->round[i].v32[3];
1582         expanded_key->round[i].v32[3] =
1583             U0[T4[(tmp >> 24)       ] & 0xff] ^
1584             U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
1585             U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1586             U3[T4[(tmp)       & 0xff] & 0xff];
1587 #else
1588         tmp = expanded_key->round[i].v32[0];
1589         expanded_key->round[i].v32[0] =
1590             U3[T4[(tmp >> 24)       ] & 0xff] ^
1591             U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
1592             U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1593             U0[T4[(tmp)       & 0xff] & 0xff];
1594 
1595         tmp = expanded_key->round[i].v32[1];
1596         expanded_key->round[i].v32[1] =
1597             U3[T4[(tmp >> 24)       ] & 0xff] ^
1598             U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
1599             U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1600             U0[T4[(tmp)       & 0xff] & 0xff];
1601 
1602         tmp = expanded_key->round[i].v32[2];
1603         expanded_key->round[i].v32[2] =
1604             U3[T4[(tmp >> 24)       ] & 0xff] ^
1605             U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
1606             U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1607             U0[T4[(tmp)       & 0xff] & 0xff];
1608 
1609         tmp = expanded_key->round[i].v32[3];
1610         expanded_key->round[i].v32[3] =
1611             U3[T4[(tmp >> 24)       ] & 0xff] ^
1612             U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
1613             U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
1614             U0[T4[(tmp)       & 0xff] & 0xff];
1615 /* clang-format on */
1616 #endif /* WORDS_BIGENDIAN */
1617 
1618 #else /* assume CPU_CISC */
1619 
1620         uint32_t c0, c1, c2, c3;
1621 
1622         c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]] ^
1623              U1[aes_sbox[expanded_key->round[i].v8[1]]] ^
1624              U2[aes_sbox[expanded_key->round[i].v8[2]]] ^
1625              U3[aes_sbox[expanded_key->round[i].v8[3]]];
1626 
1627         c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]] ^
1628              U1[aes_sbox[expanded_key->round[i].v8[5]]] ^
1629              U2[aes_sbox[expanded_key->round[i].v8[6]]] ^
1630              U3[aes_sbox[expanded_key->round[i].v8[7]]];
1631 
1632         c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]] ^
1633              U1[aes_sbox[expanded_key->round[i].v8[9]]] ^
1634              U2[aes_sbox[expanded_key->round[i].v8[10]]] ^
1635              U3[aes_sbox[expanded_key->round[i].v8[11]]];
1636 
1637         c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]] ^
1638              U1[aes_sbox[expanded_key->round[i].v8[13]]] ^
1639              U2[aes_sbox[expanded_key->round[i].v8[14]]] ^
1640              U3[aes_sbox[expanded_key->round[i].v8[15]]];
1641 
1642         expanded_key->round[i].v32[0] = c0;
1643         expanded_key->round[i].v32[1] = c1;
1644         expanded_key->round[i].v32[2] = c2;
1645         expanded_key->round[i].v32[3] = c3;
1646 
1647 #endif
1648     }
1649 
1650     return srtp_err_status_ok;
1651 }
1652 
1653 #ifdef CPU_CISC
1654 
aes_round(v128_t * state,const v128_t * round_key)1655 static inline void aes_round(v128_t *state, const v128_t *round_key)
1656 {
1657     uint32_t column0, column1, column2, column3;
1658 
1659     /* compute the columns of the output square in terms of the octets
1660        of state, using the tables T0, T1, T2, T3 */
1661 
1662     column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
1663               T3[state->v8[15]];
1664 
1665     column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
1666               T3[state->v8[3]];
1667 
1668     column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
1669               T3[state->v8[7]];
1670 
1671     column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
1672               T3[state->v8[11]];
1673 
1674     state->v32[0] = column0 ^ round_key->v32[0];
1675     state->v32[1] = column1 ^ round_key->v32[1];
1676     state->v32[2] = column2 ^ round_key->v32[2];
1677     state->v32[3] = column3 ^ round_key->v32[3];
1678 }
1679 
aes_inv_round(v128_t * state,const v128_t * round_key)1680 static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
1681 {
1682     uint32_t column0, column1, column2, column3;
1683 
1684     /* compute the columns of the output square in terms of the octets
1685        of state, using the tables U0, U1, U2, U3 */
1686 
1687     column0 = U0[state->v8[0]] ^ U1[state->v8[13]] ^ U2[state->v8[10]] ^
1688               U3[state->v8[7]];
1689 
1690     column1 = U0[state->v8[4]] ^ U1[state->v8[1]] ^ U2[state->v8[14]] ^
1691               U3[state->v8[11]];
1692 
1693     column2 = U0[state->v8[8]] ^ U1[state->v8[5]] ^ U2[state->v8[2]] ^
1694               U3[state->v8[15]];
1695 
1696     column3 = U0[state->v8[12]] ^ U1[state->v8[9]] ^ U2[state->v8[6]] ^
1697               U3[state->v8[3]];
1698 
1699     state->v32[0] = column0 ^ round_key->v32[0];
1700     state->v32[1] = column1 ^ round_key->v32[1];
1701     state->v32[2] = column2 ^ round_key->v32[2];
1702     state->v32[3] = column3 ^ round_key->v32[3];
1703 }
1704 
aes_final_round(v128_t * state,const v128_t * round_key)1705 static inline void aes_final_round(v128_t *state, const v128_t *round_key)
1706 {
1707     uint8_t tmp;
1708 
1709     /* byte substitutions and row shifts */
1710     /* first row - no shift */
1711     state->v8[0] = aes_sbox[state->v8[0]];
1712     state->v8[4] = aes_sbox[state->v8[4]];
1713     state->v8[8] = aes_sbox[state->v8[8]];
1714     state->v8[12] = aes_sbox[state->v8[12]];
1715 
1716     /* second row - shift one left */
1717     tmp = aes_sbox[state->v8[1]];
1718     state->v8[1] = aes_sbox[state->v8[5]];
1719     state->v8[5] = aes_sbox[state->v8[9]];
1720     state->v8[9] = aes_sbox[state->v8[13]];
1721     state->v8[13] = tmp;
1722 
1723     /* third row - shift two left */
1724     tmp = aes_sbox[state->v8[10]];
1725     state->v8[10] = aes_sbox[state->v8[2]];
1726     state->v8[2] = tmp;
1727     tmp = aes_sbox[state->v8[14]];
1728     state->v8[14] = aes_sbox[state->v8[6]];
1729     state->v8[6] = tmp;
1730 
1731     /* fourth row - shift three left */
1732     tmp = aes_sbox[state->v8[15]];
1733     state->v8[15] = aes_sbox[state->v8[11]];
1734     state->v8[11] = aes_sbox[state->v8[7]];
1735     state->v8[7] = aes_sbox[state->v8[3]];
1736     state->v8[3] = tmp;
1737 
1738     v128_xor_eq(state, round_key);
1739 }
1740 
aes_inv_final_round(v128_t * state,const v128_t * round_key)1741 static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
1742 {
1743     uint8_t tmp;
1744 
1745     /* byte substitutions and row shifts */
1746     /* first row - no shift */
1747     state->v8[0] = aes_inv_sbox[state->v8[0]];
1748     state->v8[4] = aes_inv_sbox[state->v8[4]];
1749     state->v8[8] = aes_inv_sbox[state->v8[8]];
1750     state->v8[12] = aes_inv_sbox[state->v8[12]];
1751 
1752     /* second row - shift one right */
1753     tmp = aes_inv_sbox[state->v8[13]];
1754     state->v8[13] = aes_inv_sbox[state->v8[9]];
1755     state->v8[9] = aes_inv_sbox[state->v8[5]];
1756     state->v8[5] = aes_inv_sbox[state->v8[1]];
1757     state->v8[1] = tmp;
1758 
1759     /* third row - shift two right */
1760     tmp = aes_inv_sbox[state->v8[2]];
1761     state->v8[2] = aes_inv_sbox[state->v8[10]];
1762     state->v8[10] = tmp;
1763     tmp = aes_inv_sbox[state->v8[6]];
1764     state->v8[6] = aes_inv_sbox[state->v8[14]];
1765     state->v8[14] = tmp;
1766 
1767     /* fourth row - shift three right */
1768     tmp = aes_inv_sbox[state->v8[3]];
1769     state->v8[3] = aes_inv_sbox[state->v8[7]];
1770     state->v8[7] = aes_inv_sbox[state->v8[11]];
1771     state->v8[11] = aes_inv_sbox[state->v8[15]];
1772     state->v8[15] = tmp;
1773 
1774     v128_xor_eq(state, round_key);
1775 }
1776 
1777 #elif defined(CPU_RISC)
1778 
aes_round(v128_t * state,const v128_t * round_key)1779 static inline void aes_round(v128_t *state, const v128_t *round_key)
1780 {
1781     uint32_t column0, column1, column2, column3;
1782 
1783 /* compute the columns of the output square in terms of the octets
1784    of state, using the tables T0, T1, T2, T3 */
1785 #ifdef WORDS_BIGENDIAN
1786     column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] ^
1787               T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
1788 
1789     column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] ^
1790               T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
1791 
1792     column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] ^
1793               T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
1794 
1795     column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] ^
1796               T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
1797 #else
1798     column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] ^
1799               T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
1800 
1801     column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] ^
1802               T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
1803 
1804     column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff] ^
1805               T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];
1806 
1807     column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff] ^
1808               T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];
1809 #endif /* WORDS_BIGENDIAN */
1810 
1811     state->v32[0] = column0 ^ round_key->v32[0];
1812     state->v32[1] = column1 ^ round_key->v32[1];
1813     state->v32[2] = column2 ^ round_key->v32[2];
1814     state->v32[3] = column3 ^ round_key->v32[3];
1815 }
1816 
aes_inv_round(v128_t * state,const v128_t * round_key)1817 static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
1818 {
1819     uint32_t column0, column1, column2, column3;
1820 
1821 /* compute the columns of the output square in terms of the octets
1822    of state, using the tables U0, U1, U2, U3 */
1823 
1824 #ifdef WORDS_BIGENDIAN
1825     column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff] ^
1826               U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
1827 
1828     column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] ^
1829               U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
1830 
1831     column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] ^
1832               U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
1833 
1834     column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff] ^
1835               U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
1836 #else
1837     column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff] ^
1838               U2[(state->v32[2] >> 16) & 0xff] ^
1839               U3[(state->v32[1] >> 24) & 0xff];
1840 
1841     column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff] ^
1842               U2[(state->v32[3] >> 16) & 0xff] ^
1843               U3[(state->v32[2] >> 24) & 0xff];
1844 
1845     column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff] ^
1846               U2[(state->v32[0] >> 16) & 0xff] ^
1847               U3[(state->v32[3] >> 24) & 0xff];
1848 
1849     column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff] ^
1850               U2[(state->v32[1] >> 16) & 0xff] ^
1851               U3[(state->v32[0] >> 24) & 0xff];
1852 #endif /* WORDS_BIGENDIAN */
1853 
1854     state->v32[0] = column0 ^ round_key->v32[0];
1855     state->v32[1] = column1 ^ round_key->v32[1];
1856     state->v32[2] = column2 ^ round_key->v32[2];
1857     state->v32[3] = column3 ^ round_key->v32[3];
1858 }
1859 
aes_final_round(v128_t * state,const v128_t * round_key)1860 static inline void aes_final_round(v128_t *state, const v128_t *round_key)
1861 {
1862     uint32_t tmp0, tmp1, tmp2, tmp3;
1863 
1864 #ifdef WORDS_BIGENDIAN
1865     /* clang-format off */
1866     tmp0 = (T4[(state->v32[0] >> 24)]        & 0xff000000) ^
1867            (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
1868            (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
1869            (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
1870            round_key->v32[0];
1871 
1872     tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
1873            (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
1874            (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
1875            (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
1876            round_key->v32[1];
1877 
1878     tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000) ^
1879            (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
1880            (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
1881            (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
1882            round_key->v32[2];
1883 
1884     tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
1885            (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
1886            (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
1887            (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
1888            round_key->v32[3];
1889 #else
1890     tmp0 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
1891            (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
1892            (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
1893            (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
1894            round_key->v32[0];
1895 
1896     tmp1 = (T4[(state->v32[0] >> 24)]        & 0xff000000) ^
1897            (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
1898            (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
1899            (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
1900            round_key->v32[1];
1901 
1902     tmp2 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
1903            (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
1904            (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
1905            (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
1906            round_key->v32[2];
1907 
1908     tmp3 = (T4[(state->v32[2] >> 24)]        & 0xff000000) ^
1909            (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
1910            (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
1911            (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
1912            round_key->v32[3];
1913 /* clang-format on */
1914 #endif /* WORDS_BIGENDIAN */
1915 
1916     state->v32[0] = tmp0;
1917     state->v32[1] = tmp1;
1918     state->v32[2] = tmp2;
1919     state->v32[3] = tmp3;
1920 }
1921 
aes_inv_final_round(v128_t * state,const v128_t * round_key)1922 static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
1923 {
1924     uint32_t tmp0, tmp1, tmp2, tmp3;
1925 
1926 #ifdef WORDS_BIGENDIAN
1927     /* clang-format off */
1928     tmp0 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
1929            (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
1930            (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
1931            (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
1932            round_key->v32[0];
1933 
1934     tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000) ^
1935            (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
1936            (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
1937            (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
1938            round_key->v32[1];
1939 
1940     tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
1941            (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
1942            (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
1943            (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
1944            round_key->v32[2];
1945 
1946     tmp3 = (U4[(state->v32[3] >> 24)]        & 0xff000000) ^
1947            (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
1948            (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
1949            (U4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
1950            round_key->v32[3];
1951 #else
1952     tmp0 = (U4[(state->v32[1] >> 24)]        & 0xff000000) ^
1953            (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
1954            (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
1955            (U4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
1956            round_key->v32[0];
1957 
1958     tmp1 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
1959            (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
1960            (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
1961            (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
1962            round_key->v32[1];
1963 
1964     tmp2 = (U4[(state->v32[3] >> 24)]        & 0xff000000) ^
1965            (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
1966            (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
1967            (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
1968            round_key->v32[2];
1969 
1970     tmp3 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
1971            (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
1972            (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
1973            (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
1974            round_key->v32[3];
1975 /* clang-format on */
1976 #endif /* WORDS_BIGENDIAN */
1977 
1978     state->v32[0] = tmp0;
1979     state->v32[1] = tmp1;
1980     state->v32[2] = tmp2;
1981     state->v32[3] = tmp3;
1982 }
1983 
1984 #elif CPU_16 /* assume 16-bit word size on processor */
1985 
aes_round(v128_t * state,const v128_t * round_key)1986 static inline void aes_round(v128_t *state, const v128_t *round_key)
1987 {
1988     uint32_t column0, column1, column2, column3;
1989     /* compute the columns of the output square in terms of the octets
1990        of state, using the tables T0, T1, T2, T3 */
1991 
1992     column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
1993               T3[state->v8[15]];
1994 
1995     column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
1996               T3[state->v8[3]];
1997 
1998     column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
1999               T3[state->v8[7]];
2000 
2001     column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
2002               T3[state->v8[11]];
2003 
2004     state->v32[0] = column0 ^ round_key->v32[0];
2005     state->v32[1] = column1 ^ round_key->v32[1];
2006     state->v32[2] = column2 ^ round_key->v32[2];
2007     state->v32[3] = column3 ^ round_key->v32[3];
2008 }
2009 
aes_inv_round(v128_t * state,const v128_t * round_key)2010 static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
2011 {
2012     uint32_t column0, column1, column2, column3;
2013 
2014     /* compute the columns of the output square in terms of the octets
2015        of state, using the tables U0, U1, U2, U3 */
2016 
2017     column0 = U0[state->v8[0]] ^ U1[state->v8[5]] ^ U2[state->v8[10]] ^
2018               U3[state->v8[15]];
2019 
2020     column1 = U0[state->v8[4]] ^ U1[state->v8[9]] ^ U2[state->v8[14]] ^
2021               U3[state->v8[3]];
2022 
2023     column2 = U0[state->v8[8]] ^ U1[state->v8[13]] ^ U2[state->v8[2]] ^
2024               U3[state->v8[7]];
2025 
2026     column3 = U0[state->v8[12]] ^ U1[state->v8[1]] ^ U2[state->v8[6]] ^
2027               U3[state->v8[11]];
2028 
2029     state->v32[0] = column0 ^ round_key->v32[0];
2030     state->v32[1] = column1 ^ round_key->v32[1];
2031     state->v32[2] = column2 ^ round_key->v32[2];
2032     state->v32[3] = column3 ^ round_key->v32[3];
2033 }
2034 
aes_final_round(v128_t * state,const v128_t * round_key)2035 static inline void aes_final_round(v128_t *state, const v128_t *round_key)
2036 {
2037     uint8_t tmp;
2038 
2039     /* byte substitutions and row shifts */
2040     /* first row - no shift */
2041     state->v8[0] = aes_sbox[state->v8[0]];
2042     state->v8[4] = aes_sbox[state->v8[4]];
2043     state->v8[8] = aes_sbox[state->v8[8]];
2044     state->v8[12] = aes_sbox[state->v8[12]];
2045 
2046     /* second row - shift one left */
2047     tmp = aes_sbox[state->v8[1]];
2048     state->v8[1] = aes_sbox[state->v8[5]];
2049     state->v8[5] = aes_sbox[state->v8[9]];
2050     state->v8[9] = aes_sbox[state->v8[13]];
2051     state->v8[13] = tmp;
2052 
2053     /* third row - shift two left */
2054     tmp = aes_sbox[state->v8[10]];
2055     state->v8[10] = aes_sbox[state->v8[2]];
2056     state->v8[2] = tmp;
2057     tmp = aes_sbox[state->v8[14]];
2058     state->v8[14] = aes_sbox[state->v8[6]];
2059     state->v8[6] = tmp;
2060 
2061     /* fourth row - shift three left */
2062     tmp = aes_sbox[state->v8[15]];
2063     state->v8[15] = aes_sbox[state->v8[11]];
2064     state->v8[11] = aes_sbox[state->v8[7]];
2065     state->v8[7] = aes_sbox[state->v8[3]];
2066     state->v8[3] = tmp;
2067 
2068     v128_xor_eq(state, round_key);
2069 }
2070 
aes_inv_final_round(v128_t * state,const v128_t * round_key)2071 static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
2072 {
2073     uint8_t tmp;
2074 
2075     /* byte substitutions and row shifts */
2076     /* first row - no shift */
2077     state->v8[0] = aes_inv_sbox[state->v8[0]];
2078     state->v8[4] = aes_inv_sbox[state->v8[4]];
2079     state->v8[8] = aes_inv_sbox[state->v8[8]];
2080     state->v8[12] = aes_inv_sbox[state->v8[12]];
2081 
2082     /* second row - shift one left */
2083     tmp = aes_inv_sbox[state->v8[1]];
2084     state->v8[1] = aes_inv_sbox[state->v8[5]];
2085     state->v8[5] = aes_inv_sbox[state->v8[9]];
2086     state->v8[9] = aes_inv_sbox[state->v8[13]];
2087     state->v8[13] = tmp;
2088 
2089     /* third row - shift two left */
2090     tmp = aes_inv_sbox[state->v8[10]];
2091     state->v8[10] = aes_inv_sbox[state->v8[2]];
2092     state->v8[2] = tmp;
2093     tmp = aes_inv_sbox[state->v8[14]];
2094     state->v8[14] = aes_inv_sbox[state->v8[6]];
2095     state->v8[6] = tmp;
2096 
2097     /* fourth row - shift three left */
2098     tmp = aes_inv_sbox[state->v8[15]];
2099     state->v8[15] = aes_inv_sbox[state->v8[11]];
2100     state->v8[11] = aes_inv_sbox[state->v8[7]];
2101     state->v8[7] = aes_inv_sbox[state->v8[3]];
2102     state->v8[3] = tmp;
2103 
2104     v128_xor_eq(state, round_key);
2105 }
2106 
2107 #endif /* CPU type */
2108 
srtp_aes_encrypt(v128_t * plaintext,const srtp_aes_expanded_key_t * exp_key)2109 void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
2110 {
2111     /* add in the subkey */
2112     v128_xor_eq(plaintext, &exp_key->round[0]);
2113 
2114     /* now do the rounds */
2115     aes_round(plaintext, &exp_key->round[1]);
2116     aes_round(plaintext, &exp_key->round[2]);
2117     aes_round(plaintext, &exp_key->round[3]);
2118     aes_round(plaintext, &exp_key->round[4]);
2119     aes_round(plaintext, &exp_key->round[5]);
2120     aes_round(plaintext, &exp_key->round[6]);
2121     aes_round(plaintext, &exp_key->round[7]);
2122     aes_round(plaintext, &exp_key->round[8]);
2123     aes_round(plaintext, &exp_key->round[9]);
2124     if (exp_key->num_rounds == 10) {
2125         aes_final_round(plaintext, &exp_key->round[10]);
2126     } else if (exp_key->num_rounds == 12) {
2127         aes_round(plaintext, &exp_key->round[10]);
2128         aes_round(plaintext, &exp_key->round[11]);
2129         aes_final_round(plaintext, &exp_key->round[12]);
2130     } else if (exp_key->num_rounds == 14) {
2131         aes_round(plaintext, &exp_key->round[10]);
2132         aes_round(plaintext, &exp_key->round[11]);
2133         aes_round(plaintext, &exp_key->round[12]);
2134         aes_round(plaintext, &exp_key->round[13]);
2135         aes_final_round(plaintext, &exp_key->round[14]);
2136     }
2137 }
2138 
srtp_aes_decrypt(v128_t * plaintext,const srtp_aes_expanded_key_t * exp_key)2139 void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
2140 {
2141     /* add in the subkey */
2142     v128_xor_eq(plaintext, &exp_key->round[0]);
2143 
2144     /* now do the rounds */
2145     aes_inv_round(plaintext, &exp_key->round[1]);
2146     aes_inv_round(plaintext, &exp_key->round[2]);
2147     aes_inv_round(plaintext, &exp_key->round[3]);
2148     aes_inv_round(plaintext, &exp_key->round[4]);
2149     aes_inv_round(plaintext, &exp_key->round[5]);
2150     aes_inv_round(plaintext, &exp_key->round[6]);
2151     aes_inv_round(plaintext, &exp_key->round[7]);
2152     aes_inv_round(plaintext, &exp_key->round[8]);
2153     aes_inv_round(plaintext, &exp_key->round[9]);
2154     if (exp_key->num_rounds == 10) {
2155         aes_inv_final_round(plaintext, &exp_key->round[10]);
2156     } else if (exp_key->num_rounds == 12) {
2157         aes_inv_round(plaintext, &exp_key->round[10]);
2158         aes_inv_round(plaintext, &exp_key->round[11]);
2159         aes_inv_final_round(plaintext, &exp_key->round[12]);
2160     } else if (exp_key->num_rounds == 14) {
2161         aes_inv_round(plaintext, &exp_key->round[10]);
2162         aes_inv_round(plaintext, &exp_key->round[11]);
2163         aes_inv_round(plaintext, &exp_key->round[12]);
2164         aes_inv_round(plaintext, &exp_key->round[13]);
2165         aes_inv_final_round(plaintext, &exp_key->round[14]);
2166     }
2167 }
2168