]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/aes.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / wolfcrypt / src / aes.c
1 /* aes.c
2  *
3  * Copyright (C) 2006-2015 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL. (formerly known as CyaSSL)
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27
28 #ifndef NO_AES
29
30 #include <wolfssl/wolfcrypt/aes.h>
31
32 #ifdef HAVE_FIPS
33 int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
34                           int dir)
35 {
36     return AesSetKey_fips(aes, key, len, iv, dir);
37 }
38
39
40 int wc_AesSetIV(Aes* aes, const byte* iv)
41 {
42     return AesSetIV_fips(aes, iv);
43 }
44
45
46 int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
47 {
48     return AesCbcEncrypt_fips(aes, out, in, sz);
49 }
50
51
52 int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
53 {
54     return AesCbcDecrypt_fips(aes, out, in, sz);
55 }
56
57
58 int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,
59                                  const byte* key, word32 keySz, const byte* iv)
60 {
61     return AesCbcDecryptWithKey(out, in, inSz, key, keySz, iv);
62 }
63
64
65 /* AES-CTR */
66 #ifdef WOLFSSL_AES_COUNTER
67 void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
68 {
69     AesCtrEncrypt(aes, out, in, sz);
70 }
71 #endif
72
73 /* AES-DIRECT */
74 #if defined(WOLFSSL_AES_DIRECT)
75 void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
76 {
77     AesEncryptDirect(aes, out, in);
78 }
79
80
81 void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
82 {
83     AesDecryptDirect(aes, out, in);
84 }
85
86
87 int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
88                                 const byte* iv, int dir)
89 {
90     return AesSetKeyDirect(aes, key, len, iv, dir);
91 }
92 #endif
93
94
95 #ifdef HAVE_AESGCM
96 int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
97 {
98     return AesGcmSetKey_fips(aes, key, len);
99 }
100
101
102 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
103                               const byte* iv, word32 ivSz,
104                               byte* authTag, word32 authTagSz,
105                               const byte* authIn, word32 authInSz)
106 {
107     return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
108                               authIn, authInSz);
109 }
110
111
112 int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
113                               const byte* iv, word32 ivSz,
114                               const byte* authTag, word32 authTagSz,
115                               const byte* authIn, word32 authInSz)
116 {
117     return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
118                               authIn, authInSz);
119 }
120
121
122 int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
123 {
124     return GmacSetKey(gmac, key, len);
125 }
126
127
128 int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
129                               const byte* authIn, word32 authInSz,
130                               byte* authTag, word32 authTagSz)
131 {
132     return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,
133                       authTag, authTagSz);
134 }
135
136 #endif /* HAVE_AESGCM */
137 #ifdef HAVE_AESCCM
138 void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
139 {
140     AesCcmSetKey(aes, key, keySz);
141 }
142
143
144 void wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
145                               const byte* nonce, word32 nonceSz,
146                               byte* authTag, word32 authTagSz,
147                               const byte* authIn, word32 authInSz)
148 {
149     AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
150                   authIn, authInSz);
151 }
152
153
154 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
155                               const byte* nonce, word32 nonceSz,
156                               const byte* authTag, word32 authTagSz,
157                               const byte* authIn, word32 authInSz)
158 {
159     return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
160                          authIn, authInSz);
161 }
162 #endif /* HAVE_AESCCM */
163
164 #ifdef HAVE_CAVIUM
165 int  wc_AesInitCavium(Aes* aes, int i)
166 {
167     return AesInitCavium(aes, i);
168 }
169
170
171 void wc_AesFreeCavium(Aes* aes)
172 {
173     AesFreeCavium(aes);
174 }
175 #endif
176 #else /* HAVE_FIPS */
177
178 #ifdef WOLFSSL_TI_CRYPT
179 #include <wolfcrypt/src/port/ti/ti-aes.c>
180 #else
181
182 #include <wolfssl/wolfcrypt/error-crypt.h>
183 #include <wolfssl/wolfcrypt/logging.h>
184 #ifdef NO_INLINE
185     #include <wolfssl/wolfcrypt/misc.h>
186 #else
187     #include <wolfcrypt/src/misc.c>
188 #endif
189 #ifdef DEBUG_AESNI
190     #include <stdio.h>
191 #endif
192
193
194 #ifdef _MSC_VER
195     /* 4127 warning constant while(1)  */
196     #pragma warning(disable: 4127)
197 #endif
198
199
200 #if defined(STM32F2_CRYPTO)
201      /* STM32F2 hardware AES support for CBC, CTR modes through the STM32F2
202       * Standard Peripheral Library. Documentation located in STM32F2xx
203       * Standard Peripheral Library document (See note in README).
204       * NOTE: no support for AES-GCM/CCM/Direct */
205     #include "stm32f2xx.h"
206     #include "stm32f2xx_cryp.h"
207 #elif defined(HAVE_COLDFIRE_SEC)
208     /* Freescale Coldfire SEC support for CBC mode.
209      * NOTE: no support for AES-CTR/GCM/CCM/Direct */
210     #include <wolfssl/wolfcrypt/types.h>
211     #include "sec.h"
212     #include "mcf5475_sec.h"
213     #include "mcf5475_siu.h"
214 #elif defined(FREESCALE_MMCAU)
215     /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
216      * through the CAU/mmCAU library. Documentation located in
217      * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
218      * Guide (See note in README).
219      * NOTE: no support for AES-CTR */
220     #include "cau_api.h"
221 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
222     /* NOTE: no support for AES-CCM/Direct */
223     #define DEBUG_WOLFSSL
224     #include "wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h"
225 #elif defined(HAVE_CAVIUM)
226     #include <wolfssl/wolfcrypt/logging.h>
227     #include "cavium_common.h"
228
229     /* still leave SW crypto available */
230     #define NEED_AES_TABLES
231
232     static int  wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
233                                 const byte* iv);
234     static int  wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
235                                     word32 length);
236     static int  wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
237                                     word32 length);
238 #else
239     /* using CTaoCrypt software AES implementation */
240     #define NEED_AES_TABLES
241 #endif /* STM32F2_CRYPTO */
242
243
244 #ifdef NEED_AES_TABLES
245
246 static const word32 rcon[] = {
247     0x01000000, 0x02000000, 0x04000000, 0x08000000,
248     0x10000000, 0x20000000, 0x40000000, 0x80000000,
249     0x1B000000, 0x36000000,
250     /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
251 };
252
253 static const word32 Te[5][256] = {
254 {
255     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
256     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
257     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
258     0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
259     0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
260     0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
261     0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
262     0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
263     0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
264     0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
265     0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
266     0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
267     0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
268     0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
269     0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
270     0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
271     0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
272     0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
273     0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
274     0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
275     0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
276     0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
277     0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
278     0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
279     0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
280     0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
281     0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
282     0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
283     0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
284     0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
285     0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
286     0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
287     0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
288     0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
289     0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
290     0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
291     0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
292     0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
293     0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
294     0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
295     0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
296     0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
297     0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
298     0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
299     0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
300     0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
301     0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
302     0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
303     0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
304     0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
305     0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
306     0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
307     0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
308     0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
309     0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
310     0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
311     0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
312     0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
313     0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
314     0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
315     0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
316     0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
317     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
318     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
319 },
320 {
321     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
322     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
323     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
324     0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
325     0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
326     0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
327     0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
328     0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
329     0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
330     0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
331     0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
332     0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
333     0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
334     0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
335     0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
336     0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
337     0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
338     0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
339     0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
340     0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
341     0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
342     0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
343     0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
344     0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
345     0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
346     0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
347     0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
348     0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
349     0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
350     0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
351     0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
352     0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
353     0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
354     0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
355     0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
356     0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
357     0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
358     0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
359     0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
360     0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
361     0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
362     0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
363     0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
364     0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
365     0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
366     0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
367     0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
368     0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
369     0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
370     0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
371     0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
372     0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
373     0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
374     0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
375     0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
376     0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
377     0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
378     0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
379     0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
380     0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
381     0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
382     0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
383     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
384     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
385 },
386 {
387     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
388     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
389     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
390     0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
391     0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
392     0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
393     0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
394     0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
395     0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
396     0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
397     0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
398     0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
399     0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
400     0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
401     0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
402     0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
403     0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
404     0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
405     0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
406     0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
407     0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
408     0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
409     0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
410     0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
411     0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
412     0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
413     0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
414     0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
415     0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
416     0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
417     0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
418     0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
419     0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
420     0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
421     0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
422     0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
423     0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
424     0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
425     0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
426     0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
427     0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
428     0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
429     0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
430     0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
431     0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
432     0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
433     0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
434     0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
435     0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
436     0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
437     0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
438     0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
439     0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
440     0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
441     0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
442     0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
443     0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
444     0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
445     0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
446     0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
447     0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
448     0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
449     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
450     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
451 },
452 {
453     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
454     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
455     0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
456     0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
457     0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
458     0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
459     0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
460     0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
461     0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
462     0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
463     0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
464     0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
465     0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
466     0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
467     0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
468     0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
469     0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
470     0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
471     0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
472     0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
473     0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
474     0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
475     0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
476     0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
477     0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
478     0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
479     0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
480     0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
481     0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
482     0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
483     0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
484     0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
485     0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
486     0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
487     0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
488     0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
489     0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
490     0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
491     0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
492     0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
493     0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
494     0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
495     0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
496     0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
497     0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
498     0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
499     0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
500     0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
501     0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
502     0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
503     0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
504     0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
505     0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
506     0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
507     0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
508     0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
509     0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
510     0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
511     0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
512     0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
513     0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
514     0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
515     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
516     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
517 },
518 {
519     0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
520     0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
521     0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
522     0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
523     0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
524     0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
525     0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
526     0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
527     0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
528     0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
529     0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
530     0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
531     0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
532     0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
533     0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
534     0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
535     0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
536     0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
537     0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
538     0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
539     0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
540     0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
541     0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
542     0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
543     0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
544     0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
545     0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
546     0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
547     0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
548     0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
549     0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
550     0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
551     0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
552     0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
553     0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
554     0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
555     0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
556     0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
557     0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
558     0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
559     0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
560     0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
561     0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
562     0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
563     0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
564     0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
565     0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
566     0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
567     0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
568     0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
569     0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
570     0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
571     0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
572     0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
573     0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
574     0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
575     0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
576     0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
577     0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
578     0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
579     0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
580     0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
581     0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
582     0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
583 }
584 };
585
586 static const word32 Td[5][256] = {
587 {
588     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
589     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
590     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
591     0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
592     0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
593     0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
594     0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
595     0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
596     0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
597     0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
598     0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
599     0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
600     0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
601     0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
602     0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
603     0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
604     0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
605     0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
606     0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
607     0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
608     0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
609     0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
610     0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
611     0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
612     0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
613     0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
614     0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
615     0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
616     0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
617     0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
618     0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
619     0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
620     0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
621     0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
622     0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
623     0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
624     0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
625     0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
626     0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
627     0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
628     0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
629     0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
630     0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
631     0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
632     0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
633     0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
634     0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
635     0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
636     0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
637     0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
638     0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
639     0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
640     0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
641     0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
642     0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
643     0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
644     0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
645     0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
646     0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
647     0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
648     0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
649     0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
650     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
651     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
652 },
653 {
654     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
655     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
656     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
657     0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
658     0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
659     0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
660     0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
661     0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
662     0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
663     0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
664     0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
665     0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
666     0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
667     0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
668     0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
669     0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
670     0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
671     0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
672     0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
673     0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
674     0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
675     0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
676     0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
677     0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
678     0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
679     0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
680     0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
681     0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
682     0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
683     0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
684     0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
685     0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
686     0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
687     0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
688     0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
689     0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
690     0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
691     0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
692     0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
693     0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
694     0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
695     0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
696     0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
697     0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
698     0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
699     0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
700     0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
701     0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
702     0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
703     0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
704     0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
705     0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
706     0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
707     0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
708     0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
709     0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
710     0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
711     0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
712     0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
713     0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
714     0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
715     0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
716     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
717     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
718 },
719 {
720     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
721     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
722     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
723     0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
724     0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
725     0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
726     0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
727     0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
728     0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
729     0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
730     0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
731     0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
732     0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
733     0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
734     0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
735     0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
736     0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
737     0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
738     0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
739     0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
740
741     0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
742     0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
743     0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
744     0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
745     0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
746     0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
747     0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
748     0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
749     0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
750     0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
751     0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
752     0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
753     0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
754     0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
755     0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
756     0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
757     0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
758     0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
759     0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
760     0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
761     0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
762     0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
763     0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
764     0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
765     0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
766     0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
767     0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
768     0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
769     0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
770     0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
771     0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
772     0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
773     0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
774     0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
775     0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
776     0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
777     0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
778     0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
779     0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
780     0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
781     0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
782     0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
783     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
784     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
785 },
786 {
787     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
788     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
789     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
790     0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
791     0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
792     0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
793     0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
794     0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
795     0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
796     0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
797     0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
798     0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
799     0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
800     0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
801     0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
802     0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
803     0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
804     0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
805     0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
806     0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
807     0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
808     0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
809     0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
810     0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
811     0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
812     0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
813     0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
814     0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
815     0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
816     0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
817     0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
818     0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
819     0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
820     0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
821     0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
822     0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
823     0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
824     0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
825     0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
826     0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
827     0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
828     0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
829     0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
830     0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
831     0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
832     0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
833     0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
834     0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
835     0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
836     0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
837     0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
838     0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
839     0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
840     0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
841     0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
842     0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
843     0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
844     0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
845     0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
846     0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
847     0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
848     0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
849     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
850     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
851 },
852 {
853     0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
854     0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
855     0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
856     0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
857     0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
858     0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
859     0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
860     0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
861     0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
862     0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
863     0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
864     0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
865     0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
866     0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
867     0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
868     0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
869     0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
870     0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
871     0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
872     0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
873     0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
874     0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
875     0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
876     0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
877     0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
878     0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
879     0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
880     0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
881     0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
882     0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
883     0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
884     0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
885     0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
886     0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
887     0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
888     0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
889     0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
890     0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
891     0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
892     0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
893     0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
894     0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
895     0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
896     0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
897     0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
898     0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
899     0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
900     0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
901     0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
902     0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
903     0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
904     0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
905     0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
906     0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
907     0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
908     0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
909     0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
910     0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
911     0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
912     0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
913     0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
914     0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
915     0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
916     0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
917 }
918 };
919
920 #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
921
922 #ifdef WOLFSSL_AESNI
923
924 /* Each platform needs to query info type 1 from cpuid to see if aesni is
925  * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
926  */
927
928 #ifndef _MSC_VER
929
930     #define cpuid(reg, func)\
931         __asm__ __volatile__ ("cpuid":\
932              "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
933              "a" (func));
934
935     #define XASM_LINK(f) asm(f)
936 #else
937
938     #include <intrin.h>
939     #define cpuid(a,b) __cpuid((int*)a,b)
940
941     #define XASM_LINK(f)
942
943 #endif /* _MSC_VER */
944
945
946 static int Check_CPU_support_AES(void)
947 {
948     unsigned int reg[4];  /* put a,b,c,d into 0,1,2,3 */
949     cpuid(reg, 1);        /* query info 1 */
950
951     if (reg[2] & 0x2000000)
952         return 1;
953
954     return 0;
955 }
956
957 static int checkAESNI = 0;
958 static int haveAESNI  = 0;
959
960
961 /* tell C compiler these are asm functions in case any mix up of ABI underscore
962    prefix between clang/gcc/llvm etc */
963 void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
964                      unsigned char* ivec, unsigned long length,
965                      const unsigned char* KS, int nr)
966                      XASM_LINK("AES_CBC_encrypt");
967
968
969 void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
970                      unsigned char* ivec, unsigned long length,
971                      const unsigned char* KS, int nr)
972                      XASM_LINK("AES_CBC_decrypt");
973
974 void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
975                      unsigned long length, const unsigned char* KS, int nr)
976                      XASM_LINK("AES_ECB_encrypt");
977
978
979 void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
980                      unsigned long length, const unsigned char* KS, int nr)
981                      XASM_LINK("AES_ECB_decrypt");
982
983 void AES_128_Key_Expansion(const unsigned char* userkey,
984                            unsigned char* key_schedule)
985                            XASM_LINK("AES_128_Key_Expansion");
986
987 void AES_192_Key_Expansion(const unsigned char* userkey,
988                            unsigned char* key_schedule)
989                            XASM_LINK("AES_192_Key_Expansion");
990
991 void AES_256_Key_Expansion(const unsigned char* userkey,
992                            unsigned char* key_schedule)
993                            XASM_LINK("AES_256_Key_Expansion");
994
995
996 static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
997                                Aes* aes)
998 {
999     if (!userKey || !aes)
1000         return BAD_FUNC_ARG;
1001
1002     if (bits == 128) {
1003        AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
1004        return 0;
1005     }
1006     else if (bits == 192) {
1007        AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
1008        return 0;
1009     }
1010     else if (bits == 256) {
1011        AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
1012        return 0;
1013     }
1014     return BAD_FUNC_ARG;
1015 }
1016
1017
1018 static int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
1019                                Aes* aes)
1020 {
1021     int nr;
1022     Aes temp_key;
1023     __m128i *Key_Schedule = (__m128i*)aes->key;
1024     __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
1025
1026     if (!userKey || !aes)
1027         return BAD_FUNC_ARG;
1028
1029     if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
1030         return BAD_FUNC_ARG;
1031
1032     nr = temp_key.rounds;
1033     aes->rounds = nr;
1034
1035     Key_Schedule[nr] = Temp_Key_Schedule[0];
1036     Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
1037     Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
1038     Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
1039     Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
1040     Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
1041     Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
1042     Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
1043     Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
1044     Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
1045
1046     if(nr>10) {
1047         Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
1048         Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
1049     }
1050
1051     if(nr>12) {
1052         Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
1053         Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
1054     }
1055
1056     Key_Schedule[0] = Temp_Key_Schedule[nr];
1057
1058     return 0;
1059 }
1060
1061
1062
1063 #endif /* WOLFSSL_AESNI */
1064
1065
1066 static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
1067 {
1068     word32 s0, s1, s2, s3;
1069     word32 t0, t1, t2, t3;
1070     word32 r = aes->rounds >> 1;
1071
1072     const word32* rk = aes->key;
1073     if (r > 7 || r == 0) {
1074         WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
1075         return;  /* stop instead of segfaulting, set up your keys! */
1076     }
1077 #ifdef WOLFSSL_AESNI
1078     if (haveAESNI && aes->use_aesni) {
1079         #ifdef DEBUG_AESNI
1080             printf("about to aes encrypt\n");
1081             printf("in  = %p\n", inBlock);
1082             printf("out = %p\n", outBlock);
1083             printf("aes->key = %p\n", aes->key);
1084             printf("aes->rounds = %d\n", aes->rounds);
1085             printf("sz = %d\n", AES_BLOCK_SIZE);
1086         #endif
1087
1088         /* check alignment, decrypt doesn't need alignment */
1089         if ((wolfssl_word)inBlock % 16) {
1090         #ifndef NO_WOLFSSL_ALLOC_ALIGN
1091             byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL,
1092                                                       DYNAMIC_TYPE_TMP_BUFFER);
1093             if (tmp == NULL) return;
1094
1095             XMEMCPY(tmp, inBlock, AES_BLOCK_SIZE);
1096             AES_ECB_encrypt(tmp, tmp, AES_BLOCK_SIZE, (byte*)aes->key,
1097                             aes->rounds);
1098             XMEMCPY(outBlock, tmp, AES_BLOCK_SIZE);
1099             XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1100             return;
1101         #else
1102             WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
1103             return;
1104         #endif
1105         }
1106
1107         AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
1108                         aes->rounds);
1109
1110         return;
1111     }
1112     else {
1113         #ifdef DEBUG_AESNI
1114             printf("Skipping AES-NI\n");
1115         #endif
1116     }
1117 #endif
1118
1119     /*
1120      * map byte array block to cipher state
1121      * and add initial round key:
1122      */
1123     XMEMCPY(&s0, inBlock,                  sizeof(s0));
1124     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
1125     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1126     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1127
1128     #ifdef LITTLE_ENDIAN_ORDER
1129         s0 = ByteReverseWord32(s0);
1130         s1 = ByteReverseWord32(s1);
1131         s2 = ByteReverseWord32(s2);
1132         s3 = ByteReverseWord32(s3);
1133     #endif
1134
1135     s0 ^= rk[0];
1136     s1 ^= rk[1];
1137     s2 ^= rk[2];
1138     s3 ^= rk[3];
1139
1140     /*
1141      * Nr - 1 full rounds:
1142      */
1143
1144     for (;;) {
1145         t0 =
1146             Te[0][GETBYTE(s0, 3)]  ^
1147             Te[1][GETBYTE(s1, 2)]  ^
1148             Te[2][GETBYTE(s2, 1)]  ^
1149             Te[3][GETBYTE(s3, 0)]  ^
1150             rk[4];
1151         t1 =
1152             Te[0][GETBYTE(s1, 3)]  ^
1153             Te[1][GETBYTE(s2, 2)]  ^
1154             Te[2][GETBYTE(s3, 1)]  ^
1155             Te[3][GETBYTE(s0, 0)]  ^
1156             rk[5];
1157         t2 =
1158             Te[0][GETBYTE(s2, 3)] ^
1159             Te[1][GETBYTE(s3, 2)]  ^
1160             Te[2][GETBYTE(s0, 1)]  ^
1161             Te[3][GETBYTE(s1, 0)]  ^
1162             rk[6];
1163         t3 =
1164             Te[0][GETBYTE(s3, 3)] ^
1165             Te[1][GETBYTE(s0, 2)]  ^
1166             Te[2][GETBYTE(s1, 1)]  ^
1167             Te[3][GETBYTE(s2, 0)]  ^
1168             rk[7];
1169
1170         rk += 8;
1171         if (--r == 0) {
1172             break;
1173         }
1174
1175         s0 =
1176             Te[0][GETBYTE(t0, 3)] ^
1177             Te[1][GETBYTE(t1, 2)] ^
1178             Te[2][GETBYTE(t2, 1)] ^
1179             Te[3][GETBYTE(t3, 0)] ^
1180             rk[0];
1181         s1 =
1182             Te[0][GETBYTE(t1, 3)] ^
1183             Te[1][GETBYTE(t2, 2)] ^
1184             Te[2][GETBYTE(t3, 1)] ^
1185             Te[3][GETBYTE(t0, 0)] ^
1186             rk[1];
1187         s2 =
1188             Te[0][GETBYTE(t2, 3)] ^
1189             Te[1][GETBYTE(t3, 2)] ^
1190             Te[2][GETBYTE(t0, 1)] ^
1191             Te[3][GETBYTE(t1, 0)] ^
1192             rk[2];
1193         s3 =
1194             Te[0][GETBYTE(t3, 3)] ^
1195             Te[1][GETBYTE(t0, 2)] ^
1196             Te[2][GETBYTE(t1, 1)] ^
1197             Te[3][GETBYTE(t2, 0)] ^
1198             rk[3];
1199     }
1200
1201     /*
1202      * apply last round and
1203      * map cipher state to byte array block:
1204      */
1205
1206     s0 =
1207         (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
1208         (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
1209         (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
1210         (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
1211         rk[0];
1212     s1 =
1213         (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
1214         (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
1215         (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
1216         (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
1217         rk[1];
1218     s2 =
1219         (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
1220         (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
1221         (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
1222         (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
1223         rk[2];
1224     s3 =
1225         (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
1226         (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
1227         (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
1228         (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
1229         rk[3];
1230
1231     /* write out */
1232     #ifdef LITTLE_ENDIAN_ORDER
1233         s0 = ByteReverseWord32(s0);
1234         s1 = ByteReverseWord32(s1);
1235         s2 = ByteReverseWord32(s2);
1236         s3 = ByteReverseWord32(s3);
1237     #endif
1238
1239     XMEMCPY(outBlock,                  &s0, sizeof(s0));
1240     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
1241     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
1242     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
1243 }
1244
1245 static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
1246 {
1247     word32 s0, s1, s2, s3;
1248     word32 t0, t1, t2, t3;
1249     word32 r = aes->rounds >> 1;
1250
1251     const word32* rk = aes->key;
1252     if (r > 7 || r == 0) {
1253         WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
1254         return;  /* stop instead of segfaulting, set up your keys! */
1255     }
1256 #ifdef WOLFSSL_AESNI
1257     if (haveAESNI && aes->use_aesni) {
1258         #ifdef DEBUG_AESNI
1259             printf("about to aes decrypt\n");
1260             printf("in  = %p\n", inBlock);
1261             printf("out = %p\n", outBlock);
1262             printf("aes->key = %p\n", aes->key);
1263             printf("aes->rounds = %d\n", aes->rounds);
1264             printf("sz = %d\n", AES_BLOCK_SIZE);
1265         #endif
1266
1267         /* if input and output same will overwrite input iv */
1268         XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
1269         AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
1270                         aes->rounds);
1271         return;
1272     }
1273     else {
1274         #ifdef DEBUG_AESNI
1275             printf("Skipping AES-NI\n");
1276         #endif
1277     }
1278 #endif
1279
1280     /*
1281      * map byte array block to cipher state
1282      * and add initial round key:
1283      */
1284     XMEMCPY(&s0, inBlock,                  sizeof(s0));
1285     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
1286     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1287     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1288
1289     #ifdef LITTLE_ENDIAN_ORDER
1290         s0 = ByteReverseWord32(s0);
1291         s1 = ByteReverseWord32(s1);
1292         s2 = ByteReverseWord32(s2);
1293         s3 = ByteReverseWord32(s3);
1294     #endif
1295
1296     s0 ^= rk[0];
1297     s1 ^= rk[1];
1298     s2 ^= rk[2];
1299     s3 ^= rk[3];
1300
1301     /*
1302      * Nr - 1 full rounds:
1303      */
1304
1305     for (;;) {
1306         t0 =
1307             Td[0][GETBYTE(s0, 3)] ^
1308             Td[1][GETBYTE(s3, 2)] ^
1309             Td[2][GETBYTE(s2, 1)] ^
1310             Td[3][GETBYTE(s1, 0)] ^
1311             rk[4];
1312         t1 =
1313             Td[0][GETBYTE(s1, 3)] ^
1314             Td[1][GETBYTE(s0, 2)] ^
1315             Td[2][GETBYTE(s3, 1)] ^
1316             Td[3][GETBYTE(s2, 0)] ^
1317             rk[5];
1318         t2 =
1319             Td[0][GETBYTE(s2, 3)] ^
1320             Td[1][GETBYTE(s1, 2)] ^
1321             Td[2][GETBYTE(s0, 1)] ^
1322             Td[3][GETBYTE(s3, 0)] ^
1323             rk[6];
1324         t3 =
1325             Td[0][GETBYTE(s3, 3)] ^
1326             Td[1][GETBYTE(s2, 2)] ^
1327             Td[2][GETBYTE(s1, 1)] ^
1328             Td[3][GETBYTE(s0, 0)] ^
1329             rk[7];
1330
1331         rk += 8;
1332         if (--r == 0) {
1333             break;
1334         }
1335
1336         s0 =
1337             Td[0][GETBYTE(t0, 3)] ^
1338             Td[1][GETBYTE(t3, 2)] ^
1339             Td[2][GETBYTE(t2, 1)] ^
1340             Td[3][GETBYTE(t1, 0)] ^
1341             rk[0];
1342         s1 =
1343             Td[0][GETBYTE(t1, 3)] ^
1344             Td[1][GETBYTE(t0, 2)] ^
1345             Td[2][GETBYTE(t3, 1)] ^
1346             Td[3][GETBYTE(t2, 0)] ^
1347             rk[1];
1348         s2 =
1349             Td[0][GETBYTE(t2, 3)] ^
1350             Td[1][GETBYTE(t1, 2)] ^
1351             Td[2][GETBYTE(t0, 1)] ^
1352             Td[3][GETBYTE(t3, 0)] ^
1353             rk[2];
1354         s3 =
1355             Td[0][GETBYTE(t3, 3)] ^
1356             Td[1][GETBYTE(t2, 2)] ^
1357             Td[2][GETBYTE(t1, 1)] ^
1358             Td[3][GETBYTE(t0, 0)] ^
1359             rk[3];
1360     }
1361     /*
1362      * apply last round and
1363      * map cipher state to byte array block:
1364      */
1365     s0 =
1366         (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
1367         (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
1368         (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
1369         (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
1370         rk[0];
1371     s1 =
1372         (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
1373         (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
1374         (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
1375         (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
1376         rk[1];
1377     s2 =
1378         (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
1379         (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
1380         (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
1381         (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
1382         rk[2];
1383     s3 =
1384         (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
1385         (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
1386         (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
1387         (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
1388         rk[3];
1389
1390     /* write out */
1391     #ifdef LITTLE_ENDIAN_ORDER
1392         s0 = ByteReverseWord32(s0);
1393         s1 = ByteReverseWord32(s1);
1394         s2 = ByteReverseWord32(s2);
1395         s3 = ByteReverseWord32(s3);
1396     #endif
1397
1398     XMEMCPY(outBlock,                  &s0, sizeof(s0));
1399     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
1400     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
1401     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
1402 }
1403
1404 #endif /* NEED_AES_TABLES */
1405
1406
1407 /* wc_AesSetKey */
1408 #ifdef STM32F2_CRYPTO
1409     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
1410                   int dir)
1411     {
1412         word32 *rk = aes->key;
1413
1414         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
1415             return BAD_FUNC_ARG;
1416
1417         aes->rounds = keylen/4 + 6;
1418         XMEMCPY(rk, userKey, keylen);
1419         ByteReverseWords(rk, rk, keylen);
1420
1421         return wc_AesSetIV(aes, iv);
1422     }
1423
1424     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
1425                         const byte* iv, int dir)
1426     {
1427         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
1428     }
1429
1430 #elif defined(HAVE_COLDFIRE_SEC)
1431     #if defined (HAVE_THREADX)
1432         #include "memory_pools.h"
1433         extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
1434     #endif
1435
1436     #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
1437     static unsigned char *AESBuffIn = NULL;
1438     static unsigned char *AESBuffOut = NULL;
1439     static byte *secReg;
1440     static byte *secKey;
1441     static volatile SECdescriptorType *secDesc;
1442
1443     static wolfSSL_Mutex Mutex_AesSEC;
1444
1445     #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
1446     #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
1447
1448     extern volatile unsigned char __MBAR[];
1449
1450     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
1451                   int dir)
1452     {
1453         if (AESBuffIn == NULL) {
1454             #if defined (HAVE_THREADX)
1455                             int s1, s2, s3, s4, s5 ;
1456                 s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
1457                                       sizeof(SECdescriptorType), TX_NO_WAIT);
1458                 s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
1459                                       AES_BUFFER_SIZE, TX_NO_WAIT);
1460                 s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
1461                                       AES_BUFFER_SIZE, TX_NO_WAIT);
1462                 s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
1463                                       AES_BLOCK_SIZE*2, TX_NO_WAIT);
1464                 s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
1465                                       AES_BLOCK_SIZE, TX_NO_WAIT);
1466
1467                 if(s1 || s2 || s3 || s4 || s5)
1468                     return BAD_FUNC_ARG;
1469             #else
1470                 #warning "Allocate non-Cache buffers"
1471             #endif
1472
1473             InitMutex(&Mutex_AesSEC);
1474         }
1475
1476         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
1477             return BAD_FUNC_ARG;
1478
1479         if (aes == NULL)
1480             return BAD_FUNC_ARG;
1481
1482         aes->rounds = keylen/4 + 6;
1483         XMEMCPY(aes->key, userKey, keylen);
1484
1485         if (iv)
1486             XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
1487
1488         return 0;
1489     }
1490 #elif defined(FREESCALE_MMCAU)
1491     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
1492                   int dir)
1493     {
1494         byte *rk = (byte*)aes->key;
1495
1496         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
1497             return BAD_FUNC_ARG;
1498
1499         if (rk == NULL)
1500             return BAD_FUNC_ARG;
1501
1502         aes->rounds = keylen/4 + 6;
1503         cau_aes_set_key(userKey, keylen*8, rk);
1504
1505         return wc_AesSetIV(aes, iv);
1506     }
1507
1508     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
1509                         const byte* iv, int dir)
1510     {
1511         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
1512     }
1513 #else
1514     static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
1515                 const byte* iv, int dir)
1516     {
1517         word32 temp, *rk = aes->key;
1518         unsigned int i = 0;
1519
1520         #ifdef WOLFSSL_AESNI
1521             aes->use_aesni = 0;
1522         #endif /* WOLFSSL_AESNI */
1523         #ifdef WOLFSSL_AES_COUNTER
1524             aes->left = 0;
1525         #endif /* WOLFSSL_AES_COUNTER */
1526
1527         aes->rounds = keylen/4 + 6;
1528
1529         XMEMCPY(rk, userKey, keylen);
1530         #ifdef LITTLE_ENDIAN_ORDER
1531             ByteReverseWords(rk, rk, keylen);
1532         #endif
1533
1534         #ifdef WOLFSSL_PIC32MZ_CRYPT
1535         {
1536             word32 *akey1 = aes->key_ce;
1537             word32 *areg = aes->iv_ce ;
1538             aes->keylen = keylen ;
1539             XMEMCPY(akey1, userKey, keylen);
1540             if (iv)
1541                 XMEMCPY(areg, iv, AES_BLOCK_SIZE);
1542             else
1543                 XMEMSET(areg,  0, AES_BLOCK_SIZE);
1544         }
1545         #endif
1546
1547         switch(keylen)
1548         {
1549         case 16:
1550             while (1)
1551             {
1552                 temp  = rk[3];
1553                 rk[4] = rk[0] ^
1554                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
1555                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
1556                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
1557                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
1558                     rcon[i];
1559                 rk[5] = rk[1] ^ rk[4];
1560                 rk[6] = rk[2] ^ rk[5];
1561                 rk[7] = rk[3] ^ rk[6];
1562                 if (++i == 10)
1563                     break;
1564                 rk += 4;
1565             }
1566             break;
1567
1568         case 24:
1569             /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
1570             while (1)
1571             {
1572                 temp = rk[ 5];
1573                 rk[ 6] = rk[ 0] ^
1574                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
1575                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
1576                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
1577                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
1578                     rcon[i];
1579                 rk[ 7] = rk[ 1] ^ rk[ 6];
1580                 rk[ 8] = rk[ 2] ^ rk[ 7];
1581                 rk[ 9] = rk[ 3] ^ rk[ 8];
1582                 if (++i == 8)
1583                     break;
1584                 rk[10] = rk[ 4] ^ rk[ 9];
1585                 rk[11] = rk[ 5] ^ rk[10];
1586                 rk += 6;
1587             }
1588             break;
1589
1590         case 32:
1591             while (1)
1592             {
1593                 temp = rk[ 7];
1594                 rk[ 8] = rk[ 0] ^
1595                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
1596                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
1597                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
1598                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
1599                     rcon[i];
1600                 rk[ 9] = rk[ 1] ^ rk[ 8];
1601                 rk[10] = rk[ 2] ^ rk[ 9];
1602                 rk[11] = rk[ 3] ^ rk[10];
1603                 if (++i == 7)
1604                     break;
1605                 temp = rk[11];
1606                 rk[12] = rk[ 4] ^
1607                     (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
1608                     (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
1609                     (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
1610                     (Te[4][GETBYTE(temp, 0)] & 0x000000ff);
1611                 rk[13] = rk[ 5] ^ rk[12];
1612                 rk[14] = rk[ 6] ^ rk[13];
1613                 rk[15] = rk[ 7] ^ rk[14];
1614
1615                 rk += 8;
1616             }
1617             break;
1618
1619         default:
1620             return BAD_FUNC_ARG;
1621         }
1622
1623         if (dir == AES_DECRYPTION)
1624         {
1625             unsigned int j;
1626             rk = aes->key;
1627
1628             /* invert the order of the round keys: */
1629             for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
1630                 temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
1631                 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
1632                 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
1633                 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
1634             }
1635             /* apply the inverse MixColumn transform to all round keys but the
1636                first and the last: */
1637             for (i = 1; i < aes->rounds; i++) {
1638                 rk += 4;
1639                 rk[0] =
1640                     Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
1641                     Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
1642                     Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
1643                     Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
1644                 rk[1] =
1645                     Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
1646                     Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
1647                     Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
1648                     Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
1649                 rk[2] =
1650                     Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
1651                     Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
1652                     Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
1653                     Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
1654                 rk[3] =
1655                     Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
1656                     Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
1657                     Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
1658                     Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
1659             }
1660         }
1661
1662         return wc_AesSetIV(aes, iv);
1663     }
1664
1665     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
1666                   int dir)
1667     {
1668
1669         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
1670             return BAD_FUNC_ARG;
1671
1672         #ifdef HAVE_CAVIUM
1673         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
1674             return wc_AesCaviumSetKey(aes, userKey, keylen, iv);
1675         #endif
1676
1677         #ifdef WOLFSSL_AESNI
1678         if (checkAESNI == 0) {
1679             haveAESNI  = Check_CPU_support_AES();
1680             checkAESNI = 1;
1681         }
1682         if (haveAESNI) {
1683             aes->use_aesni = 1;
1684             if (iv)
1685                 XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
1686             if (dir == AES_ENCRYPTION)
1687                 return AES_set_encrypt_key(userKey, keylen * 8, aes);
1688             else
1689                 return AES_set_decrypt_key(userKey, keylen * 8, aes);
1690         }
1691         #endif /* WOLFSSL_AESNI */
1692
1693         return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
1694     }
1695
1696     #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
1697
1698     /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */
1699     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
1700                         const byte* iv, int dir)
1701     {
1702         return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
1703     }
1704
1705     #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
1706 #endif /* STM32F2_CRYPTO, wc_AesSetKey block */
1707
1708
1709 /* wc_AesSetIV is shared between software and hardware */
1710 int wc_AesSetIV(Aes* aes, const byte* iv)
1711 {
1712     if (aes == NULL)
1713         return BAD_FUNC_ARG;
1714
1715     if (iv)
1716         XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
1717     else
1718         XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
1719
1720     return 0;
1721 }
1722
1723
1724 int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,
1725                                   const byte* key, word32 keySz, const byte* iv)
1726 {
1727     int  ret = 0;
1728 #ifdef WOLFSSL_SMALL_STACK
1729     Aes* aes = NULL;
1730 #else
1731     Aes  aes[1];
1732 #endif
1733
1734 #ifdef WOLFSSL_SMALL_STACK
1735     aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);
1736     if (aes == NULL)
1737         return MEMORY_E;
1738 #endif
1739
1740     ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
1741     if (ret == 0)
1742         ret = wc_AesCbcDecrypt(aes, out, in, inSz); 
1743
1744 #ifdef WOLFSSL_SMALL_STACK
1745     XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1746 #endif
1747
1748     return ret;
1749 }
1750
1751
1752 /* AES-DIRECT */
1753 #if defined(WOLFSSL_AES_DIRECT)
1754     #if defined(FREESCALE_MMCAU)
1755
1756         /* Allow direct access to one block encrypt */
1757         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
1758         {
1759             byte* key;
1760             key = (byte*)aes->key;
1761
1762             return cau_aes_encrypt(in, key, aes->rounds, out);
1763         }
1764
1765         /* Allow direct access to one block decrypt */
1766         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
1767         {
1768             byte* key;
1769             key = (byte*)aes->key;
1770
1771             return cau_aes_decrypt(in, key, aes->rounds, out);
1772         }
1773
1774     #elif defined(STM32F2_CRYPTO)
1775         #error "STM32F2 crypto doesn't yet support AES direct"
1776
1777     #elif defined(HAVE_COLDFIRE_SEC)
1778         #error "Coldfire SEC doesn't yet support AES direct"
1779
1780     #elif defined(WOLFSSL_PIC32MZ_CRYPT)
1781         #error "PIC32MZ doesn't yet support AES direct"
1782
1783     #else
1784         /* Allow direct access to one block encrypt */
1785         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
1786         {
1787             wc_AesEncrypt(aes, in, out);
1788         }
1789
1790         /* Allow direct access to one block decrypt */
1791         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
1792         {
1793             wc_AesDecrypt(aes, in, out);
1794         }
1795
1796     #endif /* FREESCALE_MMCAU, AES direct block */
1797 #endif /* WOLFSSL_AES_DIRECT */
1798
1799
1800 /* AES-CBC */
1801 #ifdef STM32F2_CRYPTO
1802     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
1803     {
1804         word32 *enc_key, *iv;
1805         CRYP_InitTypeDef AES_CRYP_InitStructure;
1806         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
1807         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
1808
1809         enc_key = aes->key;
1810         iv = aes->reg;
1811
1812         /* crypto structure initialization */
1813         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
1814         CRYP_StructInit(&AES_CRYP_InitStructure);
1815         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
1816
1817         /* reset registers to their default values */
1818         CRYP_DeInit();
1819
1820         /* load key into correct registers */
1821         switch(aes->rounds)
1822         {
1823             case 10: /* 128-bit key */
1824                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
1825                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
1826                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
1827                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
1828                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
1829                 break;
1830
1831             case 12: /* 192-bit key */
1832                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
1833                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
1834                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
1835                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
1836                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
1837                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
1838                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
1839                 break;
1840
1841             case 14: /* 256-bit key */
1842                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
1843                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
1844                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
1845                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
1846                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
1847                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
1848                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
1849                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
1850                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
1851                 break;
1852
1853             default:
1854                 break;
1855         }
1856         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1857
1858         /* set iv */
1859         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
1860         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
1861         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
1862         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
1863         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
1864         CRYP_IVInit(&AES_CRYP_IVInitStructure);
1865
1866         /* set direction, mode, and datatype */
1867         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
1868         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
1869         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1870         CRYP_Init(&AES_CRYP_InitStructure);
1871
1872         /* enable crypto processor */
1873         CRYP_Cmd(ENABLE);
1874
1875         while (sz > 0)
1876         {
1877             /* flush IN/OUT FIFOs */
1878             CRYP_FIFOFlush();
1879
1880             CRYP_DataIn(*(uint32_t*)&in[0]);
1881             CRYP_DataIn(*(uint32_t*)&in[4]);
1882             CRYP_DataIn(*(uint32_t*)&in[8]);
1883             CRYP_DataIn(*(uint32_t*)&in[12]);
1884
1885             /* wait until the complete message has been processed */
1886             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
1887
1888             *(uint32_t*)&out[0]  = CRYP_DataOut();
1889             *(uint32_t*)&out[4]  = CRYP_DataOut();
1890             *(uint32_t*)&out[8]  = CRYP_DataOut();
1891             *(uint32_t*)&out[12] = CRYP_DataOut();
1892
1893             /* store iv for next call */
1894             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
1895
1896             sz  -= 16;
1897             in  += 16;
1898             out += 16;
1899         }
1900
1901         /* disable crypto processor */
1902         CRYP_Cmd(DISABLE);
1903
1904         return 0;
1905     }
1906
1907     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
1908     {
1909         word32 *dec_key, *iv;
1910         CRYP_InitTypeDef AES_CRYP_InitStructure;
1911         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
1912         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
1913
1914         dec_key = aes->key;
1915         iv = aes->reg;
1916
1917         /* crypto structure initialization */
1918         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
1919         CRYP_StructInit(&AES_CRYP_InitStructure);
1920         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
1921
1922         /* if input and output same will overwrite input iv */
1923         XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
1924
1925         /* reset registers to their default values */
1926         CRYP_DeInit();
1927
1928         /* load key into correct registers */
1929         switch(aes->rounds)
1930         {
1931             case 10: /* 128-bit key */
1932                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
1933                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[0];
1934                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1];
1935                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[2];
1936                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3];
1937                 break;
1938
1939             case 12: /* 192-bit key */
1940                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
1941                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[0];
1942                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1];
1943                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[2];
1944                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3];
1945                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[4];
1946                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5];
1947                 break;
1948
1949             case 14: /* 256-bit key */
1950                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
1951                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = dec_key[0];
1952                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1];
1953                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[2];
1954                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3];
1955                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[4];
1956                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5];
1957                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[6];
1958                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7];
1959                 break;
1960
1961             default:
1962                 break;
1963         }
1964
1965         /* set direction, mode, and datatype for key preparation */
1966         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
1967         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
1968         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
1969         CRYP_Init(&AES_CRYP_InitStructure);
1970         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
1971
1972         /* enable crypto processor */
1973         CRYP_Cmd(ENABLE);
1974
1975         /* wait until key has been prepared */
1976         while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
1977
1978         /* set direction, mode, and datatype for decryption */
1979         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
1980         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
1981         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
1982         CRYP_Init(&AES_CRYP_InitStructure);
1983
1984         /* set iv */
1985         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
1986
1987         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
1988         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
1989         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
1990         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
1991         CRYP_IVInit(&AES_CRYP_IVInitStructure);
1992
1993         /* enable crypto processor */
1994         CRYP_Cmd(ENABLE);
1995
1996         while (sz > 0)
1997         {
1998             /* flush IN/OUT FIFOs */
1999             CRYP_FIFOFlush();
2000
2001             CRYP_DataIn(*(uint32_t*)&in[0]);
2002             CRYP_DataIn(*(uint32_t*)&in[4]);
2003             CRYP_DataIn(*(uint32_t*)&in[8]);
2004             CRYP_DataIn(*(uint32_t*)&in[12]);
2005
2006             /* wait until the complete message has been processed */
2007             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
2008
2009             *(uint32_t*)&out[0]  = CRYP_DataOut();
2010             *(uint32_t*)&out[4]  = CRYP_DataOut();
2011             *(uint32_t*)&out[8]  = CRYP_DataOut();
2012             *(uint32_t*)&out[12] = CRYP_DataOut();
2013
2014             /* store iv for next call */
2015             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
2016
2017             sz -= 16;
2018             in += 16;
2019             out += 16;
2020         }
2021
2022         /* disable crypto processor */
2023         CRYP_Cmd(DISABLE);
2024
2025         return 0;
2026     }
2027
2028 #elif defined(HAVE_COLDFIRE_SEC)
2029     static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,
2030                            word32 descHeader)
2031     {
2032         #ifdef DEBUG_WOLFSSL
2033             int i; int stat1, stat2; int ret;
2034             #endif
2035
2036         int size;
2037         volatile int v;
2038
2039         if ((pi == NULL) || (po == NULL))
2040             return BAD_FUNC_ARG;    /*wrong pointer*/
2041
2042         LockMutex(&Mutex_AesSEC);
2043
2044         /* Set descriptor for SEC */
2045         secDesc->length1 = 0x0;
2046         secDesc->pointer1 = NULL;
2047
2048         secDesc->length2 = AES_BLOCK_SIZE;
2049         secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
2050
2051         switch(aes->rounds) {
2052             case 10: secDesc->length3 = 16 ; break ;
2053             case 12: secDesc->length3 = 24 ; break ;
2054             case 14: secDesc->length3 = 32 ; break ;
2055         }
2056         XMEMCPY(secKey, aes->key, secDesc->length3);
2057
2058         secDesc->pointer3 = (byte *)secKey;
2059         secDesc->pointer4 = AESBuffIn;
2060         secDesc->pointer5 = AESBuffOut;
2061         secDesc->length6 = 0x0;
2062         secDesc->pointer6 = NULL;
2063         secDesc->length7 = 0x0;
2064         secDesc->pointer7 = NULL;
2065         secDesc->nextDescriptorPtr = NULL;
2066
2067         while (sz) {
2068             secDesc->header = descHeader;
2069             XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
2070             if ((sz % AES_BUFFER_SIZE) == sz) {
2071                 size = sz;
2072                 sz = 0;
2073             } else {
2074                 size = AES_BUFFER_SIZE;
2075                 sz -= AES_BUFFER_SIZE;
2076             }
2077             secDesc->length4 = size;
2078             secDesc->length5 = size;
2079
2080             XMEMCPY(AESBuffIn, pi, size);
2081             if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
2082                 XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
2083                         AES_BLOCK_SIZE);
2084             }
2085
2086             /* Point SEC to the location of the descriptor */
2087             MCF_SEC_FR0 = (uint32)secDesc;
2088             /* Initialize SEC and wait for encryption to complete */
2089             MCF_SEC_CCCR0 = 0x0000001a;
2090             /* poll SISR to determine when channel is complete */
2091             v=0;
2092
2093             while ((secDesc->header>> 24) != 0xff) v++;
2094
2095             #ifdef DEBUG_WOLFSSL
2096                 ret = MCF_SEC_SISRH;
2097                 stat1 = MCF_SEC_AESSR;
2098                 stat2 = MCF_SEC_AESISR;
2099                 if (ret & 0xe0000000) {
2100                     db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
2101                               "AESISR=%08x\n", i, ret, stat1, stat2);
2102                 }
2103             #endif
2104
2105             XMEMCPY(po, AESBuffOut, size);
2106
2107             if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
2108                 XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
2109                         AES_BLOCK_SIZE);
2110             } else {
2111                 XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
2112             }
2113
2114             pi += size;
2115             po += size;
2116         }
2117
2118         UnLockMutex(&Mutex_AesSEC);
2119         return 0;
2120     }
2121
2122     int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
2123     {
2124         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
2125     }
2126
2127     int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
2128     {
2129         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
2130     }
2131
2132 #elif defined(FREESCALE_MMCAU)
2133     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2134     {
2135         int i;
2136         int offset = 0;
2137         int len = sz;
2138
2139         byte *iv, *enc_key;
2140         byte temp_block[AES_BLOCK_SIZE];
2141
2142         iv      = (byte*)aes->reg;
2143         enc_key = (byte*)aes->key;
2144
2145         if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
2146             WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
2147             return BAD_ALIGN_E;
2148         }
2149
2150         while (len > 0)
2151         {
2152             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
2153
2154             /* XOR block with IV for CBC */
2155             for (i = 0; i < AES_BLOCK_SIZE; i++)
2156                 temp_block[i] ^= iv[i];
2157
2158             cau_aes_encrypt(temp_block, enc_key, aes->rounds, out + offset);
2159
2160             len    -= AES_BLOCK_SIZE;
2161             offset += AES_BLOCK_SIZE;
2162
2163             /* store IV for next block */
2164             XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
2165         }
2166
2167         return 0;
2168     }
2169
2170     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2171     {
2172         int i;
2173         int offset = 0;
2174         int len = sz;
2175
2176         byte* iv, *dec_key;
2177         byte temp_block[AES_BLOCK_SIZE];
2178
2179         iv      = (byte*)aes->reg;
2180         dec_key = (byte*)aes->key;
2181
2182         if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
2183             WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
2184             return BAD_ALIGN_E;
2185         }
2186
2187         while (len > 0)
2188         {
2189             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
2190
2191             cau_aes_decrypt(in + offset, dec_key, aes->rounds, out + offset);
2192
2193             /* XOR block with IV for CBC */
2194             for (i = 0; i < AES_BLOCK_SIZE; i++)
2195                 (out + offset)[i] ^= iv[i];
2196
2197             /* store IV for next block */
2198             XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
2199
2200             len    -= AES_BLOCK_SIZE;
2201             offset += AES_BLOCK_SIZE;
2202         }
2203
2204         return 0;
2205     }
2206
2207 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
2208     /* core hardware crypt engine driver */
2209     static void wc_AesCrypt(Aes *aes, byte* out, const byte* in, word32 sz,
2210                                             int dir, int algo, int cryptoalgo)
2211     {
2212         securityAssociation *sa_p ;
2213         bufferDescriptor *bd_p ;
2214
2215         volatile securityAssociation sa __attribute__((aligned (8)));
2216         volatile bufferDescriptor bd __attribute__((aligned (8)));
2217         volatile int k ;
2218
2219         /* get uncached address */
2220         sa_p = KVA0_TO_KVA1(&sa) ;
2221         bd_p = KVA0_TO_KVA1(&bd) ;
2222
2223         /* Sync cache and physical memory */
2224         if(PIC32MZ_IF_RAM(in)) {
2225             XMEMCPY((void *)KVA0_TO_KVA1(in), (void *)in, sz);
2226         }
2227         XMEMSET((void *)KVA0_TO_KVA1(out), 0, sz);
2228         /* Set up the Security Association */
2229         XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa));
2230         sa_p->SA_CTRL.ALGO = algo ; /* AES */
2231         sa_p->SA_CTRL.LNC = 1;
2232         sa_p->SA_CTRL.LOADIV = 1;
2233         sa_p->SA_CTRL.FB = 1;
2234         sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */
2235         sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
2236
2237         if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM){
2238             switch(aes->keylen) {
2239             case 32:
2240                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_256 ;
2241                 break ;
2242             case 24:
2243                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_192 ;
2244                 break ;
2245             case 16:
2246                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
2247                 break ;
2248             }
2249         } else
2250             sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
2251
2252         ByteReverseWords(
2253         (word32 *)KVA0_TO_KVA1(sa.SA_ENCKEY + 8 - aes->keylen/sizeof(word32)),
2254                          (word32 *)aes->key_ce, aes->keylen);
2255         ByteReverseWords(
2256         (word32*)KVA0_TO_KVA1(sa.SA_ENCIV), (word32 *)aes->iv_ce, 16);
2257
2258         XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd));
2259         /* Set up the Buffer Descriptor */
2260         bd_p->BD_CTRL.BUFLEN = sz;
2261         if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM) {
2262             if(sz % 0x10)
2263                 bd_p->BD_CTRL.BUFLEN = (sz/0x10 + 1) * 0x10 ;
2264         }
2265         bd_p->BD_CTRL.LIFM = 1;
2266         bd_p->BD_CTRL.SA_FETCH_EN = 1;
2267         bd_p->BD_CTRL.LAST_BD = 1;
2268         bd_p->BD_CTRL.DESC_EN = 1;
2269
2270         bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ;
2271         bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ;
2272         bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out);
2273         bd_p->MSGLEN = sz ;
2274
2275         CECON = 1 << 6;
2276         while (CECON);
2277
2278         /* Run the engine */
2279         CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ;
2280         CEINTEN = 0x07;
2281         CECON = 0x27;
2282
2283         WAIT_ENGINE ;
2284
2285         if((cryptoalgo == PIC32_CRYPTOALGO_CBC) ||
2286            (cryptoalgo == PIC32_CRYPTOALGO_TCBC)||
2287            (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
2288             /* set iv for the next call */
2289             if(dir == PIC32_ENCRYPTION) {
2290                 XMEMCPY((void *)aes->iv_ce,
2291                         (void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE),
2292                         AES_BLOCK_SIZE) ;
2293             } else {
2294                 ByteReverseWords((word32*)aes->iv_ce,
2295                         (word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE),
2296                         AES_BLOCK_SIZE);
2297             }
2298         }
2299         XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ;
2300         ByteReverseWords((word32*)out, (word32 *)out, sz);
2301     }
2302
2303     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2304     {
2305         wc_AesCrypt(aes, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_AES,
2306                                                       PIC32_CRYPTOALGO_RCBC );
2307         return 0 ;
2308     }
2309
2310     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2311     {
2312         wc_AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES,
2313                                                       PIC32_CRYPTOALGO_RCBC);
2314         return 0 ;
2315     }
2316
2317 #else
2318     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2319     {
2320         word32 blocks = sz / AES_BLOCK_SIZE;
2321
2322     #ifdef HAVE_CAVIUM
2323         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
2324             return wc_AesCaviumCbcEncrypt(aes, out, in, sz);
2325     #endif
2326
2327     #ifdef WOLFSSL_AESNI
2328         if (haveAESNI) {
2329             #ifdef DEBUG_AESNI
2330                 printf("about to aes cbc encrypt\n");
2331                 printf("in  = %p\n", in);
2332                 printf("out = %p\n", out);
2333                 printf("aes->key = %p\n", aes->key);
2334                 printf("aes->reg = %p\n", aes->reg);
2335                 printf("aes->rounds = %d\n", aes->rounds);
2336                 printf("sz = %d\n", sz);
2337             #endif
2338
2339             /* check alignment, decrypt doesn't need alignment */
2340             if ((wolfssl_word)in % 16) {
2341             #ifndef NO_WOLFSSL_ALLOC_ALIGN
2342                 byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2343                 WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
2344                 if (tmp == NULL) return MEMORY_E;
2345
2346                 XMEMCPY(tmp, in, sz);
2347                 AES_CBC_encrypt(tmp, tmp, (byte*)aes->reg, sz, (byte*)aes->key,
2348                             aes->rounds);
2349                 /* store iv for next call */
2350                 XMEMCPY(aes->reg, tmp + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
2351
2352                 XMEMCPY(out, tmp, sz);
2353                 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2354                 return 0;
2355             #else
2356                 return BAD_ALIGN_E;
2357             #endif
2358             }
2359
2360             AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
2361                             aes->rounds);
2362             /* store iv for next call */
2363             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
2364
2365             return 0;
2366         }
2367     #endif
2368
2369         while (blocks--) {
2370             xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
2371             wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
2372             XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
2373
2374             out += AES_BLOCK_SIZE;
2375             in  += AES_BLOCK_SIZE;
2376         }
2377
2378         return 0;
2379     }
2380
2381     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2382     {
2383         word32 blocks = sz / AES_BLOCK_SIZE;
2384
2385     #ifdef HAVE_CAVIUM
2386         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
2387             return wc_AesCaviumCbcDecrypt(aes, out, in, sz);
2388     #endif
2389
2390     #ifdef WOLFSSL_AESNI
2391         if (haveAESNI) {
2392             #ifdef DEBUG_AESNI
2393                 printf("about to aes cbc decrypt\n");
2394                 printf("in  = %p\n", in);
2395                 printf("out = %p\n", out);
2396                 printf("aes->key = %p\n", aes->key);
2397                 printf("aes->reg = %p\n", aes->reg);
2398                 printf("aes->rounds = %d\n", aes->rounds);
2399                 printf("sz = %d\n", sz);
2400             #endif
2401
2402             /* if input and output same will overwrite input iv */
2403             XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
2404             AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
2405                             aes->rounds);
2406             /* store iv for next call */
2407             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
2408             return 0;
2409         }
2410     #endif
2411
2412         while (blocks--) {
2413             XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
2414             wc_AesDecrypt(aes, (byte*)aes->tmp, out);
2415             xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
2416             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
2417
2418             out += AES_BLOCK_SIZE;
2419             in  += AES_BLOCK_SIZE;
2420         }
2421
2422         return 0;
2423     }
2424
2425 #endif /* STM32F2_CRYPTO, AES-CBC block */
2426
2427 /* AES-CTR */
2428 #ifdef WOLFSSL_AES_COUNTER
2429
2430     #ifdef STM32F2_CRYPTO
2431         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2432         {
2433             word32 *enc_key, *iv;
2434             CRYP_InitTypeDef AES_CRYP_InitStructure;
2435             CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
2436             CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
2437
2438             enc_key = aes->key;
2439             iv = aes->reg;
2440
2441             /* crypto structure initialization */
2442             CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
2443             CRYP_StructInit(&AES_CRYP_InitStructure);
2444             CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
2445
2446             /* reset registers to their default values */
2447             CRYP_DeInit();
2448
2449             /* load key into correct registers */
2450             switch(aes->rounds)
2451             {
2452                 case 10: /* 128-bit key */
2453                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
2454                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
2455                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
2456                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
2457                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
2458                     break;
2459
2460                 case 12: /* 192-bit key */
2461                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
2462                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
2463                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
2464                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
2465                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
2466                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
2467                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
2468                     break;
2469
2470                 case 14: /* 256-bit key */
2471                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
2472                     AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
2473                     AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
2474                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
2475                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
2476                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
2477                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
2478                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
2479                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
2480                     break;
2481
2482                 default:
2483                     break;
2484             }
2485             CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
2486
2487             /* set iv */
2488             ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
2489             AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
2490             AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
2491             AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
2492             AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
2493             CRYP_IVInit(&AES_CRYP_IVInitStructure);
2494
2495             /* set direction, mode, and datatype */
2496             AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
2497             AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
2498             AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
2499             CRYP_Init(&AES_CRYP_InitStructure);
2500
2501             /* enable crypto processor */
2502             CRYP_Cmd(ENABLE);
2503
2504             while (sz > 0)
2505             {
2506                 /* flush IN/OUT FIFOs */
2507                 CRYP_FIFOFlush();
2508
2509                 CRYP_DataIn(*(uint32_t*)&in[0]);
2510                 CRYP_DataIn(*(uint32_t*)&in[4]);
2511                 CRYP_DataIn(*(uint32_t*)&in[8]);
2512                 CRYP_DataIn(*(uint32_t*)&in[12]);
2513
2514                 /* wait until the complete message has been processed */
2515                 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
2516
2517                 *(uint32_t*)&out[0]  = CRYP_DataOut();
2518                 *(uint32_t*)&out[4]  = CRYP_DataOut();
2519                 *(uint32_t*)&out[8]  = CRYP_DataOut();
2520                 *(uint32_t*)&out[12] = CRYP_DataOut();
2521
2522                 /* store iv for next call */
2523                 XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
2524
2525                 sz  -= 16;
2526                 in  += 16;
2527                 out += 16;
2528             }
2529
2530             /* disable crypto processor */
2531             CRYP_Cmd(DISABLE);
2532         }
2533
2534     #elif defined(WOLFSSL_PIC32MZ_CRYPT)
2535         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2536         {
2537             int i ;
2538             char out_block[AES_BLOCK_SIZE] ;
2539             int odd ;
2540             int even ;
2541             char *tmp ; /* (char *)aes->tmp, for short */
2542
2543             tmp = (char *)aes->tmp ;
2544             if(aes->left) {
2545                 if((aes->left + sz) >= AES_BLOCK_SIZE){
2546                     odd = AES_BLOCK_SIZE - aes->left ;
2547                 } else {
2548                     odd = sz ;
2549                 }
2550                 XMEMCPY(tmp+aes->left, in, odd) ;
2551                 if((odd+aes->left) == AES_BLOCK_SIZE){
2552                     wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
2553                         PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
2554                     XMEMCPY(out, out_block+aes->left, odd) ;
2555                     aes->left = 0 ;
2556                     XMEMSET(tmp, 0x0, AES_BLOCK_SIZE) ;
2557                     /* Increment IV */
2558                     for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
2559                         if (++((byte *)aes->iv_ce)[i])
2560                             break ;
2561                     }
2562                 }
2563                 in += odd ;
2564                 out+= odd ;
2565                 sz -= odd ;
2566             }
2567             odd = sz % AES_BLOCK_SIZE ;  /* if there is tail flagment */
2568             if(sz / AES_BLOCK_SIZE) {
2569                 even = (sz/AES_BLOCK_SIZE)*AES_BLOCK_SIZE ;
2570                 wc_AesCrypt(aes, out, in, even, PIC32_ENCRYPTION, PIC32_ALGO_AES,
2571                                                         PIC32_CRYPTOALGO_RCTR);
2572                 out += even ;
2573                 in  += even ;
2574                 do {  /* Increment IV */
2575                     for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
2576                         if (++((byte *)aes->iv_ce)[i])
2577                             break ;
2578                     }
2579                     even -= AES_BLOCK_SIZE ;
2580                 } while((int)even > 0) ;
2581             }
2582             if(odd) {
2583                 XMEMSET(tmp+aes->left, 0x0, AES_BLOCK_SIZE - aes->left) ;
2584                 XMEMCPY(tmp+aes->left, in, odd) ;
2585                 wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
2586                         PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
2587                 XMEMCPY(out, out_block+aes->left,odd) ;
2588                 aes->left += odd ;
2589             }
2590         }
2591
2592     #elif defined(HAVE_COLDFIRE_SEC)
2593         #error "Coldfire SEC doesn't currently support AES-CTR mode"
2594
2595     #elif defined(FREESCALE_MMCAU)
2596         #error "Freescale mmCAU doesn't currently support AES-CTR mode"
2597
2598     #else
2599         /* Increment AES counter */
2600         static INLINE void IncrementAesCounter(byte* inOutCtr)
2601         {
2602             int i;
2603
2604             /* in network byte order so start at end and work back */
2605             for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
2606                 if (++inOutCtr[i])  /* we're done unless we overflow */
2607                     return;
2608             }
2609         }
2610
2611         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
2612         {
2613             byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
2614
2615             /* consume any unused bytes left in aes->tmp */
2616             while (aes->left && sz) {
2617                *(out++) = *(in++) ^ *(tmp++);
2618                aes->left--;
2619                sz--;
2620             }
2621
2622             /* do as many block size ops as possible */
2623             while (sz >= AES_BLOCK_SIZE) {
2624                 wc_AesEncrypt(aes, (byte*)aes->reg, out);
2625                 IncrementAesCounter((byte*)aes->reg);
2626                 xorbuf(out, in, AES_BLOCK_SIZE);
2627
2628                 out += AES_BLOCK_SIZE;
2629                 in  += AES_BLOCK_SIZE;
2630                 sz  -= AES_BLOCK_SIZE;
2631                 aes->left = 0;
2632             }
2633
2634             /* handle non block size remaining and sotre unused byte count in left */
2635             if (sz) {
2636                 wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
2637                 IncrementAesCounter((byte*)aes->reg);
2638
2639                 aes->left = AES_BLOCK_SIZE;
2640                 tmp = (byte*)aes->tmp;
2641
2642                 while (sz--) {
2643                     *(out++) = *(in++) ^ *(tmp++);
2644                     aes->left--;
2645                 }
2646             }
2647         }
2648
2649     #endif /* STM32F2_CRYPTO, AES-CTR block */
2650
2651 #endif /* WOLFSSL_AES_COUNTER */
2652
2653 #ifdef HAVE_AESGCM
2654
2655 /*
2656  * The IV for AES GCM, stored in struct Aes's member reg, is comprised of
2657  * three parts in order:
2658  *   1. The implicit IV. This is generated from the PRF using the shared
2659  *      secrets between endpoints. It is 4 bytes long.
2660  *   2. The explicit IV. This is set by the user of the AES. It needs to be
2661  *      unique for each call to encrypt. The explicit IV is shared with the
2662  *      other end of the transaction in the clear.
2663  *   3. The counter. Each block of data is encrypted with its own sequence
2664  *      number counter.
2665  */
2666
2667 #ifdef STM32F2_CRYPTO
2668     #error "STM32F2 crypto doesn't currently support AES-GCM mode"
2669
2670 #elif defined(HAVE_COLDFIRE_SEC)
2671     #error "Coldfire SEC doesn't currently support AES-GCM mode"
2672
2673 #endif
2674
2675 enum {
2676     CTR_SZ = 4
2677 };
2678
2679
2680 static INLINE void InitGcmCounter(byte* inOutCtr)
2681 {
2682     inOutCtr[AES_BLOCK_SIZE - 4] = 0;
2683     inOutCtr[AES_BLOCK_SIZE - 3] = 0;
2684     inOutCtr[AES_BLOCK_SIZE - 2] = 0;
2685     inOutCtr[AES_BLOCK_SIZE - 1] = 1;
2686 }
2687
2688
2689 static INLINE void IncrementGcmCounter(byte* inOutCtr)
2690 {
2691     int i;
2692
2693     /* in network byte order so start at end and work back */
2694     for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
2695         if (++inOutCtr[i])  /* we're done unless we overflow */
2696             return;
2697     }
2698 }
2699
2700
2701 #if defined(GCM_SMALL) || defined(GCM_TABLE)
2702
2703 static INLINE void FlattenSzInBits(byte* buf, word32 sz)
2704 {
2705     /* Multiply the sz by 8 */
2706     word32 szHi = (sz >> (8*sizeof(sz) - 3));
2707     sz <<= 3;
2708
2709     /* copy over the words of the sz into the destination buffer */
2710     buf[0] = (szHi >> 24) & 0xff;
2711     buf[1] = (szHi >> 16) & 0xff;
2712     buf[2] = (szHi >>  8) & 0xff;
2713     buf[3] = szHi & 0xff;
2714     buf[4] = (sz >> 24) & 0xff;
2715     buf[5] = (sz >> 16) & 0xff;
2716     buf[6] = (sz >>  8) & 0xff;
2717     buf[7] = sz & 0xff;
2718 }
2719
2720
2721 static INLINE void RIGHTSHIFTX(byte* x)
2722 {
2723     int i;
2724     int carryOut = 0;
2725     int carryIn = 0;
2726     int borrow = x[15] & 0x01;
2727
2728     for (i = 0; i < AES_BLOCK_SIZE; i++) {
2729         carryOut = x[i] & 0x01;
2730         x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
2731         carryIn = carryOut;
2732     }
2733     if (borrow) x[0] ^= 0xE1;
2734 }
2735
2736 #endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
2737
2738
2739 #ifdef GCM_TABLE
2740
2741 static void GenerateM0(Aes* aes)
2742 {
2743     int i, j;
2744     byte (*m)[AES_BLOCK_SIZE] = aes->M0;
2745
2746     XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
2747
2748     for (i = 64; i > 0; i /= 2) {
2749         XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
2750         RIGHTSHIFTX(m[i]);
2751     }
2752
2753     for (i = 2; i < 256; i *= 2) {
2754         for (j = 1; j < i; j++) {
2755             XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
2756             xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
2757         }
2758     }
2759
2760     XMEMSET(m[0], 0, AES_BLOCK_SIZE);
2761 }
2762
2763 #endif /* GCM_TABLE */
2764
2765
2766 int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
2767 {
2768     int  ret;
2769     byte iv[AES_BLOCK_SIZE];
2770
2771     #ifdef FREESCALE_MMCAU
2772         byte* rk = (byte*)aes->key;
2773     #endif
2774
2775     if (!((len == 16) || (len == 24) || (len == 32)))
2776         return BAD_FUNC_ARG;
2777
2778     XMEMSET(iv, 0, AES_BLOCK_SIZE);
2779     ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
2780
2781     if (ret == 0) {
2782     #ifdef FREESCALE_MMCAU
2783         cau_aes_encrypt(iv, rk, aes->rounds, aes->H);
2784     #else
2785         wc_AesEncrypt(aes, iv, aes->H);
2786     #endif
2787     #ifdef GCM_TABLE
2788         GenerateM0(aes);
2789     #endif /* GCM_TABLE */
2790     }
2791
2792     return ret;
2793 }
2794
2795
2796 #if defined(GCM_SMALL)
2797
2798 static void GMULT(byte* X, byte* Y)
2799 {
2800     byte Z[AES_BLOCK_SIZE];
2801     byte V[AES_BLOCK_SIZE];
2802     int i, j;
2803
2804     XMEMSET(Z, 0, AES_BLOCK_SIZE);
2805     XMEMCPY(V, X, AES_BLOCK_SIZE);
2806     for (i = 0; i < AES_BLOCK_SIZE; i++)
2807     {
2808         byte y = Y[i];
2809         for (j = 0; j < 8; j++)
2810         {
2811             if (y & 0x80) {
2812                 xorbuf(Z, V, AES_BLOCK_SIZE);
2813             }
2814
2815             RIGHTSHIFTX(V);
2816             y = y << 1;
2817         }
2818     }
2819     XMEMCPY(X, Z, AES_BLOCK_SIZE);
2820 }
2821
2822
2823 static void GHASH(Aes* aes, const byte* a, word32 aSz,
2824                                 const byte* c, word32 cSz, byte* s, word32 sSz)
2825 {
2826     byte x[AES_BLOCK_SIZE];
2827     byte scratch[AES_BLOCK_SIZE];
2828     word32 blocks, partial;
2829     byte* h = aes->H;
2830
2831     XMEMSET(x, 0, AES_BLOCK_SIZE);
2832
2833     /* Hash in A, the Additional Authentication Data */
2834     if (aSz != 0 && a != NULL) {
2835         blocks = aSz / AES_BLOCK_SIZE;
2836         partial = aSz % AES_BLOCK_SIZE;
2837         while (blocks--) {
2838             xorbuf(x, a, AES_BLOCK_SIZE);
2839             GMULT(x, h);
2840             a += AES_BLOCK_SIZE;
2841         }
2842         if (partial != 0) {
2843             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
2844             XMEMCPY(scratch, a, partial);
2845             xorbuf(x, scratch, AES_BLOCK_SIZE);
2846             GMULT(x, h);
2847         }
2848     }
2849
2850     /* Hash in C, the Ciphertext */
2851     if (cSz != 0 && c != NULL) {
2852         blocks = cSz / AES_BLOCK_SIZE;
2853         partial = cSz % AES_BLOCK_SIZE;
2854         while (blocks--) {
2855             xorbuf(x, c, AES_BLOCK_SIZE);
2856             GMULT(x, h);
2857             c += AES_BLOCK_SIZE;
2858         }
2859         if (partial != 0) {
2860             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
2861             XMEMCPY(scratch, c, partial);
2862             xorbuf(x, scratch, AES_BLOCK_SIZE);
2863             GMULT(x, h);
2864         }
2865     }
2866
2867     /* Hash in the lengths of A and C in bits */
2868     FlattenSzInBits(&scratch[0], aSz);
2869     FlattenSzInBits(&scratch[8], cSz);
2870     xorbuf(x, scratch, AES_BLOCK_SIZE);
2871     GMULT(x, h);
2872
2873     /* Copy the result into s. */
2874     XMEMCPY(s, x, sSz);
2875 }
2876
2877 /* end GCM_SMALL */
2878 #elif defined(GCM_TABLE)
2879
2880 static const byte R[256][2] = {
2881     {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
2882     {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
2883     {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
2884     {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
2885     {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
2886     {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
2887     {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
2888     {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
2889     {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
2890     {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
2891     {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
2892     {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
2893     {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
2894     {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
2895     {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
2896     {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
2897     {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
2898     {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
2899     {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
2900     {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
2901     {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
2902     {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
2903     {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
2904     {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
2905     {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
2906     {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
2907     {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
2908     {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
2909     {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
2910     {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
2911     {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
2912     {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
2913     {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
2914     {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
2915     {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
2916     {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
2917     {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
2918     {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
2919     {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
2920     {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
2921     {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
2922     {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
2923     {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
2924     {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
2925     {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
2926     {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
2927     {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
2928     {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
2929     {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
2930     {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
2931     {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
2932     {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
2933     {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
2934     {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
2935     {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
2936     {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
2937     {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
2938     {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
2939     {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
2940     {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
2941     {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
2942     {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
2943     {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
2944     {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
2945
2946
2947 static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
2948 {
2949     int i, j;
2950     byte Z[AES_BLOCK_SIZE];
2951     byte a;
2952
2953     XMEMSET(Z, 0, sizeof(Z));
2954
2955     for (i = 15; i > 0; i--) {
2956         xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
2957         a = Z[15];
2958
2959         for (j = 15; j > 0; j--) {
2960             Z[j] = Z[j-1];
2961         }
2962
2963         Z[0] = R[a][0];
2964         Z[1] ^= R[a][1];
2965     }
2966     xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
2967
2968     XMEMCPY(x, Z, AES_BLOCK_SIZE);
2969 }
2970
2971
2972 static void GHASH(Aes* aes, const byte* a, word32 aSz,
2973                                 const byte* c, word32 cSz, byte* s, word32 sSz)
2974 {
2975     byte x[AES_BLOCK_SIZE];
2976     byte scratch[AES_BLOCK_SIZE];
2977     word32 blocks, partial;
2978
2979     XMEMSET(x, 0, AES_BLOCK_SIZE);
2980
2981     /* Hash in A, the Additional Authentication Data */
2982     if (aSz != 0 && a != NULL) {
2983         blocks = aSz / AES_BLOCK_SIZE;
2984         partial = aSz % AES_BLOCK_SIZE;
2985         while (blocks--) {
2986             xorbuf(x, a, AES_BLOCK_SIZE);
2987             GMULT(x, aes->M0);
2988             a += AES_BLOCK_SIZE;
2989         }
2990         if (partial != 0) {
2991             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
2992             XMEMCPY(scratch, a, partial);
2993             xorbuf(x, scratch, AES_BLOCK_SIZE);
2994             GMULT(x, aes->M0);
2995         }
2996     }
2997
2998     /* Hash in C, the Ciphertext */
2999     if (cSz != 0 && c != NULL) {
3000         blocks = cSz / AES_BLOCK_SIZE;
3001         partial = cSz % AES_BLOCK_SIZE;
3002         while (blocks--) {
3003             xorbuf(x, c, AES_BLOCK_SIZE);
3004             GMULT(x, aes->M0);
3005             c += AES_BLOCK_SIZE;
3006         }
3007         if (partial != 0) {
3008             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
3009             XMEMCPY(scratch, c, partial);
3010             xorbuf(x, scratch, AES_BLOCK_SIZE);
3011             GMULT(x, aes->M0);
3012         }
3013     }
3014
3015     /* Hash in the lengths of A and C in bits */
3016     FlattenSzInBits(&scratch[0], aSz);
3017     FlattenSzInBits(&scratch[8], cSz);
3018     xorbuf(x, scratch, AES_BLOCK_SIZE);
3019     GMULT(x, aes->M0);
3020
3021     /* Copy the result into s. */
3022     XMEMCPY(s, x, sSz);
3023 }
3024
3025 /* end GCM_TABLE */
3026 #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
3027
3028 static void GMULT(word64* X, word64* Y)
3029 {
3030     word64 Z[2] = {0,0};
3031     word64 V[2] ; 
3032     int i, j;
3033     V[0] = X[0] ;  V[1] = X[1] ;
3034
3035     for (i = 0; i < 2; i++)
3036     {
3037         word64 y = Y[i];
3038         for (j = 0; j < 64; j++)
3039         {
3040             if (y & 0x8000000000000000ULL) {
3041                 Z[0] ^= V[0];
3042                 Z[1] ^= V[1];
3043             }
3044
3045             if (V[1] & 0x0000000000000001) {
3046                 V[1] >>= 1;
3047                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
3048                 V[0] >>= 1;
3049                 V[0] ^= 0xE100000000000000ULL;
3050             }
3051             else {
3052                 V[1] >>= 1;
3053                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
3054                 V[0] >>= 1;
3055             }
3056             y <<= 1;
3057         }
3058     }
3059     X[0] = Z[0];
3060     X[1] = Z[1];
3061 }
3062
3063
3064 static void GHASH(Aes* aes, const byte* a, word32 aSz,
3065                                 const byte* c, word32 cSz, byte* s, word32 sSz)
3066 {
3067     word64 x[2] = {0,0};
3068     word32 blocks, partial;
3069     word64 bigH[2];
3070
3071     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
3072     #ifdef LITTLE_ENDIAN_ORDER
3073         ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE); 
3074     #endif
3075
3076     /* Hash in A, the Additional Authentication Data */
3077     if (aSz != 0 && a != NULL) {
3078         word64 bigA[2];
3079         blocks = aSz / AES_BLOCK_SIZE;
3080         partial = aSz % AES_BLOCK_SIZE;
3081         while (blocks--) {
3082             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
3083             #ifdef LITTLE_ENDIAN_ORDER
3084                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
3085             #endif
3086             x[0] ^= bigA[0];
3087             x[1] ^= bigA[1];
3088             GMULT(x, bigH);
3089             a += AES_BLOCK_SIZE;
3090         }
3091         if (partial != 0) {
3092             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
3093             XMEMCPY(bigA, a, partial);
3094             #ifdef LITTLE_ENDIAN_ORDER
3095                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
3096             #endif
3097             x[0] ^= bigA[0];
3098             x[1] ^= bigA[1];
3099             GMULT(x, bigH);
3100         }
3101     }
3102
3103     /* Hash in C, the Ciphertext */
3104     if (cSz != 0 && c != NULL) {
3105         word64 bigC[2];
3106         blocks = cSz / AES_BLOCK_SIZE;
3107         partial = cSz % AES_BLOCK_SIZE;
3108         while (blocks--) {
3109             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
3110             #ifdef LITTLE_ENDIAN_ORDER
3111                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
3112             #endif
3113             x[0] ^= bigC[0];
3114             x[1] ^= bigC[1];
3115             GMULT(x, bigH);
3116             c += AES_BLOCK_SIZE;
3117         }
3118         if (partial != 0) {
3119             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
3120             XMEMCPY(bigC, c, partial);
3121             #ifdef LITTLE_ENDIAN_ORDER
3122                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
3123             #endif
3124             x[0] ^= bigC[0];
3125             x[1] ^= bigC[1];
3126             GMULT(x, bigH);
3127         }
3128     }
3129
3130     /* Hash in the lengths in bits of A and C */
3131     {
3132         word64 len[2] ; 
3133         len[0] = aSz ; len[1] = cSz;
3134
3135         /* Lengths are in bytes. Convert to bits. */
3136         len[0] *= 8;
3137         len[1] *= 8;
3138
3139         x[0] ^= len[0];
3140         x[1] ^= len[1];
3141         GMULT(x, bigH);
3142     }
3143     #ifdef LITTLE_ENDIAN_ORDER
3144         ByteReverseWords64(x, x, AES_BLOCK_SIZE);
3145     #endif
3146     XMEMCPY(s, x, sSz);
3147 }
3148
3149 /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
3150 #else /* GCM_WORD32 */
3151
3152 static void GMULT(word32* X, word32* Y)
3153 {
3154     word32 Z[4] = {0,0,0,0};
3155     word32 V[4] ;
3156     int i, j;
3157
3158     V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
3159
3160     for (i = 0; i < 4; i++)
3161     {
3162         word32 y = Y[i];
3163         for (j = 0; j < 32; j++)
3164         {
3165             if (y & 0x80000000) {
3166                 Z[0] ^= V[0];
3167                 Z[1] ^= V[1];
3168                 Z[2] ^= V[2];
3169                 Z[3] ^= V[3];
3170             }
3171
3172             if (V[3] & 0x00000001) {
3173                 V[3] >>= 1;
3174                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
3175                 V[2] >>= 1;
3176                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
3177                 V[1] >>= 1;
3178                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
3179                 V[0] >>= 1;
3180                 V[0] ^= 0xE1000000;
3181             } else {
3182                 V[3] >>= 1;
3183                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
3184                 V[2] >>= 1;
3185                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
3186                 V[1] >>= 1;
3187                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
3188                 V[0] >>= 1;
3189             }
3190             y <<= 1;
3191         }
3192     }
3193     X[0] = Z[0];
3194     X[1] = Z[1];
3195     X[2] = Z[2];
3196     X[3] = Z[3];
3197 }
3198
3199
3200 static void GHASH(Aes* aes, const byte* a, word32 aSz,
3201                                 const byte* c, word32 cSz, byte* s, word32 sSz)
3202 {
3203     word32 x[4] = {0,0,0,0};
3204     word32 blocks, partial;
3205     word32 bigH[4];
3206
3207     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
3208     #ifdef LITTLE_ENDIAN_ORDER
3209         ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
3210     #endif
3211
3212     /* Hash in A, the Additional Authentication Data */
3213     if (aSz != 0 && a != NULL) {
3214         word32 bigA[4];
3215         blocks = aSz / AES_BLOCK_SIZE;
3216         partial = aSz % AES_BLOCK_SIZE;
3217         while (blocks--) {
3218             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
3219             #ifdef LITTLE_ENDIAN_ORDER
3220                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
3221             #endif
3222             x[0] ^= bigA[0];
3223             x[1] ^= bigA[1];
3224             x[2] ^= bigA[2];
3225             x[3] ^= bigA[3];
3226             GMULT(x, bigH);
3227             a += AES_BLOCK_SIZE;
3228         }
3229         if (partial != 0) {
3230             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
3231             XMEMCPY(bigA, a, partial);
3232             #ifdef LITTLE_ENDIAN_ORDER
3233                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
3234             #endif
3235             x[0] ^= bigA[0];
3236             x[1] ^= bigA[1];
3237             x[2] ^= bigA[2];
3238             x[3] ^= bigA[3];
3239             GMULT(x, bigH);
3240         }
3241     }
3242
3243     /* Hash in C, the Ciphertext */
3244     if (cSz != 0 && c != NULL) {
3245         word32 bigC[4];
3246         blocks = cSz / AES_BLOCK_SIZE;
3247         partial = cSz % AES_BLOCK_SIZE;
3248         while (blocks--) {
3249             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
3250             #ifdef LITTLE_ENDIAN_ORDER
3251                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
3252             #endif
3253             x[0] ^= bigC[0];
3254             x[1] ^= bigC[1];
3255             x[2] ^= bigC[2];
3256             x[3] ^= bigC[3];
3257             GMULT(x, bigH);
3258             c += AES_BLOCK_SIZE;
3259         }
3260         if (partial != 0) {
3261             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
3262             XMEMCPY(bigC, c, partial);
3263             #ifdef LITTLE_ENDIAN_ORDER
3264                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
3265             #endif
3266             x[0] ^= bigC[0];
3267             x[1] ^= bigC[1];
3268             x[2] ^= bigC[2];
3269             x[3] ^= bigC[3];
3270             GMULT(x, bigH);
3271         }
3272     }
3273
3274     /* Hash in the lengths in bits of A and C */
3275     {
3276         word32 len[4];
3277
3278         /* Lengths are in bytes. Convert to bits. */
3279         len[0] = (aSz >> (8*sizeof(aSz) - 3));
3280         len[1] = aSz << 3;
3281         len[2] = (cSz >> (8*sizeof(cSz) - 3));
3282         len[3] = cSz << 3;
3283
3284         x[0] ^= len[0];
3285         x[1] ^= len[1];
3286         x[2] ^= len[2];
3287         x[3] ^= len[3];
3288         GMULT(x, bigH);
3289     }
3290     #ifdef LITTLE_ENDIAN_ORDER
3291         ByteReverseWords(x, x, AES_BLOCK_SIZE);
3292     #endif
3293     XMEMCPY(s, x, sSz);
3294 }
3295
3296 #endif /* end GCM_WORD32 */
3297
3298
3299 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
3300                    const byte* iv, word32 ivSz,
3301                    byte* authTag, word32 authTagSz,
3302                    const byte* authIn, word32 authInSz)
3303 {
3304     word32 blocks = sz / AES_BLOCK_SIZE;
3305     word32 partial = sz % AES_BLOCK_SIZE;
3306     const byte* p = in;
3307     byte* c = out;
3308     byte counter[AES_BLOCK_SIZE];
3309     byte *ctr ;
3310     byte scratch[AES_BLOCK_SIZE];
3311
3312 #ifdef FREESCALE_MMCAU
3313     byte* key = (byte*)aes->key;
3314 #endif
3315
3316     WOLFSSL_ENTER("AesGcmEncrypt");
3317
3318 #ifdef WOLFSSL_PIC32MZ_CRYPT
3319     ctr = (char *)aes->iv_ce ;
3320 #else
3321     ctr = counter ;
3322 #endif
3323
3324     XMEMSET(ctr, 0, AES_BLOCK_SIZE);
3325     XMEMCPY(ctr, iv, ivSz);
3326     InitGcmCounter(ctr);
3327
3328 #ifdef WOLFSSL_PIC32MZ_CRYPT
3329     if(blocks)
3330         wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
3331              PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
3332 #endif
3333     while (blocks--) {
3334         IncrementGcmCounter(ctr);
3335         #ifndef WOLFSSL_PIC32MZ_CRYPT
3336             #ifdef FREESCALE_MMCAU
3337                 cau_aes_encrypt(ctr, key, aes->rounds, scratch);
3338             #else
3339                 wc_AesEncrypt(aes, ctr, scratch);
3340             #endif
3341         xorbuf(scratch, p, AES_BLOCK_SIZE);
3342         XMEMCPY(c, scratch, AES_BLOCK_SIZE);
3343         #endif
3344         p += AES_BLOCK_SIZE;
3345         c += AES_BLOCK_SIZE;
3346     }
3347
3348     if (partial != 0) {
3349         IncrementGcmCounter(ctr);
3350         #ifdef FREESCALE_MMCAU
3351             cau_aes_encrypt(ctr, key, aes->rounds, scratch);
3352         #else
3353             wc_AesEncrypt(aes, ctr, scratch);
3354         #endif
3355         xorbuf(scratch, p, partial);
3356         XMEMCPY(c, scratch, partial);
3357
3358     }
3359
3360     GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
3361     InitGcmCounter(ctr);
3362     #ifdef FREESCALE_MMCAU
3363         cau_aes_encrypt(ctr, key, aes->rounds, scratch);
3364     #else
3365         wc_AesEncrypt(aes, ctr, scratch);
3366     #endif
3367     xorbuf(authTag, scratch, authTagSz);
3368
3369     return 0;
3370 }
3371
3372
3373 int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
3374                    const byte* iv, word32 ivSz,
3375                    const byte* authTag, word32 authTagSz,
3376                    const byte* authIn, word32 authInSz)
3377 {
3378     word32 blocks = sz / AES_BLOCK_SIZE;
3379     word32 partial = sz % AES_BLOCK_SIZE;
3380     const byte* c = in;
3381     byte* p = out;
3382     byte counter[AES_BLOCK_SIZE];
3383     byte *ctr ;
3384     byte scratch[AES_BLOCK_SIZE];
3385
3386 #ifdef FREESCALE_MMCAU
3387     byte* key = (byte*)aes->key;
3388 #endif
3389
3390     WOLFSSL_ENTER("AesGcmDecrypt");
3391
3392 #ifdef WOLFSSL_PIC32MZ_CRYPT
3393     ctr = (char *)aes->iv_ce ;
3394 #else
3395     ctr = counter ;
3396 #endif
3397
3398     XMEMSET(ctr, 0, AES_BLOCK_SIZE);
3399     XMEMCPY(ctr, iv, ivSz);
3400     InitGcmCounter(ctr);
3401
3402     /* Calculate the authTag again using the received auth data and the
3403      * cipher text. */
3404     {
3405         byte Tprime[AES_BLOCK_SIZE];
3406         byte EKY0[AES_BLOCK_SIZE];
3407
3408         GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
3409         #ifdef FREESCALE_MMCAU
3410             cau_aes_encrypt(ctr, key, aes->rounds, EKY0);
3411         #else
3412             wc_AesEncrypt(aes, ctr, EKY0);
3413         #endif
3414         xorbuf(Tprime, EKY0, sizeof(Tprime));
3415
3416         if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
3417             return AES_GCM_AUTH_E;
3418         }
3419     }
3420
3421 #ifdef WOLFSSL_PIC32MZ_CRYPT
3422     if(blocks)
3423         wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
3424              PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
3425 #endif
3426
3427     while (blocks--) {
3428         IncrementGcmCounter(ctr);
3429         #ifndef WOLFSSL_PIC32MZ_CRYPT
3430             #ifdef FREESCALE_MMCAU
3431                 cau_aes_encrypt(ctr, key, aes->rounds, scratch);
3432             #else
3433                 wc_AesEncrypt(aes, ctr, scratch);
3434             #endif
3435         xorbuf(scratch, c, AES_BLOCK_SIZE);
3436         XMEMCPY(p, scratch, AES_BLOCK_SIZE);
3437         #endif
3438         p += AES_BLOCK_SIZE;
3439         c += AES_BLOCK_SIZE;
3440     }
3441     if (partial != 0) {
3442         IncrementGcmCounter(ctr);
3443         #ifdef FREESCALE_MMCAU
3444             cau_aes_encrypt(ctr, key, aes->rounds, scratch);
3445         #else
3446             wc_AesEncrypt(aes, ctr, scratch);
3447         #endif
3448         xorbuf(scratch, c, partial);
3449         XMEMCPY(p, scratch, partial);
3450     }
3451     return 0;
3452 }
3453
3454
3455
3456 WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
3457 {
3458     return wc_AesGcmSetKey(&gmac->aes, key, len);
3459 }
3460
3461
3462 WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
3463                               const byte* authIn, word32 authInSz,
3464                               byte* authTag, word32 authTagSz)
3465 {
3466     return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
3467                                          authTag, authTagSz, authIn, authInSz);
3468 }
3469
3470 #endif /* HAVE_AESGCM */
3471
3472
3473 #ifdef HAVE_AESCCM
3474
3475 #ifdef STM32F2_CRYPTO
3476     #error "STM32F2 crypto doesn't currently support AES-CCM mode"
3477
3478 #elif defined(HAVE_COLDFIRE_SEC)
3479     #error "Coldfire SEC doesn't currently support AES-CCM mode"
3480
3481 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
3482     #error "PIC32MZ doesn't currently support AES-CCM mode"
3483
3484 #endif
3485
3486 void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
3487 {
3488     byte nonce[AES_BLOCK_SIZE];
3489
3490     if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
3491         return;
3492
3493     XMEMSET(nonce, 0, sizeof(nonce));
3494     wc_AesSetKey(aes, key, keySz, nonce, AES_ENCRYPTION);
3495 }
3496
3497
3498 static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
3499 {
3500     #ifdef FREESCALE_MMCAU
3501         byte* key = (byte*)aes->key;
3502     #endif
3503
3504     /* process the bulk of the data */
3505     while (inSz >= AES_BLOCK_SIZE) {
3506         xorbuf(out, in, AES_BLOCK_SIZE);
3507         in += AES_BLOCK_SIZE;
3508         inSz -= AES_BLOCK_SIZE;
3509
3510         #ifdef FREESCALE_MMCAU
3511             cau_aes_encrypt(out, key, aes->rounds, out);
3512         #else
3513             wc_AesEncrypt(aes, out, out);
3514         #endif
3515     }
3516
3517     /* process remainder of the data */
3518     if (inSz > 0) {
3519         xorbuf(out, in, inSz);
3520         #ifdef FREESCALE_MMCAU
3521             cau_aes_encrypt(out, key, aes->rounds, out);
3522         #else
3523             wc_AesEncrypt(aes, out, out);
3524         #endif
3525     }
3526 }
3527
3528
3529 static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)
3530 {
3531     word32 authLenSz;
3532     word32 remainder;
3533
3534     #ifdef FREESCALE_MMCAU
3535         byte* key = (byte*)aes->key;
3536     #endif
3537
3538     /* encode the length in */
3539     if (inSz <= 0xFEFF) {
3540         authLenSz = 2;
3541         out[0] ^= ((inSz & 0xFF00) >> 8);
3542         out[1] ^=  (inSz & 0x00FF);
3543     }
3544     else if (inSz <= 0xFFFFFFFF) {
3545         authLenSz = 6;
3546         out[0] ^= 0xFF; out[1] ^= 0xFE;
3547         out[2] ^= ((inSz & 0xFF000000) >> 24);
3548         out[3] ^= ((inSz & 0x00FF0000) >> 16);
3549         out[4] ^= ((inSz & 0x0000FF00) >>  8);
3550         out[5] ^=  (inSz & 0x000000FF);
3551     }
3552     /* Note, the protocol handles auth data up to 2^64, but we are
3553      * using 32-bit sizes right now, so the bigger data isn't handled
3554      * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
3555     else
3556         return;
3557
3558     /* start fill out the rest of the first block */
3559     remainder = AES_BLOCK_SIZE - authLenSz;
3560     if (inSz >= remainder) {
3561         /* plenty of bulk data to fill the remainder of this block */
3562         xorbuf(out + authLenSz, in, remainder);
3563         inSz -= remainder;
3564         in += remainder;
3565     }
3566     else {
3567         /* not enough bulk data, copy what is available, and pad zero */
3568         xorbuf(out + authLenSz, in, inSz);
3569         inSz = 0;
3570     }
3571     #ifdef FREESCALE_MMCAU
3572         cau_aes_encrypt(out, key, aes->rounds, out);
3573     #else
3574         wc_AesEncrypt(aes, out, out);
3575     #endif
3576
3577     if (inSz > 0)
3578         roll_x(aes, in, inSz, out);
3579 }
3580
3581
3582 static INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
3583 {
3584     word32 i;
3585
3586     for (i = 0; i < lenSz; i++) {
3587         if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
3588     }
3589 }
3590
3591
3592 void wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
3593                    const byte* nonce, word32 nonceSz,
3594                    byte* authTag, word32 authTagSz,
3595                    const byte* authIn, word32 authInSz)
3596 {
3597     byte A[AES_BLOCK_SIZE];
3598     byte B[AES_BLOCK_SIZE];
3599     byte lenSz;
3600     word32 i;
3601
3602     #ifdef FREESCALE_MMCAU
3603         byte* key = (byte*)aes->key;
3604     #endif
3605
3606     XMEMCPY(B+1, nonce, nonceSz);
3607     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
3608     B[0] = (authInSz > 0 ? 64 : 0)
3609          + (8 * (((byte)authTagSz - 2) / 2))
3610          + (lenSz - 1);
3611     for (i = 0; i < lenSz; i++)
3612         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF;
3613
3614     #ifdef FREESCALE_MMCAU
3615         cau_aes_encrypt(B, key, aes->rounds, A);
3616     #else
3617         wc_AesEncrypt(aes, B, A);
3618     #endif
3619     if (authInSz > 0)
3620         roll_auth(aes, authIn, authInSz, A);
3621     if (inSz > 0)
3622         roll_x(aes, in, inSz, A);
3623     XMEMCPY(authTag, A, authTagSz);
3624
3625     B[0] = lenSz - 1;
3626     for (i = 0; i < lenSz; i++)
3627         B[AES_BLOCK_SIZE - 1 - i] = 0;
3628     #ifdef FREESCALE_MMCAU
3629         cau_aes_encrypt(B, key, aes->rounds, A);
3630     #else
3631         wc_AesEncrypt(aes, B, A);
3632     #endif
3633     xorbuf(authTag, A, authTagSz);
3634
3635     B[15] = 1;
3636     while (inSz >= AES_BLOCK_SIZE) {
3637         #ifdef FREESCALE_MMCAU
3638             cau_aes_encrypt(B, key, aes->rounds, A);
3639         #else
3640             wc_AesEncrypt(aes, B, A);
3641         #endif
3642         xorbuf(A, in, AES_BLOCK_SIZE);
3643         XMEMCPY(out, A, AES_BLOCK_SIZE);
3644
3645         AesCcmCtrInc(B, lenSz);
3646         inSz -= AES_BLOCK_SIZE;
3647         in += AES_BLOCK_SIZE;
3648         out += AES_BLOCK_SIZE;
3649     }
3650     if (inSz > 0) {
3651         #ifdef FREESCALE_MMCAU
3652             cau_aes_encrypt(B, key, aes->rounds, A);
3653         #else
3654             wc_AesEncrypt(aes, B, A);
3655         #endif
3656         xorbuf(A, in, inSz);
3657         XMEMCPY(out, A, inSz);
3658     }
3659
3660     ForceZero(A, AES_BLOCK_SIZE);
3661     ForceZero(B, AES_BLOCK_SIZE);
3662 }
3663
3664
3665 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
3666                    const byte* nonce, word32 nonceSz,
3667                    const byte* authTag, word32 authTagSz,
3668                    const byte* authIn, word32 authInSz)
3669 {
3670     byte A[AES_BLOCK_SIZE];
3671     byte B[AES_BLOCK_SIZE];
3672     byte* o;
3673     byte lenSz;
3674     word32 i, oSz;
3675     int result = 0;
3676
3677     #ifdef FREESCALE_MMCAU
3678         byte* key = (byte*)aes->key;
3679     #endif
3680
3681     o = out;
3682     oSz = inSz;
3683     XMEMCPY(B+1, nonce, nonceSz);
3684     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
3685
3686     B[0] = lenSz - 1;
3687     for (i = 0; i < lenSz; i++)
3688         B[AES_BLOCK_SIZE - 1 - i] = 0;
3689     B[15] = 1;
3690
3691     while (oSz >= AES_BLOCK_SIZE) {
3692         #ifdef FREESCALE_MMCAU
3693             cau_aes_encrypt(B, key, aes->rounds, A);
3694         #else
3695             wc_AesEncrypt(aes, B, A);
3696         #endif
3697         xorbuf(A, in, AES_BLOCK_SIZE);
3698         XMEMCPY(o, A, AES_BLOCK_SIZE);
3699
3700         AesCcmCtrInc(B, lenSz);
3701         oSz -= AES_BLOCK_SIZE;
3702         in += AES_BLOCK_SIZE;
3703         o += AES_BLOCK_SIZE;
3704     }
3705     if (inSz > 0) {
3706         #ifdef FREESCALE_MMCAU
3707             cau_aes_encrypt(B, key, aes->rounds, A);
3708         #else
3709             wc_AesEncrypt(aes, B, A);
3710         #endif
3711         xorbuf(A, in, oSz);
3712         XMEMCPY(o, A, oSz);
3713     }
3714
3715     for (i = 0; i < lenSz; i++)
3716         B[AES_BLOCK_SIZE - 1 - i] = 0;
3717     #ifdef FREESCALE_MMCAU
3718         cau_aes_encrypt(B, key, aes->rounds, A);
3719     #else
3720         wc_AesEncrypt(aes, B, A);
3721     #endif
3722
3723     o = out;
3724     oSz = inSz;
3725
3726     B[0] = (authInSz > 0 ? 64 : 0)
3727          + (8 * (((byte)authTagSz - 2) / 2))
3728          + (lenSz - 1);
3729     for (i = 0; i < lenSz; i++)
3730         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF;
3731
3732     #ifdef FREESCALE_MMCAU
3733         cau_aes_encrypt(B, key, aes->rounds, A);
3734     #else
3735         wc_AesEncrypt(aes, B, A);
3736     #endif
3737     if (authInSz > 0)
3738         roll_auth(aes, authIn, authInSz, A);
3739     if (inSz > 0)
3740         roll_x(aes, o, oSz, A);
3741
3742     B[0] = lenSz - 1;
3743     for (i = 0; i < lenSz; i++)
3744         B[AES_BLOCK_SIZE - 1 - i] = 0;
3745     #ifdef FREESCALE_MMCAU
3746         cau_aes_encrypt(B, key, aes->rounds, B);
3747     #else
3748         wc_AesEncrypt(aes, B, B);
3749     #endif
3750     xorbuf(A, B, authTagSz);
3751
3752     if (ConstantCompare(A, authTag, authTagSz) != 0) {
3753         /* If the authTag check fails, don't keep the decrypted data.
3754          * Unfortunately, you need the decrypted data to calculate the
3755          * check value. */
3756         XMEMSET(out, 0, inSz);
3757         result = AES_CCM_AUTH_E;
3758     }
3759
3760     ForceZero(A, AES_BLOCK_SIZE);
3761     ForceZero(B, AES_BLOCK_SIZE);
3762     o = NULL;
3763
3764     return result;
3765 }
3766
3767 #endif /* HAVE_AESCCM */
3768
3769
3770 #ifdef HAVE_CAVIUM
3771
3772 #include <wolfssl/ctaocrypt/logging.h>
3773 #include "cavium_common.h"
3774
3775 /* Initiliaze Aes for use with Nitrox device */
3776 int wc_AesInitCavium(Aes* aes, int devId)
3777 {
3778     if (aes == NULL)
3779         return -1;
3780
3781     if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0)
3782         return -1;
3783
3784     aes->devId = devId;
3785     aes->magic = WOLFSSL_AES_CAVIUM_MAGIC;
3786
3787     return 0;
3788 }
3789
3790
3791 /* Free Aes from use with Nitrox device */
3792 void wc_AesFreeCavium(Aes* aes)
3793 {
3794     if (aes == NULL)
3795         return;
3796
3797     if (aes->magic != WOLFSSL_AES_CAVIUM_MAGIC)
3798         return;
3799
3800     CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId);
3801     aes->magic = 0;
3802 }
3803
3804
3805 static int wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
3806                            const byte* iv)
3807 {
3808     if (aes == NULL)
3809         return -1;
3810
3811     XMEMCPY(aes->key, key, length);   /* key still holds key, iv still in reg */
3812     if (length == 16)
3813         aes->type = AES_128;
3814     else if (length == 24)
3815         aes->type = AES_192;
3816     else if (length == 32)
3817         aes->type = AES_256;
3818
3819     return wc_AesSetIV(aes, iv);
3820 }
3821
3822
3823 static int AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
3824                                word32 length)
3825 {
3826     wolfssl_word offset = 0;
3827     word32 requestId;
3828
3829     while (length > WOLFSSL_MAX_16BIT) {
3830         word16 slen = (word16)WOLFSSL_MAX_16BIT;
3831         if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
3832                           aes->type, slen, (byte*)in + offset, out + offset,
3833                           (byte*)aes->reg, (byte*)aes->key, &requestId,
3834                           aes->devId) != 0) {
3835             WOLFSSL_MSG("Bad Cavium Aes Encrypt");
3836             return -1;
3837         }
3838         length -= WOLFSSL_MAX_16BIT;
3839         offset += WOLFSSL_MAX_16BIT;
3840         XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
3841     }
3842     if (length) {
3843         word16 slen = (word16)length;
3844         if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
3845                           aes->type, slen, (byte*)in + offset, out + offset,
3846                           (byte*)aes->reg, (byte*)aes->key, &requestId,
3847                           aes->devId) != 0) {
3848             WOLFSSL_MSG("Bad Cavium Aes Encrypt");
3849             return -1;
3850         }
3851         XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
3852     }
3853     return 0;
3854 }
3855
3856 static int AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
3857                                word32 length)
3858 {
3859     word32 requestId;
3860     wolfssl_word offset = 0;
3861
3862     while (length > WOLFSSL_MAX_16BIT) {
3863         word16 slen = (word16)WOLFSSL_MAX_16BIT;
3864         XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
3865         if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
3866                           aes->type, slen, (byte*)in + offset, out + offset,
3867                           (byte*)aes->reg, (byte*)aes->key, &requestId,
3868                           aes->devId) != 0) {
3869             WOLFSSL_MSG("Bad Cavium Aes Decrypt");
3870             return -1;
3871         }
3872         length -= WOLFSSL_MAX_16BIT;
3873         offset += WOLFSSL_MAX_16BIT;
3874         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
3875     }
3876     if (length) {
3877         word16 slen = (word16)length;
3878         XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
3879         if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
3880                           aes->type, slen, (byte*)in + offset, out + offset,
3881                           (byte*)aes->reg, (byte*)aes->key, &requestId,
3882                           aes->devId) != 0) {
3883             WOLFSSL_MSG("Bad Cavium Aes Decrypt");
3884             return -1;
3885         }
3886         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
3887     }
3888     return 0;
3889 }
3890
3891 #endif /* HAVE_CAVIUM */
3892
3893 #endif /* WOLFSSL_TI_CRYPT */
3894
3895 #endif /* HAVE_FIPS */
3896
3897 #endif /* NO_AES */