Renesas / SecureDweet
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aes.c Source File

aes.c

00001 /* aes.c
00002  *
00003  * Copyright (C) 2006-2016 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfssl/wolfcrypt/settings.h>
00028 
00029 #ifndef NO_AES
00030 
00031 #include <wolfssl/wolfcrypt/aes.h>
00032 
00033 #ifdef HAVE_FIPS
00034 int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
00035                           int dir)
00036 {
00037     return AesSetKey_fips(aes, key, len, iv, dir);
00038 }
00039 
00040 
00041 int wc_AesSetIV(Aes* aes, const byte* iv)
00042 {
00043     return AesSetIV_fips(aes, iv);
00044 }
00045 
00046 
00047 #ifdef HAVE_AES_CBC
00048 int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00049 {
00050     return AesCbcEncrypt_fips(aes, out, in, sz);
00051 }
00052 
00053 #ifdef HAVE_AES_DECRYPT
00054 int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00055 {
00056     return AesCbcDecrypt_fips(aes, out, in, sz);
00057 }
00058 #endif /* HAVE_AES_DECRYPT */
00059 #endif /* HAVE_AES_CBC */
00060 
00061 /* AES-CTR */
00062 #ifdef WOLFSSL_AES_COUNTER
00063 void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00064 {
00065     AesCtrEncrypt(aes, out, in, sz);
00066 }
00067 #endif
00068 
00069 /* AES-DIRECT */
00070 #if defined(WOLFSSL_AES_DIRECT)
00071 void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
00072 {
00073     AesEncryptDirect(aes, out, in);
00074 }
00075 
00076 #ifdef HAVE_AES_DECRYPT
00077 void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
00078 {
00079     AesDecryptDirect(aes, out, in);
00080 }
00081 #endif /* HAVE_AES_DECRYPT */
00082 
00083 int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
00084                                 const byte* iv, int dir)
00085 {
00086     return AesSetKeyDirect(aes, key, len, iv, dir);
00087 }
00088 #endif
00089 
00090 
00091 #ifdef HAVE_AESGCM
00092 int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
00093 {
00094     return AesGcmSetKey_fips(aes, key, len);
00095 }
00096 
00097 
00098 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
00099                               const byte* iv, word32 ivSz,
00100                               byte* authTag, word32 authTagSz,
00101                               const byte* authIn, word32 authInSz)
00102 {
00103     return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
00104                               authIn, authInSz);
00105 }
00106 
00107 #ifdef HAVE_AES_DECRYPT
00108 int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
00109                               const byte* iv, word32 ivSz,
00110                               const byte* authTag, word32 authTagSz,
00111                               const byte* authIn, word32 authInSz)
00112 {
00113     return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
00114                               authIn, authInSz);
00115 }
00116 #endif /* HAVE_AES_DECRYPT */
00117 
00118 int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
00119 {
00120     return GmacSetKey(gmac, key, len);
00121 }
00122 
00123 
00124 int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
00125                               const byte* authIn, word32 authInSz,
00126                               byte* authTag, word32 authTagSz)
00127 {
00128     return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,
00129                       authTag, authTagSz);
00130 }
00131 
00132 #endif /* HAVE_AESGCM */
00133 #ifdef HAVE_AESCCM
00134 void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
00135 {
00136     AesCcmSetKey(aes, key, keySz);
00137 }
00138 
00139 
00140 int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
00141                               const byte* nonce, word32 nonceSz,
00142                               byte* authTag, word32 authTagSz,
00143                               const byte* authIn, word32 authInSz)
00144 {
00145     /* sanity check on arguments */
00146     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
00147             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
00148         return BAD_FUNC_ARG;
00149 
00150     AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
00151                   authIn, authInSz);
00152     return 0;
00153 }
00154 
00155 #ifdef HAVE_AES_DECRYPT
00156 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
00157                               const byte* nonce, word32 nonceSz,
00158                               const byte* authTag, word32 authTagSz,
00159                               const byte* authIn, word32 authInSz)
00160 {
00161     return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz,
00162                          authIn, authInSz);
00163 }
00164 #endif /* HAVE_AES_DECRYPT */
00165 #endif /* HAVE_AESCCM */
00166 
00167 #ifdef HAVE_CAVIUM
00168 int  wc_AesInitCavium(Aes* aes, int i)
00169 {
00170     return AesInitCavium(aes, i);
00171 }
00172 
00173 
00174 void wc_AesFreeCavium(Aes* aes)
00175 {
00176     AesFreeCavium(aes);
00177 }
00178 #endif
00179 #else /* HAVE_FIPS */
00180 
00181 #ifdef WOLFSSL_TI_CRYPT
00182 #include <wolfcrypt/src/port/ti/ti-aes.c>
00183 #else
00184 
00185 #include <wolfssl/wolfcrypt/error-crypt.h>
00186 #include <wolfssl/wolfcrypt/logging.h>
00187 #ifdef NO_INLINE
00188     #include <wolfssl/wolfcrypt/misc.h>
00189 #else
00190     #include <wolfcrypt/src/misc.c>
00191 #endif
00192 #ifdef DEBUG_AESNI
00193     #include <stdio.h>
00194 #endif
00195 
00196 
00197 #ifdef _MSC_VER
00198     /* 4127 warning constant while(1)  */
00199     #pragma warning(disable: 4127)
00200 #endif
00201 
00202 /* Define AES implementation includes and functions */
00203 #if defined(STM32F2_CRYPTO)
00204      /* STM32F2 hardware AES support for CBC, CTR modes through the STM32F2
00205       * Standard Peripheral Library. Documentation located in STM32F2xx
00206       * Standard Peripheral Library document (See note in README).
00207       * NOTE: no support for AES-GCM/CCM/Direct */
00208     #include "stm32f2xx.h"
00209     #include "stm32f2xx_cryp.h"
00210 #elif defined(HAVE_COLDFIRE_SEC)
00211     /* Freescale Coldfire SEC support for CBC mode.
00212      * NOTE: no support for AES-CTR/GCM/CCM/Direct */
00213     #include <wolfssl/wolfcrypt/types.h>
00214     #include "sec.h"
00215     #include "mcf5475_sec.h"
00216     #include "mcf5475_siu.h"
00217 #elif defined(FREESCALE_MMCAU)
00218     /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
00219      * through the CAU/mmCAU library. Documentation located in
00220      * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
00221      * Guide (See note in README).
00222      * NOTE: no support for AES-CTR */
00223     #include "cau_api.h"
00224 
00225     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00226     {
00227         int ret = wolfSSL_CryptHwMutexLock();
00228         if(ret == 0) {
00229             cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00230             wolfSSL_CryptHwMutexUnLock();
00231         }
00232         return ret;
00233     }
00234     #ifdef HAVE_AES_DECRYPT
00235     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00236     {
00237         int ret = wolfSSL_CryptHwMutexLock();
00238         if(ret == 0) {
00239             cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00240             wolfSSL_CryptHwMutexUnLock();
00241         }
00242         return ret;
00243     }
00244     #endif /* HAVE_AES_DECRYPT */
00245 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
00246     /* NOTE: no support for AES-CCM/Direct */
00247     #define DEBUG_WOLFSSL
00248     #include "wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h"
00249 #elif defined(HAVE_CAVIUM)
00250     #include <wolfssl/wolfcrypt/logging.h>
00251     #include "cavium_common.h"
00252 
00253     /* still leave SW crypto available */
00254     #define NEED_AES_TABLES
00255 
00256     static int  wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
00257                                 const byte* iv);
00258     #ifdef HAVE_AES_CBC
00259     static int  wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
00260                                     word32 length);
00261     #ifdef HAVE_AES_DECRYPT
00262     static int  wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
00263                                     word32 length);
00264     #endif /* HAVE_AES_DECRYPT */
00265     #endif /* HAVE_AES_CBC */
00266 #elif defined(WOLFSSL_NRF51_AES)
00267     /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
00268     #include "wolfssl/wolfcrypt/port/nrf51.h"
00269 
00270     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00271     {
00272         return nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00273     }
00274     #ifdef HAVE_AES_DECRYPT
00275         #error nRF51 AES Hardware does not support decrypt
00276     #endif /* HAVE_AES_DECRYPT */
00277 
00278 #else
00279 
00280     /* using wolfCrypt software AES implementation */
00281     #define NEED_AES_TABLES
00282 #endif
00283 
00284 
00285 #ifdef NEED_AES_TABLES
00286 
00287 static const word32 rcon[] = {
00288     0x01000000, 0x02000000, 0x04000000, 0x08000000,
00289     0x10000000, 0x20000000, 0x40000000, 0x80000000,
00290     0x1B000000, 0x36000000,
00291     /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
00292 };
00293 
00294 static const word32 Te[5][256] = {
00295 {
00296     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
00297     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
00298     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
00299     0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
00300     0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
00301     0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
00302     0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
00303     0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
00304     0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
00305     0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
00306     0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
00307     0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
00308     0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
00309     0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
00310     0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
00311     0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
00312     0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
00313     0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
00314     0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
00315     0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
00316     0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
00317     0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
00318     0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
00319     0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
00320     0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
00321     0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
00322     0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
00323     0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
00324     0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
00325     0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
00326     0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
00327     0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
00328     0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
00329     0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
00330     0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
00331     0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
00332     0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
00333     0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
00334     0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
00335     0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
00336     0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
00337     0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
00338     0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
00339     0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
00340     0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
00341     0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
00342     0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
00343     0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
00344     0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
00345     0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
00346     0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
00347     0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
00348     0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
00349     0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
00350     0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
00351     0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
00352     0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
00353     0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
00354     0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
00355     0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
00356     0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
00357     0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
00358     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
00359     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
00360 },
00361 {
00362     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
00363     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
00364     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
00365     0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
00366     0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
00367     0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
00368     0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
00369     0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
00370     0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
00371     0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
00372     0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
00373     0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
00374     0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
00375     0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
00376     0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
00377     0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
00378     0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
00379     0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
00380     0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
00381     0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
00382     0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
00383     0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
00384     0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
00385     0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
00386     0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
00387     0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
00388     0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
00389     0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
00390     0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
00391     0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
00392     0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
00393     0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
00394     0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
00395     0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
00396     0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
00397     0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
00398     0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
00399     0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
00400     0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
00401     0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
00402     0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
00403     0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
00404     0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
00405     0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
00406     0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
00407     0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
00408     0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
00409     0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
00410     0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
00411     0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
00412     0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
00413     0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
00414     0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
00415     0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
00416     0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
00417     0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
00418     0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
00419     0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
00420     0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
00421     0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
00422     0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
00423     0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
00424     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
00425     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
00426 },
00427 {
00428     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
00429     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
00430     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
00431     0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
00432     0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
00433     0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
00434     0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
00435     0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
00436     0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
00437     0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
00438     0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
00439     0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
00440     0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
00441     0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
00442     0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
00443     0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
00444     0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
00445     0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
00446     0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
00447     0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
00448     0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
00449     0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
00450     0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
00451     0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
00452     0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
00453     0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
00454     0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
00455     0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
00456     0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
00457     0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
00458     0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
00459     0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
00460     0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
00461     0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
00462     0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
00463     0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
00464     0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
00465     0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
00466     0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
00467     0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
00468     0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
00469     0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
00470     0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
00471     0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
00472     0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
00473     0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
00474     0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
00475     0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
00476     0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
00477     0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
00478     0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
00479     0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
00480     0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
00481     0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
00482     0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
00483     0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
00484     0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
00485     0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
00486     0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
00487     0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
00488     0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
00489     0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
00490     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
00491     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
00492 },
00493 {
00494     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
00495     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
00496     0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
00497     0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
00498     0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
00499     0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
00500     0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
00501     0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
00502     0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
00503     0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
00504     0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
00505     0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
00506     0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
00507     0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
00508     0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
00509     0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
00510     0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
00511     0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
00512     0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
00513     0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
00514     0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
00515     0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
00516     0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
00517     0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
00518     0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
00519     0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
00520     0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
00521     0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
00522     0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
00523     0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
00524     0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
00525     0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
00526     0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
00527     0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
00528     0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
00529     0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
00530     0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
00531     0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
00532     0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
00533     0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
00534     0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
00535     0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
00536     0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
00537     0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
00538     0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
00539     0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
00540     0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
00541     0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
00542     0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
00543     0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
00544     0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
00545     0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
00546     0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
00547     0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
00548     0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
00549     0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
00550     0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
00551     0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
00552     0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
00553     0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
00554     0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
00555     0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
00556     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
00557     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
00558 },
00559 {
00560     0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
00561     0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
00562     0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
00563     0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
00564     0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
00565     0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
00566     0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
00567     0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
00568     0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
00569     0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
00570     0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
00571     0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
00572     0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
00573     0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
00574     0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
00575     0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
00576     0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
00577     0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
00578     0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
00579     0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
00580     0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
00581     0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
00582     0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
00583     0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
00584     0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
00585     0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
00586     0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
00587     0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
00588     0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
00589     0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
00590     0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
00591     0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
00592     0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
00593     0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
00594     0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
00595     0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
00596     0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
00597     0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
00598     0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
00599     0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
00600     0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
00601     0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
00602     0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
00603     0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
00604     0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
00605     0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
00606     0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
00607     0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
00608     0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
00609     0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
00610     0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
00611     0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
00612     0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
00613     0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
00614     0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
00615     0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
00616     0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
00617     0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
00618     0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
00619     0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
00620     0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
00621     0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
00622     0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
00623     0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
00624 }
00625 };
00626 
00627 static const word32 Td[5][256] = {
00628 {
00629     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
00630     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
00631     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
00632     0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
00633     0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
00634     0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
00635     0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
00636     0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
00637     0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
00638     0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
00639     0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
00640     0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
00641     0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
00642     0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
00643     0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
00644     0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
00645     0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
00646     0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
00647     0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
00648     0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
00649     0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
00650     0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
00651     0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
00652     0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
00653     0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
00654     0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
00655     0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
00656     0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
00657     0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
00658     0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
00659     0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
00660     0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
00661     0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
00662     0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
00663     0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
00664     0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
00665     0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
00666     0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
00667     0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
00668     0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
00669     0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
00670     0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
00671     0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
00672     0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
00673     0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
00674     0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
00675     0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
00676     0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
00677     0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
00678     0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
00679     0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
00680     0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
00681     0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
00682     0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
00683     0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
00684     0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
00685     0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
00686     0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
00687     0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
00688     0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
00689     0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
00690     0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
00691     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
00692     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
00693 },
00694 {
00695     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
00696     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
00697     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
00698     0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
00699     0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
00700     0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
00701     0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
00702     0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
00703     0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
00704     0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
00705     0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
00706     0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
00707     0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
00708     0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
00709     0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
00710     0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
00711     0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
00712     0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
00713     0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
00714     0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
00715     0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
00716     0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
00717     0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
00718     0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
00719     0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
00720     0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
00721     0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
00722     0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
00723     0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
00724     0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
00725     0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
00726     0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
00727     0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
00728     0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
00729     0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
00730     0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
00731     0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
00732     0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
00733     0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
00734     0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
00735     0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
00736     0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
00737     0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
00738     0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
00739     0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
00740     0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
00741     0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
00742     0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
00743     0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
00744     0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
00745     0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
00746     0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
00747     0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
00748     0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
00749     0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
00750     0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
00751     0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
00752     0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
00753     0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
00754     0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
00755     0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
00756     0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
00757     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
00758     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
00759 },
00760 {
00761     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
00762     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
00763     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
00764     0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
00765     0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
00766     0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
00767     0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
00768     0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
00769     0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
00770     0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
00771     0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
00772     0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
00773     0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
00774     0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
00775     0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
00776     0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
00777     0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
00778     0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
00779     0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
00780     0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
00781 
00782     0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
00783     0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
00784     0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
00785     0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
00786     0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
00787     0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
00788     0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
00789     0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
00790     0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
00791     0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
00792     0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
00793     0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
00794     0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
00795     0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
00796     0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
00797     0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
00798     0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
00799     0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
00800     0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
00801     0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
00802     0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
00803     0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
00804     0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
00805     0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
00806     0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
00807     0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
00808     0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
00809     0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
00810     0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
00811     0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
00812     0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
00813     0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
00814     0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
00815     0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
00816     0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
00817     0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
00818     0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
00819     0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
00820     0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
00821     0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
00822     0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
00823     0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
00824     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
00825     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
00826 },
00827 {
00828     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
00829     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
00830     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
00831     0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
00832     0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
00833     0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
00834     0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
00835     0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
00836     0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
00837     0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
00838     0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
00839     0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
00840     0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
00841     0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
00842     0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
00843     0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
00844     0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
00845     0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
00846     0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
00847     0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
00848     0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
00849     0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
00850     0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
00851     0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
00852     0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
00853     0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
00854     0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
00855     0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
00856     0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
00857     0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
00858     0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
00859     0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
00860     0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
00861     0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
00862     0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
00863     0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
00864     0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
00865     0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
00866     0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
00867     0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
00868     0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
00869     0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
00870     0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
00871     0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
00872     0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
00873     0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
00874     0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
00875     0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
00876     0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
00877     0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
00878     0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
00879     0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
00880     0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
00881     0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
00882     0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
00883     0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
00884     0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
00885     0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
00886     0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
00887     0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
00888     0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
00889     0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
00890     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
00891     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
00892 },
00893 {
00894     0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
00895     0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
00896     0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
00897     0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
00898     0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
00899     0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
00900     0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
00901     0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
00902     0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
00903     0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
00904     0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
00905     0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
00906     0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
00907     0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
00908     0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
00909     0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
00910     0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
00911     0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
00912     0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
00913     0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
00914     0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
00915     0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
00916     0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
00917     0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
00918     0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
00919     0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
00920     0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
00921     0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
00922     0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
00923     0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
00924     0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
00925     0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
00926     0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
00927     0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
00928     0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
00929     0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
00930     0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
00931     0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
00932     0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
00933     0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
00934     0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
00935     0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
00936     0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
00937     0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
00938     0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
00939     0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
00940     0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
00941     0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
00942     0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
00943     0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
00944     0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
00945     0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
00946     0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
00947     0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
00948     0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
00949     0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
00950     0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
00951     0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
00952     0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
00953     0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
00954     0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
00955     0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
00956     0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
00957     0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
00958 }
00959 };
00960 
00961 #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
00962 
00963 
00964 #ifdef WOLFSSL_AESNI
00965 
00966 /* Each platform needs to query info type 1 from cpuid to see if aesni is
00967  * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
00968  */
00969 
00970 #ifndef _MSC_VER
00971 
00972     #define cpuid(reg, func)\
00973         __asm__ __volatile__ ("cpuid":\
00974              "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3]) :\
00975              "a" (func));
00976 
00977     #define XASM_LINK(f) asm(f)
00978 #else
00979 
00980     #include <intrin.h>
00981     #define cpuid(a,b) __cpuid((int*)a,b)
00982 
00983     #define XASM_LINK(f)
00984 
00985 #endif /* _MSC_VER */
00986 
00987 
00988 static int Check_CPU_support_AES(void)
00989 {
00990     unsigned int reg[4];  /* put a,b,c,d into 0,1,2,3 */
00991     cpuid(reg, 1);        /* query info 1 */
00992 
00993     if (reg[2] & 0x2000000)
00994         return 1;
00995 
00996     return 0;
00997 }
00998 
00999 static int checkAESNI = 0;
01000 static int haveAESNI  = 0;
01001 
01002 
01003 /* tell C compiler these are asm functions in case any mix up of ABI underscore
01004    prefix between clang/gcc/llvm etc */
01005 #ifdef HAVE_AES_CBC
01006 void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
01007                      unsigned char* ivec, unsigned long length,
01008                      const unsigned char* KS, int nr)
01009                      XASM_LINK("AES_CBC_encrypt");
01010 
01011 #ifdef HAVE_AES_DECRYPT
01012 void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
01013                      unsigned char* ivec, unsigned long length,
01014                      const unsigned char* KS, int nr)
01015                      XASM_LINK("AES_CBC_decrypt");
01016 #endif /* HAVE_AES_DECRYPT */
01017 #endif /* HAVE_AES_CBC */
01018                      
01019 void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
01020                      unsigned long length, const unsigned char* KS, int nr)
01021                      XASM_LINK("AES_ECB_encrypt");
01022 
01023 #ifdef HAVE_AES_DECRYPT
01024 void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
01025                      unsigned long length, const unsigned char* KS, int nr)
01026                      XASM_LINK("AES_ECB_decrypt");
01027 #endif
01028 
01029 void AES_128_Key_Expansion(const unsigned char* userkey,
01030                            unsigned char* key_schedule)
01031                            XASM_LINK("AES_128_Key_Expansion");
01032 
01033 void AES_192_Key_Expansion(const unsigned char* userkey,
01034                            unsigned char* key_schedule)
01035                            XASM_LINK("AES_192_Key_Expansion");
01036 
01037 void AES_256_Key_Expansion(const unsigned char* userkey,
01038                            unsigned char* key_schedule)
01039                            XASM_LINK("AES_256_Key_Expansion");
01040 
01041 
01042 static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
01043                                Aes* aes)
01044 {
01045     if (!userKey || !aes)
01046         return BAD_FUNC_ARG;
01047 
01048     if (bits == 128) {
01049        AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
01050        return 0;
01051     }
01052     else if (bits == 192) {
01053        AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
01054        return 0;
01055     }
01056     else if (bits == 256) {
01057        AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
01058        return 0;
01059     }
01060     return BAD_FUNC_ARG;
01061 }
01062 
01063 #ifdef HAVE_AES_DECRYPT
01064 static int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
01065                                Aes* aes)
01066 {
01067     int nr;
01068     Aes temp_key;
01069     __m128i *Key_Schedule = (__m128i*)aes->key;
01070     __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
01071 
01072     if (!userKey || !aes)
01073         return BAD_FUNC_ARG;
01074 
01075     if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
01076         return BAD_FUNC_ARG;
01077 
01078     nr = temp_key.rounds;
01079     aes->rounds = nr;
01080 
01081     Key_Schedule[nr] = Temp_Key_Schedule[0];
01082     Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
01083     Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
01084     Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
01085     Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
01086     Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
01087     Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
01088     Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
01089     Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
01090     Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
01091 
01092     if(nr>10) {
01093         Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
01094         Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
01095     }
01096 
01097     if(nr>12) {
01098         Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
01099         Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
01100     }
01101 
01102     Key_Schedule[0] = Temp_Key_Schedule[nr];
01103 
01104     return 0;
01105 }
01106 #endif /* HAVE_AES_DECRYPT */
01107 #endif /* WOLFSSL_AESNI */
01108 
01109 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) ||\
01110     defined(HAVE_AESGCM)
01111 
01112 static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
01113 {
01114     word32 s0, s1, s2, s3;
01115     word32 t0, t1, t2, t3;
01116     word32 r = aes->rounds >> 1;
01117 
01118     const word32* rk = aes->key;
01119     if (r > 7 || r == 0) {
01120         WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
01121         return;  /* stop instead of segfaulting, set up your keys! */
01122     }
01123 #ifdef WOLFSSL_AESNI
01124     if (haveAESNI && aes->use_aesni) {
01125         #ifdef DEBUG_AESNI
01126             printf("about to aes encrypt\n");
01127             printf("in  = %p\n", inBlock);
01128             printf("out = %p\n", outBlock);
01129             printf("aes->key = %p\n", aes->key);
01130             printf("aes->rounds = %d\n", aes->rounds);
01131             printf("sz = %d\n", AES_BLOCK_SIZE);
01132         #endif
01133 
01134         /* check alignment, decrypt doesn't need alignment */
01135         if ((wolfssl_word)inBlock % 16) {
01136         #ifndef NO_WOLFSSL_ALLOC_ALIGN
01137             byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL,
01138                                                       DYNAMIC_TYPE_TMP_BUFFER);
01139             if (tmp == NULL) return;
01140 
01141             XMEMCPY(tmp, inBlock, AES_BLOCK_SIZE);
01142             AES_ECB_encrypt(tmp, tmp, AES_BLOCK_SIZE, (byte*)aes->key,
01143                             aes->rounds);
01144             XMEMCPY(outBlock, tmp, AES_BLOCK_SIZE);
01145             XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01146             return;
01147         #else
01148             WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
01149             return;
01150         #endif
01151         }
01152 
01153         AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
01154                         aes->rounds);
01155 
01156         return;
01157     }
01158     else {
01159         #ifdef DEBUG_AESNI
01160             printf("Skipping AES-NI\n");
01161         #endif
01162     }
01163 #endif
01164 
01165     /*
01166      * map byte array block to cipher state
01167      * and add initial round key:
01168      */
01169     XMEMCPY(&s0, inBlock,                  sizeof(s0));
01170     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
01171     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
01172     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
01173 
01174     #ifdef LITTLE_ENDIAN_ORDER
01175         s0 = ByteReverseWord32(s0);
01176         s1 = ByteReverseWord32(s1);
01177         s2 = ByteReverseWord32(s2);
01178         s3 = ByteReverseWord32(s3);
01179     #endif
01180 
01181     s0 ^= rk[0];
01182     s1 ^= rk[1];
01183     s2 ^= rk[2];
01184     s3 ^= rk[3];
01185 
01186     /*
01187      * Nr - 1 full rounds:
01188      */
01189 
01190     for (;;) {
01191         t0 =
01192             Te[0][GETBYTE(s0, 3)]  ^
01193             Te[1][GETBYTE(s1, 2)]  ^
01194             Te[2][GETBYTE(s2, 1)]  ^
01195             Te[3][GETBYTE(s3, 0)]  ^
01196             rk[4];
01197         t1 =
01198             Te[0][GETBYTE(s1, 3)]  ^
01199             Te[1][GETBYTE(s2, 2)]  ^
01200             Te[2][GETBYTE(s3, 1)]  ^
01201             Te[3][GETBYTE(s0, 0)]  ^
01202             rk[5];
01203         t2 =
01204             Te[0][GETBYTE(s2, 3)] ^
01205             Te[1][GETBYTE(s3, 2)]  ^
01206             Te[2][GETBYTE(s0, 1)]  ^
01207             Te[3][GETBYTE(s1, 0)]  ^
01208             rk[6];
01209         t3 =
01210             Te[0][GETBYTE(s3, 3)] ^
01211             Te[1][GETBYTE(s0, 2)]  ^
01212             Te[2][GETBYTE(s1, 1)]  ^
01213             Te[3][GETBYTE(s2, 0)]  ^
01214             rk[7];
01215 
01216         rk += 8;
01217         if (--r == 0) {
01218             break;
01219         }
01220 
01221         s0 =
01222             Te[0][GETBYTE(t0, 3)] ^
01223             Te[1][GETBYTE(t1, 2)] ^
01224             Te[2][GETBYTE(t2, 1)] ^
01225             Te[3][GETBYTE(t3, 0)] ^
01226             rk[0];
01227         s1 =
01228             Te[0][GETBYTE(t1, 3)] ^
01229             Te[1][GETBYTE(t2, 2)] ^
01230             Te[2][GETBYTE(t3, 1)] ^
01231             Te[3][GETBYTE(t0, 0)] ^
01232             rk[1];
01233         s2 =
01234             Te[0][GETBYTE(t2, 3)] ^
01235             Te[1][GETBYTE(t3, 2)] ^
01236             Te[2][GETBYTE(t0, 1)] ^
01237             Te[3][GETBYTE(t1, 0)] ^
01238             rk[2];
01239         s3 =
01240             Te[0][GETBYTE(t3, 3)] ^
01241             Te[1][GETBYTE(t0, 2)] ^
01242             Te[2][GETBYTE(t1, 1)] ^
01243             Te[3][GETBYTE(t2, 0)] ^
01244             rk[3];
01245     }
01246 
01247     /*
01248      * apply last round and
01249      * map cipher state to byte array block:
01250      */
01251 
01252     s0 =
01253         (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
01254         (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
01255         (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
01256         (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
01257         rk[0];
01258     s1 =
01259         (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
01260         (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
01261         (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
01262         (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
01263         rk[1];
01264     s2 =
01265         (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
01266         (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
01267         (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
01268         (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
01269         rk[2];
01270     s3 =
01271         (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
01272         (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
01273         (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
01274         (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
01275         rk[3];
01276 
01277     /* write out */
01278     #ifdef LITTLE_ENDIAN_ORDER
01279         s0 = ByteReverseWord32(s0);
01280         s1 = ByteReverseWord32(s1);
01281         s2 = ByteReverseWord32(s2);
01282         s3 = ByteReverseWord32(s3);
01283     #endif
01284 
01285     XMEMCPY(outBlock,                  &s0, sizeof(s0));
01286     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
01287     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
01288     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
01289 }
01290 #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
01291 
01292 #ifdef HAVE_AES_DECRYPT
01293 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
01294 static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
01295 {
01296     word32 s0, s1, s2, s3;
01297     word32 t0, t1, t2, t3;
01298     word32 r = aes->rounds >> 1;
01299 
01300     const word32* rk = aes->key;
01301     if (r > 7 || r == 0) {
01302         WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
01303         return;  /* stop instead of segfaulting, set up your keys! */
01304     }
01305 #ifdef WOLFSSL_AESNI
01306     if (haveAESNI && aes->use_aesni) {
01307         #ifdef DEBUG_AESNI
01308             printf("about to aes decrypt\n");
01309             printf("in  = %p\n", inBlock);
01310             printf("out = %p\n", outBlock);
01311             printf("aes->key = %p\n", aes->key);
01312             printf("aes->rounds = %d\n", aes->rounds);
01313             printf("sz = %d\n", AES_BLOCK_SIZE);
01314         #endif
01315 
01316         /* if input and output same will overwrite input iv */
01317         XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
01318         AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
01319                         aes->rounds);
01320         return;
01321     }
01322     else {
01323         #ifdef DEBUG_AESNI
01324             printf("Skipping AES-NI\n");
01325         #endif
01326     }
01327 #endif
01328 
01329     /*
01330      * map byte array block to cipher state
01331      * and add initial round key:
01332      */
01333     XMEMCPY(&s0, inBlock,                  sizeof(s0));
01334     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
01335     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
01336     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
01337 
01338     #ifdef LITTLE_ENDIAN_ORDER
01339         s0 = ByteReverseWord32(s0);
01340         s1 = ByteReverseWord32(s1);
01341         s2 = ByteReverseWord32(s2);
01342         s3 = ByteReverseWord32(s3);
01343     #endif
01344 
01345     s0 ^= rk[0];
01346     s1 ^= rk[1];
01347     s2 ^= rk[2];
01348     s3 ^= rk[3];
01349 
01350     /*
01351      * Nr - 1 full rounds:
01352      */
01353 
01354     for (;;) {
01355         t0 =
01356             Td[0][GETBYTE(s0, 3)] ^
01357             Td[1][GETBYTE(s3, 2)] ^
01358             Td[2][GETBYTE(s2, 1)] ^
01359             Td[3][GETBYTE(s1, 0)] ^
01360             rk[4];
01361         t1 =
01362             Td[0][GETBYTE(s1, 3)] ^
01363             Td[1][GETBYTE(s0, 2)] ^
01364             Td[2][GETBYTE(s3, 1)] ^
01365             Td[3][GETBYTE(s2, 0)] ^
01366             rk[5];
01367         t2 =
01368             Td[0][GETBYTE(s2, 3)] ^
01369             Td[1][GETBYTE(s1, 2)] ^
01370             Td[2][GETBYTE(s0, 1)] ^
01371             Td[3][GETBYTE(s3, 0)] ^
01372             rk[6];
01373         t3 =
01374             Td[0][GETBYTE(s3, 3)] ^
01375             Td[1][GETBYTE(s2, 2)] ^
01376             Td[2][GETBYTE(s1, 1)] ^
01377             Td[3][GETBYTE(s0, 0)] ^
01378             rk[7];
01379 
01380         rk += 8;
01381         if (--r == 0) {
01382             break;
01383         }
01384 
01385         s0 =
01386             Td[0][GETBYTE(t0, 3)] ^
01387             Td[1][GETBYTE(t3, 2)] ^
01388             Td[2][GETBYTE(t2, 1)] ^
01389             Td[3][GETBYTE(t1, 0)] ^
01390             rk[0];
01391         s1 =
01392             Td[0][GETBYTE(t1, 3)] ^
01393             Td[1][GETBYTE(t0, 2)] ^
01394             Td[2][GETBYTE(t3, 1)] ^
01395             Td[3][GETBYTE(t2, 0)] ^
01396             rk[1];
01397         s2 =
01398             Td[0][GETBYTE(t2, 3)] ^
01399             Td[1][GETBYTE(t1, 2)] ^
01400             Td[2][GETBYTE(t0, 1)] ^
01401             Td[3][GETBYTE(t3, 0)] ^
01402             rk[2];
01403         s3 =
01404             Td[0][GETBYTE(t3, 3)] ^
01405             Td[1][GETBYTE(t2, 2)] ^
01406             Td[2][GETBYTE(t1, 1)] ^
01407             Td[3][GETBYTE(t0, 0)] ^
01408             rk[3];
01409     }
01410     /*
01411      * apply last round and
01412      * map cipher state to byte array block:
01413      */
01414     s0 =
01415         (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
01416         (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
01417         (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
01418         (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
01419         rk[0];
01420     s1 =
01421         (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
01422         (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
01423         (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
01424         (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
01425         rk[1];
01426     s2 =
01427         (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
01428         (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
01429         (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
01430         (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
01431         rk[2];
01432     s3 =
01433         (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
01434         (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
01435         (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
01436         (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
01437         rk[3];
01438 
01439     /* write out */
01440     #ifdef LITTLE_ENDIAN_ORDER
01441         s0 = ByteReverseWord32(s0);
01442         s1 = ByteReverseWord32(s1);
01443         s2 = ByteReverseWord32(s2);
01444         s3 = ByteReverseWord32(s3);
01445     #endif
01446 
01447     XMEMCPY(outBlock,                  &s0, sizeof(s0));
01448     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
01449     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
01450     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
01451 }
01452 #endif /* HAVE_AES_DECRYPT */
01453 #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
01454 
01455 #endif /* NEED_AES_TABLES */
01456 
01457 
01458 /* wc_AesSetKey */
01459 #ifdef STM32F2_CRYPTO
01460     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
01461                   int dir)
01462     {
01463         word32 *rk = aes->key;
01464 
01465         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
01466             return BAD_FUNC_ARG;
01467 
01468         aes->rounds = keylen/4 + 6;
01469         XMEMCPY(rk, userKey, keylen);
01470         ByteReverseWords(rk, rk, keylen);
01471 
01472         return wc_AesSetIV(aes, iv);
01473     }
01474 
01475     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
01476                         const byte* iv, int dir)
01477     {
01478         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
01479     }
01480 
01481 #elif defined(HAVE_COLDFIRE_SEC)
01482     #if defined (HAVE_THREADX)
01483         #include "memory_pools.h"
01484         extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
01485     #endif
01486 
01487     #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
01488     static unsigned char *AESBuffIn = NULL;
01489     static unsigned char *AESBuffOut = NULL;
01490     static byte *secReg;
01491     static byte *secKey;
01492     static volatile SECdescriptorType *secDesc;
01493 
01494     static wolfSSL_Mutex Mutex_AesSEC;
01495 
01496     #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
01497     #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
01498 
01499     extern volatile unsigned char __MBAR[];
01500 
01501     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
01502                   int dir)
01503     {
01504         if (AESBuffIn == NULL) {
01505             #if defined (HAVE_THREADX)
01506                 int s1, s2, s3, s4, s5 ;
01507                 s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
01508                                       sizeof(SECdescriptorType), TX_NO_WAIT);
01509                 s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
01510                                       AES_BUFFER_SIZE, TX_NO_WAIT);
01511                 s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
01512                                       AES_BUFFER_SIZE, TX_NO_WAIT);
01513                 s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
01514                                       AES_BLOCK_SIZE*2, TX_NO_WAIT);
01515                 s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
01516                                       AES_BLOCK_SIZE, TX_NO_WAIT);
01517 
01518                 if(s1 || s2 || s3 || s4 || s5)
01519                     return BAD_FUNC_ARG;
01520             #else
01521                 #warning "Allocate non-Cache buffers"
01522             #endif
01523 
01524             InitMutex(&Mutex_AesSEC);
01525         }
01526 
01527         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
01528             return BAD_FUNC_ARG;
01529 
01530         if (aes == NULL)
01531             return BAD_FUNC_ARG;
01532 
01533         aes->rounds = keylen/4 + 6;
01534         XMEMCPY(aes->key, userKey, keylen);
01535 
01536         if (iv)
01537             XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
01538 
01539         return 0;
01540     }
01541 #elif defined(FREESCALE_MMCAU)
01542     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
01543                   int dir)
01544     {
01545         int ret;
01546         byte *rk = (byte*)aes->key;
01547 
01548         (void)dir;
01549 
01550         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
01551             return BAD_FUNC_ARG;
01552 
01553         if (rk == NULL)
01554             return BAD_FUNC_ARG;
01555 
01556         aes->rounds = keylen/4 + 6;
01557 
01558         ret = wolfSSL_CryptHwMutexLock();
01559         if(ret == 0) {
01560             cau_aes_set_key(userKey, keylen*8, rk);
01561             wolfSSL_CryptHwMutexUnLock();
01562 
01563             ret = wc_AesSetIV(aes, iv);
01564         }
01565 
01566         return ret;
01567     }
01568 
01569     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
01570                         const byte* iv, int dir)
01571     {
01572         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
01573     }
01574 #elif defined(WOLFSSL_NRF51_AES)
01575     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
01576                   int dir)
01577     {
01578         int ret;
01579 
01580         (void)dir;
01581         (void)iv;
01582 
01583         if (keylen != 16)
01584             return BAD_FUNC_ARG;
01585 
01586         aes->rounds = keylen/4 + 6;
01587         ret = nrf51_aes_set_key(userKey);
01588 
01589         return ret;
01590     }
01591 
01592     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
01593                         const byte* iv, int dir)
01594     {
01595         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
01596     }
01597 #else
01598     static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
01599                 const byte* iv, int dir)
01600     {
01601         word32 temp, *rk = aes->key;
01602         unsigned int i = 0;
01603 
01604         #ifdef WOLFSSL_AESNI
01605             aes->use_aesni = 0;
01606         #endif /* WOLFSSL_AESNI */
01607         #ifdef WOLFSSL_AES_COUNTER
01608             aes->left = 0;
01609         #endif /* WOLFSSL_AES_COUNTER */
01610 
01611         aes->rounds = keylen/4 + 6;
01612 
01613         XMEMCPY(rk, userKey, keylen);
01614         #ifdef LITTLE_ENDIAN_ORDER
01615             ByteReverseWords(rk, rk, keylen);
01616         #endif
01617 
01618         #ifdef WOLFSSL_PIC32MZ_CRYPT
01619         {
01620             word32 *akey1 = aes->key_ce;
01621             word32 *areg = aes->iv_ce ;
01622             aes->keylen = keylen ;
01623             XMEMCPY(akey1, userKey, keylen);
01624             if (iv)
01625                 XMEMCPY(areg, iv, AES_BLOCK_SIZE);
01626             else
01627                 XMEMSET(areg,  0, AES_BLOCK_SIZE);
01628         }
01629         #endif
01630 
01631         switch(keylen)
01632         {
01633 #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128
01634         case 16:
01635             while (1)
01636             {
01637                 temp  = rk[3];
01638                 rk[4] = rk[0] ^
01639                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
01640                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
01641                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
01642                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
01643                     rcon[i];
01644                 rk[5] = rk[1] ^ rk[4];
01645                 rk[6] = rk[2] ^ rk[5];
01646                 rk[7] = rk[3] ^ rk[6];
01647                 if (++i == 10)
01648                     break;
01649                 rk += 4;
01650             }
01651             break;
01652 #endif /* 128 */
01653 
01654 #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192
01655         case 24:
01656             /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
01657             while (1)
01658             {
01659                 temp = rk[ 5];
01660                 rk[ 6] = rk[ 0] ^
01661                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
01662                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
01663                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
01664                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
01665                     rcon[i];
01666                 rk[ 7] = rk[ 1] ^ rk[ 6];
01667                 rk[ 8] = rk[ 2] ^ rk[ 7];
01668                 rk[ 9] = rk[ 3] ^ rk[ 8];
01669                 if (++i == 8)
01670                     break;
01671                 rk[10] = rk[ 4] ^ rk[ 9];
01672                 rk[11] = rk[ 5] ^ rk[10];
01673                 rk += 6;
01674             }
01675             break;
01676 #endif /* 192 */
01677 
01678 #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256
01679         case 32:
01680             while (1)
01681             {
01682                 temp = rk[ 7];
01683                 rk[ 8] = rk[ 0] ^
01684                     (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
01685                     (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
01686                     (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
01687                     (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
01688                     rcon[i];
01689                 rk[ 9] = rk[ 1] ^ rk[ 8];
01690                 rk[10] = rk[ 2] ^ rk[ 9];
01691                 rk[11] = rk[ 3] ^ rk[10];
01692                 if (++i == 7)
01693                     break;
01694                 temp = rk[11];
01695                 rk[12] = rk[ 4] ^
01696                     (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
01697                     (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
01698                     (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
01699                     (Te[4][GETBYTE(temp, 0)] & 0x000000ff);
01700                 rk[13] = rk[ 5] ^ rk[12];
01701                 rk[14] = rk[ 6] ^ rk[13];
01702                 rk[15] = rk[ 7] ^ rk[14];
01703 
01704                 rk += 8;
01705             }
01706             break;
01707 #endif /* 256 */
01708 
01709         default:
01710             return BAD_FUNC_ARG;
01711         }
01712 
01713 #ifdef HAVE_AES_DECRYPT
01714         if (dir == AES_DECRYPTION)
01715         {
01716             unsigned int j;
01717             rk = aes->key;
01718 
01719             /* invert the order of the round keys: */
01720             for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
01721                 temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
01722                 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
01723                 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
01724                 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
01725             }
01726             /* apply the inverse MixColumn transform to all round keys but the
01727                first and the last: */
01728             for (i = 1; i < aes->rounds; i++) {
01729                 rk += 4;
01730                 rk[0] =
01731                     Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
01732                     Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
01733                     Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
01734                     Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
01735                 rk[1] =
01736                     Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
01737                     Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
01738                     Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
01739                     Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
01740                 rk[2] =
01741                     Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
01742                     Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
01743                     Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
01744                     Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
01745                 rk[3] =
01746                     Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
01747                     Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
01748                     Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
01749                     Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
01750             }
01751         }
01752 #endif /* HAVE_AES_DECRYPT */
01753 
01754         return wc_AesSetIV(aes, iv);
01755     }
01756 
01757     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
01758                   int dir)
01759     {
01760     #if defined(AES_MAX_KEY_SIZE)
01761         const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
01762     #endif
01763 
01764         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
01765             return BAD_FUNC_ARG;
01766 
01767     #if defined(AES_MAX_KEY_SIZE)
01768         /* Check key length */
01769         if (keylen > max_key_len) {
01770             return BAD_FUNC_ARG;
01771         }
01772     #endif
01773 
01774     #ifdef HAVE_CAVIUM
01775         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
01776             return wc_AesCaviumSetKey(aes, userKey, keylen, iv);
01777     #endif
01778 
01779     #ifdef WOLFSSL_AESNI
01780         if (checkAESNI == 0) {
01781             haveAESNI  = Check_CPU_support_AES();
01782             checkAESNI = 1;
01783         }
01784         if (haveAESNI) {
01785             aes->use_aesni = 1;
01786             if (iv)
01787                 XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
01788             if (dir == AES_ENCRYPTION)
01789                 return AES_set_encrypt_key(userKey, keylen * 8, aes);
01790         #ifdef HAVE_AES_DECRYPT
01791             else
01792                 return AES_set_decrypt_key(userKey, keylen * 8, aes);
01793         #endif
01794         }
01795     #endif /* WOLFSSL_AESNI */
01796 
01797         return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
01798     }
01799 
01800     #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
01801 
01802     /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */
01803     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
01804                         const byte* iv, int dir)
01805     {
01806         return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
01807     }
01808 
01809     #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
01810 #endif /* STM32F2_CRYPTO, wc_AesSetKey block */
01811 
01812 
01813 /* wc_AesSetIV is shared between software and hardware */
01814 int wc_AesSetIV(Aes* aes, const byte* iv)
01815 {
01816     if (aes == NULL)
01817         return BAD_FUNC_ARG;
01818 
01819     if (iv)
01820         XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
01821     else
01822         XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
01823 
01824     return 0;
01825 }
01826 
01827 
01828 
01829 
01830 /* AES-DIRECT */
01831 #if defined(WOLFSSL_AES_DIRECT)
01832     #if defined(STM32F2_CRYPTO)
01833         #error "STM32F2 crypto doesn't yet support AES direct"
01834 
01835     #elif defined(HAVE_COLDFIRE_SEC)
01836         #error "Coldfire SEC doesn't yet support AES direct"
01837 
01838     #elif defined(WOLFSSL_PIC32MZ_CRYPT)
01839         #error "PIC32MZ doesn't yet support AES direct"
01840 
01841     #else
01842         /* Allow direct access to one block encrypt */
01843         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
01844         {
01845             wc_AesEncrypt(aes, in, out);
01846         }
01847     #ifdef HAVE_AES_DECRYPT
01848         /* Allow direct access to one block decrypt */
01849         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
01850         {
01851             wc_AesDecrypt(aes, in, out);
01852         }
01853     #endif /* HAVE_AES_DECRYPT */
01854     #endif /* AES direct block */
01855 #endif /* WOLFSSL_AES_DIRECT */
01856 
01857 
01858 /* AES-CBC */
01859 #ifdef HAVE_AES_CBC
01860 #ifdef STM32F2_CRYPTO
01861     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
01862     {
01863         word32 *enc_key, *iv;
01864         CRYP_InitTypeDef AES_CRYP_InitStructure;
01865         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
01866         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
01867 
01868         enc_key = aes->key;
01869         iv = aes->reg;
01870 
01871         /* crypto structure initialization */
01872         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
01873         CRYP_StructInit(&AES_CRYP_InitStructure);
01874         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
01875 
01876         /* reset registers to their default values */
01877         CRYP_DeInit();
01878 
01879         /* load key into correct registers */
01880         switch(aes->rounds)
01881         {
01882             case 10: /* 128-bit key */
01883                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
01884                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
01885                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
01886                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
01887                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
01888                 break;
01889 
01890             case 12: /* 192-bit key */
01891                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
01892                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
01893                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
01894                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
01895                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
01896                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
01897                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
01898                 break;
01899 
01900             case 14: /* 256-bit key */
01901                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
01902                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
01903                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
01904                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
01905                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
01906                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
01907                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
01908                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
01909                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
01910                 break;
01911 
01912             default:
01913                 break;
01914         }
01915         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
01916 
01917         /* set iv */
01918         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
01919         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
01920         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
01921         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
01922         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
01923         CRYP_IVInit(&AES_CRYP_IVInitStructure);
01924 
01925         /* set direction, mode, and datatype */
01926         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
01927         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
01928         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
01929         CRYP_Init(&AES_CRYP_InitStructure);
01930 
01931         /* enable crypto processor */
01932         CRYP_Cmd(ENABLE);
01933 
01934         while (sz > 0)
01935         {
01936             /* flush IN/OUT FIFOs */
01937             CRYP_FIFOFlush();
01938 
01939             CRYP_DataIn(*(uint32_t*)&in[0]);
01940             CRYP_DataIn(*(uint32_t*)&in[4]);
01941             CRYP_DataIn(*(uint32_t*)&in[8]);
01942             CRYP_DataIn(*(uint32_t*)&in[12]);
01943 
01944             /* wait until the complete message has been processed */
01945             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
01946 
01947             *(uint32_t*)&out[0]  = CRYP_DataOut();
01948             *(uint32_t*)&out[4]  = CRYP_DataOut();
01949             *(uint32_t*)&out[8]  = CRYP_DataOut();
01950             *(uint32_t*)&out[12] = CRYP_DataOut();
01951 
01952             /* store iv for next call */
01953             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
01954 
01955             sz  -= 16;
01956             in  += 16;
01957             out += 16;
01958         }
01959 
01960         /* disable crypto processor */
01961         CRYP_Cmd(DISABLE);
01962 
01963         return 0;
01964     }
01965 
01966     #ifdef HAVE_AES_DECRYPT
01967     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
01968     {
01969         word32 *dec_key, *iv;
01970         CRYP_InitTypeDef AES_CRYP_InitStructure;
01971         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
01972         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
01973 
01974         dec_key = aes->key;
01975         iv = aes->reg;
01976 
01977         /* crypto structure initialization */
01978         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
01979         CRYP_StructInit(&AES_CRYP_InitStructure);
01980         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
01981 
01982         /* if input and output same will overwrite input iv */
01983         XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
01984 
01985         /* reset registers to their default values */
01986         CRYP_DeInit();
01987 
01988         /* load key into correct registers */
01989         switch(aes->rounds)
01990         {
01991             case 10: /* 128-bit key */
01992                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
01993                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[0];
01994                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1];
01995                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[2];
01996                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3];
01997                 break;
01998 
01999             case 12: /* 192-bit key */
02000                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
02001                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[0];
02002                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1];
02003                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[2];
02004                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3];
02005                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[4];
02006                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5];
02007                 break;
02008 
02009             case 14: /* 256-bit key */
02010                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
02011                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = dec_key[0];
02012                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1];
02013                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[2];
02014                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3];
02015                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[4];
02016                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5];
02017                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[6];
02018                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7];
02019                 break;
02020 
02021             default:
02022                 break;
02023         }
02024 
02025         /* set direction, mode, and datatype for key preparation */
02026         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
02027         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
02028         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
02029         CRYP_Init(&AES_CRYP_InitStructure);
02030         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
02031 
02032         /* enable crypto processor */
02033         CRYP_Cmd(ENABLE);
02034 
02035         /* wait until key has been prepared */
02036         while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
02037 
02038         /* set direction, mode, and datatype for decryption */
02039         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
02040         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
02041         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
02042         CRYP_Init(&AES_CRYP_InitStructure);
02043 
02044         /* set iv */
02045         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
02046 
02047         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
02048         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
02049         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
02050         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
02051         CRYP_IVInit(&AES_CRYP_IVInitStructure);
02052 
02053         /* enable crypto processor */
02054         CRYP_Cmd(ENABLE);
02055 
02056         while (sz > 0)
02057         {
02058             /* flush IN/OUT FIFOs */
02059             CRYP_FIFOFlush();
02060 
02061             CRYP_DataIn(*(uint32_t*)&in[0]);
02062             CRYP_DataIn(*(uint32_t*)&in[4]);
02063             CRYP_DataIn(*(uint32_t*)&in[8]);
02064             CRYP_DataIn(*(uint32_t*)&in[12]);
02065 
02066             /* wait until the complete message has been processed */
02067             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
02068 
02069             *(uint32_t*)&out[0]  = CRYP_DataOut();
02070             *(uint32_t*)&out[4]  = CRYP_DataOut();
02071             *(uint32_t*)&out[8]  = CRYP_DataOut();
02072             *(uint32_t*)&out[12] = CRYP_DataOut();
02073 
02074             /* store iv for next call */
02075             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
02076 
02077             sz -= 16;
02078             in += 16;
02079             out += 16;
02080         }
02081 
02082         /* disable crypto processor */
02083         CRYP_Cmd(DISABLE);
02084 
02085         return 0;
02086     }
02087     #endif /* HAVE_AES_DECRYPT */
02088 #elif defined(HAVE_COLDFIRE_SEC)
02089     static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,
02090                            word32 descHeader)
02091     {
02092         #ifdef DEBUG_WOLFSSL
02093             int i; int stat1, stat2; int ret;
02094         #endif
02095 
02096         int size;
02097         volatile int v;
02098 
02099         if ((pi == NULL) || (po == NULL))
02100             return BAD_FUNC_ARG;    /*wrong pointer*/
02101 
02102         LockMutex(&Mutex_AesSEC);
02103 
02104         /* Set descriptor for SEC */
02105         secDesc->length1 = 0x0;
02106         secDesc->pointer1 = NULL;
02107 
02108         secDesc->length2 = AES_BLOCK_SIZE;
02109         secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
02110 
02111         switch(aes->rounds) {
02112             case 10: secDesc->length3 = 16 ; break ;
02113             case 12: secDesc->length3 = 24 ; break ;
02114             case 14: secDesc->length3 = 32 ; break ;
02115         }
02116         XMEMCPY(secKey, aes->key, secDesc->length3);
02117 
02118         secDesc->pointer3 = (byte *)secKey;
02119         secDesc->pointer4 = AESBuffIn;
02120         secDesc->pointer5 = AESBuffOut;
02121         secDesc->length6 = 0x0;
02122         secDesc->pointer6 = NULL;
02123         secDesc->length7 = 0x0;
02124         secDesc->pointer7 = NULL;
02125         secDesc->nextDescriptorPtr = NULL;
02126 
02127         while (sz) {
02128             secDesc->header = descHeader;
02129             XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
02130             if ((sz % AES_BUFFER_SIZE) == sz) {
02131                 size = sz;
02132                 sz = 0;
02133             } else {
02134                 size = AES_BUFFER_SIZE;
02135                 sz -= AES_BUFFER_SIZE;
02136             }
02137             secDesc->length4 = size;
02138             secDesc->length5 = size;
02139 
02140             XMEMCPY(AESBuffIn, pi, size);
02141             if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
02142                 XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
02143                         AES_BLOCK_SIZE);
02144             }
02145 
02146             /* Point SEC to the location of the descriptor */
02147             MCF_SEC_FR0 = (uint32)secDesc;
02148             /* Initialize SEC and wait for encryption to complete */
02149             MCF_SEC_CCCR0 = 0x0000001a;
02150             /* poll SISR to determine when channel is complete */
02151             v=0;
02152 
02153             while ((secDesc->header>> 24) != 0xff) v++;
02154 
02155             #ifdef DEBUG_WOLFSSL
02156                 ret = MCF_SEC_SISRH;
02157                 stat1 = MCF_SEC_AESSR;
02158                 stat2 = MCF_SEC_AESISR;
02159                 if (ret & 0xe0000000) {
02160                     db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
02161                               "AESISR=%08x\n", i, ret, stat1, stat2);
02162                 }
02163             #endif
02164 
02165             XMEMCPY(po, AESBuffOut, size);
02166 
02167             if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
02168                 XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
02169                         AES_BLOCK_SIZE);
02170             } else {
02171                 XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
02172             }
02173 
02174             pi += size;
02175             po += size;
02176         }
02177 
02178         UnLockMutex(&Mutex_AesSEC);
02179         return 0;
02180     }
02181 
02182     int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
02183     {
02184         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
02185     }
02186 
02187     #ifdef HAVE_AES_DECRYPT
02188     int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
02189     {
02190         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
02191     }
02192     #endif /* HAVE_AES_DECRYPT */
02193 #elif defined(FREESCALE_MMCAU)
02194     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02195     {
02196         int i;
02197         int offset = 0;
02198         int len = sz;
02199 
02200         byte *iv;
02201         byte temp_block[AES_BLOCK_SIZE];
02202 
02203         iv      = (byte*)aes->reg;
02204 
02205         if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
02206             WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
02207             return BAD_ALIGN_E;
02208         }
02209 
02210         while (len > 0)
02211         {
02212             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
02213 
02214             /* XOR block with IV for CBC */
02215             for (i = 0; i < AES_BLOCK_SIZE; i++)
02216                 temp_block[i] ^= iv[i];
02217 
02218             wc_AesEncrypt(aes, temp_block, out + offset);
02219 
02220             len    -= AES_BLOCK_SIZE;
02221             offset += AES_BLOCK_SIZE;
02222 
02223             /* store IV for next block */
02224             XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02225         }
02226 
02227         return 0;
02228     }
02229     #ifdef HAVE_AES_DECRYPT
02230     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02231     {
02232         int i;
02233         int offset = 0;
02234         int len = sz;
02235 
02236         byte* iv;
02237         byte temp_block[AES_BLOCK_SIZE];
02238 
02239         iv      = (byte*)aes->reg;
02240 
02241         if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {
02242             WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
02243             return BAD_ALIGN_E;
02244         }
02245 
02246         while (len > 0)
02247         {
02248             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
02249 
02250             wc_AesDecrypt(aes, in + offset, out + offset);
02251 
02252             /* XOR block with IV for CBC */
02253             for (i = 0; i < AES_BLOCK_SIZE; i++)
02254                 (out + offset)[i] ^= iv[i];
02255 
02256             /* store IV for next block */
02257             XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
02258 
02259             len    -= AES_BLOCK_SIZE;
02260             offset += AES_BLOCK_SIZE;
02261         }
02262 
02263         return 0;
02264     }
02265     #endif /* HAVE_AES_DECRYPT */
02266 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
02267     /* core hardware crypt engine driver */
02268     static void wc_AesCrypt(Aes *aes, byte* out, const byte* in, word32 sz,
02269                                             int dir, int algo, int cryptoalgo)
02270     {
02271         securityAssociation *sa_p ;
02272         bufferDescriptor *bd_p ;
02273 
02274         volatile securityAssociation sa __attribute__((aligned (8)));
02275         volatile bufferDescriptor bd __attribute__((aligned (8)));
02276         volatile int k ;
02277 
02278         /* get uncached address */
02279         sa_p = KVA0_TO_KVA1(&sa) ;
02280         bd_p = KVA0_TO_KVA1(&bd) ;
02281 
02282         /* Sync cache and physical memory */
02283         if(PIC32MZ_IF_RAM(in)) {
02284             XMEMCPY((void *)KVA0_TO_KVA1(in), (void *)in, sz);
02285         }
02286         XMEMSET((void *)KVA0_TO_KVA1(out), 0, sz);
02287         /* Set up the Security Association */
02288         XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa));
02289         sa_p->SA_CTRL.ALGO = algo ; /* AES */
02290         sa_p->SA_CTRL.LNC = 1;
02291         sa_p->SA_CTRL.LOADIV = 1;
02292         sa_p->SA_CTRL.FB = 1;
02293         sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */
02294         sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
02295 
02296         if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM){
02297             switch(aes->keylen) {
02298             case 32:
02299                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_256 ;
02300                 break ;
02301             case 24:
02302                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_192 ;
02303                 break ;
02304             case 16:
02305                 sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
02306                 break ;
02307             }
02308         } else
02309             sa_p->SA_CTRL.KEYSIZE = PIC32_AES_KEYSIZE_128 ;
02310 
02311         ByteReverseWords(
02312         (word32 *)KVA0_TO_KVA1(sa.SA_ENCKEY + 8 - aes->keylen/sizeof(word32)),
02313                          (word32 *)aes->key_ce, aes->keylen);
02314         ByteReverseWords(
02315         (word32*)KVA0_TO_KVA1(sa.SA_ENCIV), (word32 *)aes->iv_ce, 16);
02316 
02317         XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd));
02318         /* Set up the Buffer Descriptor */
02319         bd_p->BD_CTRL.BUFLEN = sz;
02320         if(cryptoalgo == PIC32_CRYPTOALGO_AES_GCM) {
02321             if(sz % 0x10)
02322                 bd_p->BD_CTRL.BUFLEN = (sz/0x10 + 1) * 0x10 ;
02323         }
02324         bd_p->BD_CTRL.LIFM = 1;
02325         bd_p->BD_CTRL.SA_FETCH_EN = 1;
02326         bd_p->BD_CTRL.LAST_BD = 1;
02327         bd_p->BD_CTRL.DESC_EN = 1;
02328 
02329         bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ;
02330         bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ;
02331         bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out);
02332         bd_p->MSGLEN = sz ;
02333 
02334         CECON = 1 << 6;
02335         while (CECON);
02336 
02337         /* Run the engine */
02338         CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ;
02339         CEINTEN = 0x07;
02340         CECON = 0x27;
02341 
02342         WAIT_ENGINE ;
02343 
02344         if((cryptoalgo == PIC32_CRYPTOALGO_CBC) ||
02345            (cryptoalgo == PIC32_CRYPTOALGO_TCBC)||
02346            (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
02347             /* set iv for the next call */
02348             if(dir == PIC32_ENCRYPTION) {
02349                 XMEMCPY((void *)aes->iv_ce,
02350                         (void*)KVA0_TO_KVA1(out + sz - AES_BLOCK_SIZE),
02351                         AES_BLOCK_SIZE) ;
02352             } else {
02353                 ByteReverseWords((word32*)aes->iv_ce,
02354                         (word32 *)KVA0_TO_KVA1(in + sz - AES_BLOCK_SIZE),
02355                         AES_BLOCK_SIZE);
02356             }
02357         }
02358         XMEMCPY((byte *)out, (byte *)KVA0_TO_KVA1(out), sz) ;
02359         ByteReverseWords((word32*)out, (word32 *)out, sz);
02360     }
02361 
02362     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02363     {
02364         wc_AesCrypt(aes, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_AES,
02365                                                       PIC32_CRYPTOALGO_RCBC );
02366         return 0 ;
02367     }
02368     #ifdef HAVE_AES_DECRYPT
02369     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02370     {
02371         wc_AesCrypt(aes, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_AES,
02372                                                       PIC32_CRYPTOALGO_RCBC);
02373         return 0 ;
02374     }
02375     #endif /* HAVE_AES_DECRYPT */
02376 
02377 #else
02378     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02379     {
02380         word32 blocks = sz / AES_BLOCK_SIZE;
02381 
02382     #ifdef HAVE_CAVIUM
02383         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
02384             return wc_AesCaviumCbcEncrypt(aes, out, in, sz);
02385     #endif
02386 
02387     #ifdef WOLFSSL_AESNI
02388         if (haveAESNI) {
02389             #ifdef DEBUG_AESNI
02390                 printf("about to aes cbc encrypt\n");
02391                 printf("in  = %p\n", in);
02392                 printf("out = %p\n", out);
02393                 printf("aes->key = %p\n", aes->key);
02394                 printf("aes->reg = %p\n", aes->reg);
02395                 printf("aes->rounds = %d\n", aes->rounds);
02396                 printf("sz = %d\n", sz);
02397             #endif
02398 
02399             /* check alignment, decrypt doesn't need alignment */
02400             if ((wolfssl_word)in % 16) {
02401             #ifndef NO_WOLFSSL_ALLOC_ALIGN
02402                 byte* tmp = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02403                 WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
02404                 if (tmp == NULL) return MEMORY_E;
02405 
02406                 XMEMCPY(tmp, in, sz);
02407                 AES_CBC_encrypt(tmp, tmp, (byte*)aes->reg, sz, (byte*)aes->key,
02408                             aes->rounds);
02409                 /* store iv for next call */
02410                 XMEMCPY(aes->reg, tmp + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02411 
02412                 XMEMCPY(out, tmp, sz);
02413                 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02414                 return 0;
02415             #else
02416                 return BAD_ALIGN_E;
02417             #endif
02418             }
02419 
02420             AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
02421                             aes->rounds);
02422             /* store iv for next call */
02423             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02424 
02425             return 0;
02426         }
02427     #endif
02428 
02429         while (blocks--) {
02430             xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
02431             wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
02432             XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
02433 
02434             out += AES_BLOCK_SIZE;
02435             in  += AES_BLOCK_SIZE;
02436         }
02437 
02438         return 0;
02439     }
02440 
02441     #ifdef HAVE_AES_DECRYPT
02442     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02443     {
02444         word32 blocks = sz / AES_BLOCK_SIZE;
02445 
02446     #ifdef HAVE_CAVIUM
02447         if (aes->magic == WOLFSSL_AES_CAVIUM_MAGIC)
02448             return wc_AesCaviumCbcDecrypt(aes, out, in, sz);
02449     #endif
02450 
02451     #ifdef WOLFSSL_AESNI
02452         if (haveAESNI) {
02453             #ifdef DEBUG_AESNI
02454                 printf("about to aes cbc decrypt\n");
02455                 printf("in  = %p\n", in);
02456                 printf("out = %p\n", out);
02457                 printf("aes->key = %p\n", aes->key);
02458                 printf("aes->reg = %p\n", aes->reg);
02459                 printf("aes->rounds = %d\n", aes->rounds);
02460                 printf("sz = %d\n", sz);
02461             #endif
02462 
02463             /* if input and output same will overwrite input iv */
02464             XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02465             AES_CBC_decrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
02466                             aes->rounds);
02467             /* store iv for next call */
02468             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
02469             return 0;
02470         }
02471     #endif
02472 
02473         while (blocks--) {
02474             XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
02475             wc_AesDecrypt(aes, (byte*)aes->tmp, out);
02476             xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
02477             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
02478 
02479             out += AES_BLOCK_SIZE;
02480             in  += AES_BLOCK_SIZE;
02481         }
02482 
02483         return 0;
02484     }
02485     #endif
02486 
02487 #endif /* STM32F2_CRYPTO, AES-CBC block */
02488 #endif /* HAVE_AES_CBC */
02489 
02490 /* AES-CTR */
02491 #ifdef WOLFSSL_AES_COUNTER
02492 
02493     #ifdef STM32F2_CRYPTO
02494         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02495         {
02496             word32 *enc_key, *iv;
02497             CRYP_InitTypeDef AES_CRYP_InitStructure;
02498             CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
02499             CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
02500 
02501             enc_key = aes->key;
02502             iv = aes->reg;
02503 
02504             /* crypto structure initialization */
02505             CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
02506             CRYP_StructInit(&AES_CRYP_InitStructure);
02507             CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
02508 
02509             /* reset registers to their default values */
02510             CRYP_DeInit();
02511 
02512             /* load key into correct registers */
02513             switch(aes->rounds)
02514             {
02515                 case 10: /* 128-bit key */
02516                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
02517                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
02518                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
02519                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
02520                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
02521                     break;
02522 
02523                 case 12: /* 192-bit key */
02524                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
02525                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
02526                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
02527                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
02528                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
02529                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
02530                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
02531                     break;
02532 
02533                 case 14: /* 256-bit key */
02534                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
02535                     AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
02536                     AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
02537                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
02538                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
02539                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
02540                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
02541                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
02542                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
02543                     break;
02544 
02545                 default:
02546                     break;
02547             }
02548             CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
02549 
02550             /* set iv */
02551             ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
02552             AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
02553             AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
02554             AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
02555             AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
02556             CRYP_IVInit(&AES_CRYP_IVInitStructure);
02557 
02558             /* set direction, mode, and datatype */
02559             AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
02560             AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
02561             AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
02562             CRYP_Init(&AES_CRYP_InitStructure);
02563 
02564             /* enable crypto processor */
02565             CRYP_Cmd(ENABLE);
02566 
02567             while (sz > 0)
02568             {
02569                 /* flush IN/OUT FIFOs */
02570                 CRYP_FIFOFlush();
02571 
02572                 CRYP_DataIn(*(uint32_t*)&in[0]);
02573                 CRYP_DataIn(*(uint32_t*)&in[4]);
02574                 CRYP_DataIn(*(uint32_t*)&in[8]);
02575                 CRYP_DataIn(*(uint32_t*)&in[12]);
02576 
02577                 /* wait until the complete message has been processed */
02578                 while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
02579 
02580                 *(uint32_t*)&out[0]  = CRYP_DataOut();
02581                 *(uint32_t*)&out[4]  = CRYP_DataOut();
02582                 *(uint32_t*)&out[8]  = CRYP_DataOut();
02583                 *(uint32_t*)&out[12] = CRYP_DataOut();
02584 
02585                 /* store iv for next call */
02586                 XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02587 
02588                 sz  -= 16;
02589                 in  += 16;
02590                 out += 16;
02591             }
02592 
02593             /* disable crypto processor */
02594             CRYP_Cmd(DISABLE);
02595         }
02596 
02597     #elif defined(WOLFSSL_PIC32MZ_CRYPT)
02598         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02599         {
02600             int i ;
02601             char out_block[AES_BLOCK_SIZE] ;
02602             int odd ;
02603             int even ;
02604             char *tmp ; /* (char *)aes->tmp, for short */
02605 
02606             tmp = (char *)aes->tmp ;
02607             if(aes->left) {
02608                 if((aes->left + sz) >= AES_BLOCK_SIZE){
02609                     odd = AES_BLOCK_SIZE - aes->left ;
02610                 } else {
02611                     odd = sz ;
02612                 }
02613                 XMEMCPY(tmp+aes->left, in, odd) ;
02614                 if((odd+aes->left) == AES_BLOCK_SIZE){
02615                     wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
02616                         PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
02617                     XMEMCPY(out, out_block+aes->left, odd) ;
02618                     aes->left = 0 ;
02619                     XMEMSET(tmp, 0x0, AES_BLOCK_SIZE) ;
02620                     /* Increment IV */
02621                     for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
02622                         if (++((byte *)aes->iv_ce)[i])
02623                             break ;
02624                     }
02625                 }
02626                 in += odd ;
02627                 out+= odd ;
02628                 sz -= odd ;
02629             }
02630             odd = sz % AES_BLOCK_SIZE ;  /* if there is tail fragment */
02631             if(sz / AES_BLOCK_SIZE) {
02632                 even = (sz/AES_BLOCK_SIZE)*AES_BLOCK_SIZE ;
02633                 wc_AesCrypt(aes, out, in, even, PIC32_ENCRYPTION, PIC32_ALGO_AES,
02634                                                         PIC32_CRYPTOALGO_RCTR);
02635                 out += even ;
02636                 in  += even ;
02637                 do {  /* Increment IV */
02638                     for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
02639                         if (++((byte *)aes->iv_ce)[i])
02640                             break ;
02641                     }
02642                     even -= AES_BLOCK_SIZE ;
02643                 } while((int)even > 0) ;
02644             }
02645             if(odd) {
02646                 XMEMSET(tmp+aes->left, 0x0, AES_BLOCK_SIZE - aes->left) ;
02647                 XMEMCPY(tmp+aes->left, in, odd) ;
02648                 wc_AesCrypt(aes, out_block, tmp, AES_BLOCK_SIZE,
02649                         PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
02650                 XMEMCPY(out, out_block+aes->left,odd) ;
02651                 aes->left += odd ;
02652             }
02653         }
02654 
02655     #elif defined(HAVE_COLDFIRE_SEC)
02656         #error "Coldfire SEC doesn't currently support AES-CTR mode"
02657 
02658     #elif defined(FREESCALE_MMCAU)
02659         #error "Freescale mmCAU doesn't currently support AES-CTR mode"
02660 
02661     #else
02662         /* Increment AES counter */
02663         static INLINE void IncrementAesCounter(byte* inOutCtr)
02664         {
02665             int i;
02666 
02667             /* in network byte order so start at end and work back */
02668             for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
02669                 if (++inOutCtr[i])  /* we're done unless we overflow */
02670                     return;
02671             }
02672         }
02673 
02674         void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02675         {
02676             byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
02677 
02678             /* consume any unused bytes left in aes->tmp */
02679             while (aes->left && sz) {
02680                *(out++) = *(in++) ^ *(tmp++);
02681                aes->left--;
02682                sz--;
02683             }
02684 
02685             /* do as many block size ops as possible */
02686             while (sz >= AES_BLOCK_SIZE) {
02687                 wc_AesEncrypt(aes, (byte*)aes->reg, out);
02688                 IncrementAesCounter((byte*)aes->reg);
02689                 xorbuf(out, in, AES_BLOCK_SIZE);
02690 
02691                 out += AES_BLOCK_SIZE;
02692                 in  += AES_BLOCK_SIZE;
02693                 sz  -= AES_BLOCK_SIZE;
02694                 aes->left = 0;
02695             }
02696 
02697             /* handle non block size remaining and store unused byte count in left */
02698             if (sz) {
02699                 wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
02700                 IncrementAesCounter((byte*)aes->reg);
02701 
02702                 aes->left = AES_BLOCK_SIZE;
02703                 tmp = (byte*)aes->tmp;
02704 
02705                 while (sz--) {
02706                     *(out++) = *(in++) ^ *(tmp++);
02707                     aes->left--;
02708                 }
02709             }
02710         }
02711 
02712     #endif /* STM32F2_CRYPTO, AES-CTR block */
02713 
02714 #endif /* WOLFSSL_AES_COUNTER */
02715 
02716 #ifdef HAVE_AESGCM
02717 
02718 /*
02719  * The IV for AES GCM, stored in struct Aes's member reg, is comprised of
02720  * three parts in order:
02721  *   1. The implicit IV. This is generated from the PRF using the shared
02722  *      secrets between endpoints. It is 4 bytes long.
02723  *   2. The explicit IV. This is set by the user of the AES. It needs to be
02724  *      unique for each call to encrypt. The explicit IV is shared with the
02725  *      other end of the transaction in the clear.
02726  *   3. The counter. Each block of data is encrypted with its own sequence
02727  *      number counter.
02728  */
02729 
02730 #ifdef STM32F2_CRYPTO
02731     #error "STM32F2 crypto doesn't currently support AES-GCM mode"
02732 
02733 #elif defined(HAVE_COLDFIRE_SEC)
02734     #error "Coldfire SEC doesn't currently support AES-GCM mode"
02735 
02736 #elif defined(WOLFSSL_NRF51_AES)
02737     #error "nRF51 doesn't currently support AES-GCM mode"
02738 
02739 #endif
02740 
02741 enum {
02742     NONCE_SZ = 12,
02743     CTR_SZ   = 4
02744 };
02745 
02746 
02747 static INLINE void IncrementGcmCounter(byte* inOutCtr)
02748 {
02749     int i;
02750 
02751     /* in network byte order so start at end and work back */
02752     for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
02753         if (++inOutCtr[i])  /* we're done unless we overflow */
02754             return;
02755     }
02756 }
02757 
02758 
02759 #if defined(GCM_SMALL) || defined(GCM_TABLE)
02760 
02761 static INLINE void FlattenSzInBits(byte* buf, word32 sz)
02762 {
02763     /* Multiply the sz by 8 */
02764     word32 szHi = (sz >> (8*sizeof(sz) - 3));
02765     sz <<= 3;
02766 
02767     /* copy over the words of the sz into the destination buffer */
02768     buf[0] = (szHi >> 24) & 0xff;
02769     buf[1] = (szHi >> 16) & 0xff;
02770     buf[2] = (szHi >>  8) & 0xff;
02771     buf[3] = szHi & 0xff;
02772     buf[4] = (sz >> 24) & 0xff;
02773     buf[5] = (sz >> 16) & 0xff;
02774     buf[6] = (sz >>  8) & 0xff;
02775     buf[7] = sz & 0xff;
02776 }
02777 
02778 
02779 static INLINE void RIGHTSHIFTX(byte* x)
02780 {
02781     int i;
02782     int carryOut = 0;
02783     int carryIn = 0;
02784     int borrow = x[15] & 0x01;
02785 
02786     for (i = 0; i < AES_BLOCK_SIZE; i++) {
02787         carryOut = x[i] & 0x01;
02788         x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
02789         carryIn = carryOut;
02790     }
02791     if (borrow) x[0] ^= 0xE1;
02792 }
02793 
02794 #endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
02795 
02796 
02797 #ifdef GCM_TABLE
02798 
02799 static void GenerateM0(Aes* aes)
02800 {
02801     int i, j;
02802     byte (*m)[AES_BLOCK_SIZE] = aes->M0;
02803 
02804     XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
02805 
02806     for (i = 64; i > 0; i /= 2) {
02807         XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
02808         RIGHTSHIFTX(m[i]);
02809     }
02810 
02811     for (i = 2; i < 256; i *= 2) {
02812         for (j = 1; j < i; j++) {
02813             XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
02814             xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
02815         }
02816     }
02817 
02818     XMEMSET(m[0], 0, AES_BLOCK_SIZE);
02819 }
02820 
02821 #endif /* GCM_TABLE */
02822 
02823 
02824 int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
02825 {
02826     int  ret;
02827     byte iv[AES_BLOCK_SIZE];
02828 
02829     if (!((len == 16) || (len == 24) || (len == 32)))
02830         return BAD_FUNC_ARG;
02831 
02832     XMEMSET(iv, 0, AES_BLOCK_SIZE);
02833     ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
02834 
02835     #ifdef WOLFSSL_AESNI
02836         /* AES-NI code generates its own H value. */
02837         if (haveAESNI)
02838             return ret;
02839     #endif /* WOLFSSL_AESNI */
02840 
02841     if (ret == 0) {
02842         wc_AesEncrypt(aes, iv, aes->H);
02843     #ifdef GCM_TABLE
02844         GenerateM0(aes);
02845     #endif /* GCM_TABLE */
02846     }
02847 
02848     return ret;
02849 }
02850 
02851 
02852 #ifdef WOLFSSL_AESNI
02853 
02854 void gfmul(__m128i a, __m128i b, __m128i* out) XASM_LINK("gfmul");
02855 
02856 
02857 /* See Intel® Carry-Less Multiplication Instruction
02858  * and its Usage for Computing the GCM Mode White Paper
02859  * by Shay Gueron, Intel Mobility Group, Israel Development Center;
02860  * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */
02861 
02862 
02863 /* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */
02864 
02865 static void AES_GCM_encrypt(const unsigned char *in,
02866                             unsigned char *out,
02867                             const unsigned char* addt,
02868                             const unsigned char* ivec,
02869                             unsigned char *tag,
02870                             int nbytes, int abytes, int ibytes,
02871                             const unsigned char* key, int nr)
02872 {
02873     int i, j ,k;
02874     __m128i tmp1, tmp2, tmp3, tmp4;
02875     __m128i H, Y, T;
02876     __m128i *KEY = (__m128i*)key;
02877     __m128i ctr1, ctr2, ctr3, ctr4;
02878     __m128i last_block = _mm_setzero_si128();
02879     __m128i ONE = _mm_set_epi32(0, 1, 0, 0);
02880     __m128i FOUR = _mm_set_epi32(0, 4, 0, 0);
02881     __m128i BSWAP_EPI64 = _mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7);
02882     __m128i BSWAP_MASK = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
02883     __m128i X = _mm_setzero_si128();
02884 
02885     if(ibytes == 96/8) {
02886         Y = _mm_loadu_si128((__m128i*)ivec);
02887         Y = _mm_insert_epi32(Y, 0x1000000, 3);
02888             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
02889         tmp1 = _mm_xor_si128(X, KEY[0]);
02890         tmp2 = _mm_xor_si128(Y, KEY[0]);
02891         for(j=1; j < nr-1; j+=2) {
02892             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
02893             tmp2 = _mm_aesenc_si128(tmp2, KEY[j]);
02894             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
02895             tmp2 = _mm_aesenc_si128(tmp2, KEY[j+1]);
02896         }
02897         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
02898         tmp2 = _mm_aesenc_si128(tmp2, KEY[nr-1]);
02899         H = _mm_aesenclast_si128(tmp1, KEY[nr]);
02900         T = _mm_aesenclast_si128(tmp2, KEY[nr]);
02901         H = _mm_shuffle_epi8(H, BSWAP_MASK);
02902     }
02903     else {
02904         tmp1 = _mm_xor_si128(X, KEY[0]);
02905         for(j=1; j <nr; j++)
02906             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
02907         H = _mm_aesenclast_si128(tmp1, KEY[nr]);
02908         H = _mm_shuffle_epi8(H, BSWAP_MASK);
02909         Y = _mm_setzero_si128();
02910         for(i=0; i < ibytes/16; i++) {
02911             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
02912             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
02913             Y = _mm_xor_si128(Y, tmp1);
02914             gfmul(Y, H, &Y);
02915         }
02916         if(ibytes%16) {
02917             for(j=0; j < ibytes%16; j++)
02918                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
02919             tmp1 = last_block;
02920             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
02921             Y = _mm_xor_si128(Y, tmp1);
02922             gfmul(Y, H, &Y);
02923         }
02924         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
02925         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
02926         Y = _mm_xor_si128(Y, tmp1);
02927         gfmul(Y, H, &Y);
02928         Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */
02929         tmp1 = _mm_xor_si128(Y, KEY[0]);
02930         for(j=1; j < nr; j++)
02931             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
02932         T = _mm_aesenclast_si128(tmp1, KEY[nr]);
02933     }
02934 
02935     for(i=0; i<abytes/16; i++){
02936         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
02937         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
02938         X = _mm_xor_si128(X, tmp1);
02939         gfmul(X, H, &X);
02940     }
02941     if(abytes%16){
02942         last_block = _mm_setzero_si128();
02943         for(j=0; j<abytes%16; j++)
02944             ((unsigned char*)&last_block)[j] = addt[i*16+j];
02945         tmp1 = last_block;
02946         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
02947         X = _mm_xor_si128(X, tmp1);
02948         gfmul(X, H, &X);
02949     }
02950 
02951     ctr1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
02952     ctr1 = _mm_add_epi32(ctr1, ONE);
02953     ctr2 = _mm_add_epi32(ctr1, ONE);
02954     ctr3 = _mm_add_epi32(ctr2, ONE);
02955     ctr4 = _mm_add_epi32(ctr3, ONE);
02956 
02957     for(i=0; i < nbytes/16/4; i++){
02958         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
02959         tmp2 = _mm_shuffle_epi8(ctr2, BSWAP_EPI64);
02960         tmp3 = _mm_shuffle_epi8(ctr3, BSWAP_EPI64);
02961         tmp4 = _mm_shuffle_epi8(ctr4, BSWAP_EPI64);
02962         ctr1 = _mm_add_epi32(ctr1, FOUR);
02963         ctr2 = _mm_add_epi32(ctr2, FOUR);
02964         ctr3 = _mm_add_epi32(ctr3, FOUR);
02965         ctr4 = _mm_add_epi32(ctr4, FOUR);
02966         tmp1 =_mm_xor_si128(tmp1, KEY[0]);
02967         tmp2 =_mm_xor_si128(tmp2, KEY[0]);
02968         tmp3 =_mm_xor_si128(tmp3, KEY[0]);
02969         tmp4 =_mm_xor_si128(tmp4, KEY[0]);
02970         for(j=1; j < nr-1; j+=2){
02971             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
02972             tmp2 = _mm_aesenc_si128(tmp2, KEY[j]);
02973             tmp3 = _mm_aesenc_si128(tmp3, KEY[j]);
02974             tmp4 = _mm_aesenc_si128(tmp4, KEY[j]);
02975             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
02976             tmp2 = _mm_aesenc_si128(tmp2, KEY[j+1]);
02977             tmp3 = _mm_aesenc_si128(tmp3, KEY[j+1]);
02978             tmp4 = _mm_aesenc_si128(tmp4, KEY[j+1]);
02979         }
02980         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
02981         tmp2 = _mm_aesenc_si128(tmp2, KEY[nr-1]);
02982         tmp3 = _mm_aesenc_si128(tmp3, KEY[nr-1]);
02983         tmp4 = _mm_aesenc_si128(tmp4, KEY[nr-1]);
02984         tmp1 =_mm_aesenclast_si128(tmp1, KEY[nr]);
02985         tmp2 =_mm_aesenclast_si128(tmp2, KEY[nr]);
02986         tmp3 =_mm_aesenclast_si128(tmp3, KEY[nr]);
02987         tmp4 =_mm_aesenclast_si128(tmp4, KEY[nr]);
02988         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*4+0]));
02989         tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*4+1]));
02990         tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*4+2]));
02991         tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*4+3]));
02992         _mm_storeu_si128(&((__m128i*)out)[i*4+0], tmp1);
02993         _mm_storeu_si128(&((__m128i*)out)[i*4+1], tmp2);
02994         _mm_storeu_si128(&((__m128i*)out)[i*4+2], tmp3);
02995         _mm_storeu_si128(&((__m128i*)out)[i*4+3], tmp4);
02996         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
02997         tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);
02998         tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);
02999         tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);
03000         X = _mm_xor_si128(X, tmp1);
03001         gfmul(X, H, &X);
03002         X = _mm_xor_si128(X, tmp2);
03003         gfmul(X, H, &X);
03004         X = _mm_xor_si128(X, tmp3);
03005         gfmul(X, H, &X);
03006         X = _mm_xor_si128(X, tmp4);
03007         gfmul(X, H, &X);
03008     }
03009     for(k = i*4; k < nbytes/16; k++){
03010         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
03011         ctr1 = _mm_add_epi32(ctr1, ONE);
03012         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
03013         for(j=1; j<nr-1; j+=2){
03014             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03015             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
03016         }
03017         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03018         tmp1 = _mm_aesenclast_si128(tmp1, KEY[nr]);
03019         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
03020         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
03021         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03022         X =_mm_xor_si128(X, tmp1);
03023         gfmul(X, H, &X);
03024     }
03025     /* If one partial block remains */
03026     if(nbytes%16){
03027         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
03028         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
03029         for(j=1; j<nr-1; j+=2){
03030             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03031             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
03032         }
03033         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03034         tmp1 = _mm_aesenclast_si128(tmp1, KEY[nr]);
03035         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
03036         last_block = tmp1;
03037         for(j=0; j < nbytes%16; j++)
03038             out[k*16+j]=((unsigned char*)&last_block)[j];
03039         for(; j<16; j++)
03040             ((unsigned char*)&last_block)[j]=0;
03041         tmp1 = last_block;
03042         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03043         X =_mm_xor_si128(X, tmp1);
03044         gfmul(X, H, &X);
03045     }
03046     tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
03047     tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
03048     X = _mm_xor_si128(X, tmp1);
03049     gfmul(X, H, &X);
03050     X = _mm_shuffle_epi8(X, BSWAP_MASK);
03051     T = _mm_xor_si128(X, T);
03052     _mm_storeu_si128((__m128i*)tag, T);
03053 }
03054 
03055 
03056 #ifdef HAVE_AES_DECRYPT
03057 /* Figure 10. AES-GCM – Decrypt With Single Block Ghash at a Time */
03058 
03059 static int AES_GCM_decrypt(const unsigned char *in,
03060                            unsigned char *out,
03061                            const unsigned char* addt,
03062                            const unsigned char* ivec,
03063                            const unsigned char *tag, int nbytes, int abytes,
03064                            int ibytes, const unsigned char* key, int nr)
03065 {
03066     int i, j ,k;
03067     __m128i tmp1, tmp2, tmp3, tmp4;
03068     __m128i H, Y, T;
03069     __m128i *KEY = (__m128i*)key;
03070     __m128i ctr1, ctr2, ctr3, ctr4;
03071     __m128i last_block = _mm_setzero_si128();
03072     __m128i ONE = _mm_set_epi32(0, 1, 0, 0);
03073     __m128i FOUR = _mm_set_epi32(0, 4, 0, 0);
03074     __m128i BSWAP_EPI64 = _mm_set_epi8(8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7);
03075     __m128i BSWAP_MASK = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
03076     __m128i X = _mm_setzero_si128();
03077 
03078     if (ibytes == 96/8) {
03079         Y = _mm_loadu_si128((__m128i*)ivec);
03080         Y = _mm_insert_epi32(Y, 0x1000000, 3);
03081             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
03082         tmp1 = _mm_xor_si128(X, KEY[0]);
03083         tmp2 = _mm_xor_si128(Y, KEY[0]);
03084         for (j = 1; j < nr - 1; j += 2) {
03085             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03086             tmp2 = _mm_aesenc_si128(tmp2, KEY[j]);
03087             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
03088             tmp2 = _mm_aesenc_si128(tmp2, KEY[j+1]);
03089         }
03090         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03091         tmp2 = _mm_aesenc_si128(tmp2, KEY[nr-1]);
03092         H = _mm_aesenclast_si128(tmp1, KEY[nr]);
03093         T = _mm_aesenclast_si128(tmp2, KEY[nr]);
03094         H = _mm_shuffle_epi8(H, BSWAP_MASK);
03095     }
03096     else {
03097         tmp1 = _mm_xor_si128(X, KEY[0]);
03098         for (j = 1; j < nr; j++)
03099             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03100         H = _mm_aesenclast_si128(tmp1, KEY[nr]);
03101         H = _mm_shuffle_epi8(H, BSWAP_MASK);
03102         Y = _mm_setzero_si128();
03103 
03104         for (i = 0; i < ibytes / 16; i++) {
03105             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
03106             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03107             Y = _mm_xor_si128(Y, tmp1);
03108             gfmul(Y, H, &Y);
03109         }
03110 
03111         if (ibytes % 16) {
03112             for(j = 0; j < ibytes % 16; j++)
03113                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
03114             tmp1 = last_block;
03115             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03116             Y = _mm_xor_si128(Y, tmp1);
03117             gfmul(Y, H, &Y);
03118         }
03119 
03120         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
03121         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
03122         Y = _mm_xor_si128(Y, tmp1);
03123         gfmul(Y, H, &Y);
03124         Y = _mm_shuffle_epi8(Y, BSWAP_MASK);
03125         /* Compute E(K, Y0) */
03126         tmp1 = _mm_xor_si128(Y, KEY[0]);
03127         for(j=1; j < nr; j++)
03128             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03129         T = _mm_aesenclast_si128(tmp1, KEY[nr]);
03130     }
03131 
03132     for (i = 0; i < abytes / 16; i++) {
03133         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
03134         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03135         X = _mm_xor_si128(X, tmp1);
03136         gfmul(X, H, &X);
03137     }
03138 
03139     if (abytes % 16) {
03140         last_block = _mm_setzero_si128();
03141         for (j = 0;j < abytes % 16; j++)
03142             ((unsigned char*)&last_block)[j] = addt[i*16+j];
03143         tmp1 = last_block;
03144         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03145         X =_mm_xor_si128(X, tmp1);
03146         gfmul(X, H, &X);
03147     }
03148 
03149     for (i = 0; i < nbytes / 16; i++) {
03150         tmp1 = _mm_loadu_si128(&((__m128i*)in)[i]);
03151         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03152         X = _mm_xor_si128(X, tmp1);
03153         gfmul(X, H, &X);
03154     }
03155 
03156     if (nbytes % 16) {
03157         last_block = _mm_setzero_si128();
03158         for(j = 0; j < nbytes % 16; j++)
03159             ((unsigned char*)&last_block)[j] = in[i*16+j];
03160         tmp1 = last_block;
03161         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03162         X = _mm_xor_si128(X, tmp1);
03163         gfmul(X, H, &X);
03164     }
03165 
03166     tmp1 = _mm_insert_epi64(tmp1, nbytes * 8, 0);
03167     tmp1 = _mm_insert_epi64(tmp1, abytes * 8, 1);
03168     X = _mm_xor_si128(X, tmp1);
03169     gfmul(X, H, &X);
03170     X = _mm_shuffle_epi8(X, BSWAP_MASK);
03171     T = _mm_xor_si128(X, T);
03172 
03173     if (0xffff !=
03174            _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag))))
03175         return 0; /* in case the authentication failed */
03176 
03177     ctr1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
03178     ctr1 = _mm_add_epi32(ctr1, ONE);
03179     ctr2 = _mm_add_epi32(ctr1, ONE);
03180     ctr3 = _mm_add_epi32(ctr2, ONE);
03181     ctr4 = _mm_add_epi32(ctr3, ONE);
03182 
03183     for (i=0; i < nbytes/16/4; i++) {
03184         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
03185         tmp2 = _mm_shuffle_epi8(ctr2, BSWAP_EPI64);
03186         tmp3 = _mm_shuffle_epi8(ctr3, BSWAP_EPI64);
03187         tmp4 = _mm_shuffle_epi8(ctr4, BSWAP_EPI64);
03188 
03189         ctr1 = _mm_add_epi32(ctr1, FOUR);
03190         ctr2 = _mm_add_epi32(ctr2, FOUR);
03191         ctr3 = _mm_add_epi32(ctr3, FOUR);
03192         ctr4 = _mm_add_epi32(ctr4, FOUR);
03193 
03194         tmp1 =_mm_xor_si128(tmp1, KEY[0]);
03195         tmp2 =_mm_xor_si128(tmp2, KEY[0]);
03196         tmp3 =_mm_xor_si128(tmp3, KEY[0]);
03197         tmp4 =_mm_xor_si128(tmp4, KEY[0]);
03198 
03199         for (j = 1; j < nr - 1; j += 2) {
03200             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03201             tmp2 = _mm_aesenc_si128(tmp2, KEY[j]);
03202             tmp3 = _mm_aesenc_si128(tmp3, KEY[j]);
03203             tmp4 = _mm_aesenc_si128(tmp4, KEY[j]);
03204 
03205             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
03206             tmp2 = _mm_aesenc_si128(tmp2, KEY[j+1]);
03207             tmp3 = _mm_aesenc_si128(tmp3, KEY[j+1]);
03208             tmp4 = _mm_aesenc_si128(tmp4, KEY[j+1]);
03209         }
03210 
03211         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03212         tmp2 = _mm_aesenc_si128(tmp2, KEY[nr-1]);
03213         tmp3 = _mm_aesenc_si128(tmp3, KEY[nr-1]);
03214         tmp4 = _mm_aesenc_si128(tmp4, KEY[nr-1]);
03215 
03216         tmp1 =_mm_aesenclast_si128(tmp1, KEY[nr]);
03217         tmp2 =_mm_aesenclast_si128(tmp2, KEY[nr]);
03218         tmp3 =_mm_aesenclast_si128(tmp3, KEY[nr]);
03219         tmp4 =_mm_aesenclast_si128(tmp4, KEY[nr]);
03220 
03221         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*4+0]));
03222         tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*4+1]));
03223         tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*4+2]));
03224         tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*4+3]));
03225 
03226         _mm_storeu_si128(&((__m128i*)out)[i*4+0], tmp1);
03227         _mm_storeu_si128(&((__m128i*)out)[i*4+1], tmp2);
03228         _mm_storeu_si128(&((__m128i*)out)[i*4+2], tmp3);
03229         _mm_storeu_si128(&((__m128i*)out)[i*4+3], tmp4);
03230 
03231         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
03232         tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);
03233         tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);
03234         tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);
03235     }
03236 
03237     /* Acknowledge the dead store and continue */
03238     (void) tmp1;
03239     (void) tmp2;
03240     (void) tmp3;
03241     (void) tmp4;
03242 
03243     for (k = i*4; k < nbytes/16; k++) {
03244         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
03245         ctr1 = _mm_add_epi32(ctr1, ONE);
03246         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
03247         for (j = 1; j < nr-1; j += 2) {
03248             tmp1 = _mm_aesenc_si128(tmp1, KEY[j]);
03249             tmp1 = _mm_aesenc_si128(tmp1, KEY[j+1]);
03250         }
03251         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03252         tmp1 = _mm_aesenclast_si128(tmp1, KEY[nr]);
03253         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
03254         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
03255     }
03256 
03257     /* If one partial block remains */
03258     if (nbytes % 16) {
03259         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
03260         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
03261         for (j = 1; j < nr-1; j += 2) {
03262             tmp1 =_mm_aesenc_si128(tmp1, KEY[j]);
03263             tmp1 =_mm_aesenc_si128(tmp1, KEY[j+1]);
03264         }
03265         tmp1 = _mm_aesenc_si128(tmp1, KEY[nr-1]);
03266         tmp1 = _mm_aesenclast_si128(tmp1, KEY[nr]);
03267         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
03268         last_block = tmp1;
03269         for (j = 0; j < nbytes % 16; j++)
03270             out[k*16+j]=((unsigned char*)&last_block)[j];
03271     }
03272 
03273     return 1; /* when successful returns 1 */
03274 }
03275 #endif /* HAVE_AES_DECRYPT */
03276 #endif /* WOLFSSL_AESNI */
03277 
03278 
03279 #if defined(GCM_SMALL)
03280 
03281 static void GMULT(byte* X, byte* Y)
03282 {
03283     byte Z[AES_BLOCK_SIZE];
03284     byte V[AES_BLOCK_SIZE];
03285     int i, j;
03286 
03287     XMEMSET(Z, 0, AES_BLOCK_SIZE);
03288     XMEMCPY(V, X, AES_BLOCK_SIZE);
03289     for (i = 0; i < AES_BLOCK_SIZE; i++)
03290     {
03291         byte y = Y[i];
03292         for (j = 0; j < 8; j++)
03293         {
03294             if (y & 0x80) {
03295                 xorbuf(Z, V, AES_BLOCK_SIZE);
03296             }
03297 
03298             RIGHTSHIFTX(V);
03299             y = y << 1;
03300         }
03301     }
03302     XMEMCPY(X, Z, AES_BLOCK_SIZE);
03303 }
03304 
03305 
03306 static void GHASH(Aes* aes, const byte* a, word32 aSz,
03307                                 const byte* c, word32 cSz, byte* s, word32 sSz)
03308 {
03309     byte x[AES_BLOCK_SIZE];
03310     byte scratch[AES_BLOCK_SIZE];
03311     word32 blocks, partial;
03312     byte* h = aes->H;
03313 
03314     XMEMSET(x, 0, AES_BLOCK_SIZE);
03315 
03316     /* Hash in A, the Additional Authentication Data */
03317     if (aSz != 0 && a != NULL) {
03318         blocks = aSz / AES_BLOCK_SIZE;
03319         partial = aSz % AES_BLOCK_SIZE;
03320         while (blocks--) {
03321             xorbuf(x, a, AES_BLOCK_SIZE);
03322             GMULT(x, h);
03323             a += AES_BLOCK_SIZE;
03324         }
03325         if (partial != 0) {
03326             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
03327             XMEMCPY(scratch, a, partial);
03328             xorbuf(x, scratch, AES_BLOCK_SIZE);
03329             GMULT(x, h);
03330         }
03331     }
03332 
03333     /* Hash in C, the Ciphertext */
03334     if (cSz != 0 && c != NULL) {
03335         blocks = cSz / AES_BLOCK_SIZE;
03336         partial = cSz % AES_BLOCK_SIZE;
03337         while (blocks--) {
03338             xorbuf(x, c, AES_BLOCK_SIZE);
03339             GMULT(x, h);
03340             c += AES_BLOCK_SIZE;
03341         }
03342         if (partial != 0) {
03343             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
03344             XMEMCPY(scratch, c, partial);
03345             xorbuf(x, scratch, AES_BLOCK_SIZE);
03346             GMULT(x, h);
03347         }
03348     }
03349 
03350     /* Hash in the lengths of A and C in bits */
03351     FlattenSzInBits(&scratch[0], aSz);
03352     FlattenSzInBits(&scratch[8], cSz);
03353     xorbuf(x, scratch, AES_BLOCK_SIZE);
03354     GMULT(x, h);
03355 
03356     /* Copy the result into s. */
03357     XMEMCPY(s, x, sSz);
03358 }
03359 
03360 /* end GCM_SMALL */
03361 #elif defined(GCM_TABLE)
03362 
03363 static const byte R[256][2] = {
03364     {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
03365     {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
03366     {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
03367     {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
03368     {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
03369     {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
03370     {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
03371     {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
03372     {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
03373     {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
03374     {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
03375     {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
03376     {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
03377     {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
03378     {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
03379     {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
03380     {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
03381     {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
03382     {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
03383     {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
03384     {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
03385     {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
03386     {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
03387     {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
03388     {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
03389     {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
03390     {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
03391     {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
03392     {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
03393     {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
03394     {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
03395     {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
03396     {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
03397     {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
03398     {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
03399     {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
03400     {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
03401     {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
03402     {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
03403     {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
03404     {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
03405     {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
03406     {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
03407     {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
03408     {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
03409     {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
03410     {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
03411     {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
03412     {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
03413     {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
03414     {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
03415     {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
03416     {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
03417     {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
03418     {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
03419     {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
03420     {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
03421     {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
03422     {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
03423     {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
03424     {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
03425     {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
03426     {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
03427     {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
03428 
03429 
03430 static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
03431 {
03432     int i, j;
03433     byte Z[AES_BLOCK_SIZE];
03434     byte a;
03435 
03436     XMEMSET(Z, 0, sizeof(Z));
03437 
03438     for (i = 15; i > 0; i--) {
03439         xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
03440         a = Z[15];
03441 
03442         for (j = 15; j > 0; j--) {
03443             Z[j] = Z[j-1];
03444         }
03445 
03446         Z[0] = R[a][0];
03447         Z[1] ^= R[a][1];
03448     }
03449     xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
03450 
03451     XMEMCPY(x, Z, AES_BLOCK_SIZE);
03452 }
03453 
03454 
03455 static void GHASH(Aes* aes, const byte* a, word32 aSz,
03456                                 const byte* c, word32 cSz, byte* s, word32 sSz)
03457 {
03458     byte x[AES_BLOCK_SIZE];
03459     byte scratch[AES_BLOCK_SIZE];
03460     word32 blocks, partial;
03461 
03462     XMEMSET(x, 0, AES_BLOCK_SIZE);
03463 
03464     /* Hash in A, the Additional Authentication Data */
03465     if (aSz != 0 && a != NULL) {
03466         blocks = aSz / AES_BLOCK_SIZE;
03467         partial = aSz % AES_BLOCK_SIZE;
03468         while (blocks--) {
03469             xorbuf(x, a, AES_BLOCK_SIZE);
03470             GMULT(x, aes->M0);
03471             a += AES_BLOCK_SIZE;
03472         }
03473         if (partial != 0) {
03474             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
03475             XMEMCPY(scratch, a, partial);
03476             xorbuf(x, scratch, AES_BLOCK_SIZE);
03477             GMULT(x, aes->M0);
03478         }
03479     }
03480 
03481     /* Hash in C, the Ciphertext */
03482     if (cSz != 0 && c != NULL) {
03483         blocks = cSz / AES_BLOCK_SIZE;
03484         partial = cSz % AES_BLOCK_SIZE;
03485         while (blocks--) {
03486             xorbuf(x, c, AES_BLOCK_SIZE);
03487             GMULT(x, aes->M0);
03488             c += AES_BLOCK_SIZE;
03489         }
03490         if (partial != 0) {
03491             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
03492             XMEMCPY(scratch, c, partial);
03493             xorbuf(x, scratch, AES_BLOCK_SIZE);
03494             GMULT(x, aes->M0);
03495         }
03496     }
03497 
03498     /* Hash in the lengths of A and C in bits */
03499     FlattenSzInBits(&scratch[0], aSz);
03500     FlattenSzInBits(&scratch[8], cSz);
03501     xorbuf(x, scratch, AES_BLOCK_SIZE);
03502     GMULT(x, aes->M0);
03503 
03504     /* Copy the result into s. */
03505     XMEMCPY(s, x, sSz);
03506 }
03507 
03508 /* end GCM_TABLE */
03509 #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
03510 
03511 static void GMULT(word64* X, word64* Y)
03512 {
03513     word64 Z[2] = {0,0};
03514     word64 V[2] ;
03515     int i, j;
03516     V[0] = X[0] ;  V[1] = X[1] ;
03517 
03518     for (i = 0; i < 2; i++)
03519     {
03520         word64 y = Y[i];
03521         for (j = 0; j < 64; j++)
03522         {
03523             if (y & 0x8000000000000000ULL) {
03524                 Z[0] ^= V[0];
03525                 Z[1] ^= V[1];
03526             }
03527 
03528             if (V[1] & 0x0000000000000001) {
03529                 V[1] >>= 1;
03530                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
03531                 V[0] >>= 1;
03532                 V[0] ^= 0xE100000000000000ULL;
03533             }
03534             else {
03535                 V[1] >>= 1;
03536                 V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000ULL : 0);
03537                 V[0] >>= 1;
03538             }
03539             y <<= 1;
03540         }
03541     }
03542     X[0] = Z[0];
03543     X[1] = Z[1];
03544 }
03545 
03546 
03547 static void GHASH(Aes* aes, const byte* a, word32 aSz,
03548                                 const byte* c, word32 cSz, byte* s, word32 sSz)
03549 {
03550     word64 x[2] = {0,0};
03551     word32 blocks, partial;
03552     word64 bigH[2];
03553 
03554     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
03555     #ifdef LITTLE_ENDIAN_ORDER
03556         ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);
03557     #endif
03558 
03559     /* Hash in A, the Additional Authentication Data */
03560     if (aSz != 0 && a != NULL) {
03561         word64 bigA[2];
03562         blocks = aSz / AES_BLOCK_SIZE;
03563         partial = aSz % AES_BLOCK_SIZE;
03564         while (blocks--) {
03565             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
03566             #ifdef LITTLE_ENDIAN_ORDER
03567                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
03568             #endif
03569             x[0] ^= bigA[0];
03570             x[1] ^= bigA[1];
03571             GMULT(x, bigH);
03572             a += AES_BLOCK_SIZE;
03573         }
03574         if (partial != 0) {
03575             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
03576             XMEMCPY(bigA, a, partial);
03577             #ifdef LITTLE_ENDIAN_ORDER
03578                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
03579             #endif
03580             x[0] ^= bigA[0];
03581             x[1] ^= bigA[1];
03582             GMULT(x, bigH);
03583         }
03584     }
03585 
03586     /* Hash in C, the Ciphertext */
03587     if (cSz != 0 && c != NULL) {
03588         word64 bigC[2];
03589         blocks = cSz / AES_BLOCK_SIZE;
03590         partial = cSz % AES_BLOCK_SIZE;
03591         while (blocks--) {
03592             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
03593             #ifdef LITTLE_ENDIAN_ORDER
03594                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
03595             #endif
03596             x[0] ^= bigC[0];
03597             x[1] ^= bigC[1];
03598             GMULT(x, bigH);
03599             c += AES_BLOCK_SIZE;
03600         }
03601         if (partial != 0) {
03602             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
03603             XMEMCPY(bigC, c, partial);
03604             #ifdef LITTLE_ENDIAN_ORDER
03605                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
03606             #endif
03607             x[0] ^= bigC[0];
03608             x[1] ^= bigC[1];
03609             GMULT(x, bigH);
03610         }
03611     }
03612 
03613     /* Hash in the lengths in bits of A and C */
03614     {
03615         word64 len[2] ;
03616         len[0] = aSz ; len[1] = cSz;
03617 
03618         /* Lengths are in bytes. Convert to bits. */
03619         len[0] *= 8;
03620         len[1] *= 8;
03621 
03622         x[0] ^= len[0];
03623         x[1] ^= len[1];
03624         GMULT(x, bigH);
03625     }
03626     #ifdef LITTLE_ENDIAN_ORDER
03627         ByteReverseWords64(x, x, AES_BLOCK_SIZE);
03628     #endif
03629     XMEMCPY(s, x, sSz);
03630 }
03631 
03632 /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
03633 #else /* GCM_WORD32 */
03634 
03635 static void GMULT(word32* X, word32* Y)
03636 {
03637     word32 Z[4] = {0,0,0,0};
03638     word32 V[4] ;
03639     int i, j;
03640 
03641     V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
03642 
03643     for (i = 0; i < 4; i++)
03644     {
03645         word32 y = Y[i];
03646         for (j = 0; j < 32; j++)
03647         {
03648             if (y & 0x80000000) {
03649                 Z[0] ^= V[0];
03650                 Z[1] ^= V[1];
03651                 Z[2] ^= V[2];
03652                 Z[3] ^= V[3];
03653             }
03654 
03655             if (V[3] & 0x00000001) {
03656                 V[3] >>= 1;
03657                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
03658                 V[2] >>= 1;
03659                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
03660                 V[1] >>= 1;
03661                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
03662                 V[0] >>= 1;
03663                 V[0] ^= 0xE1000000;
03664             } else {
03665                 V[3] >>= 1;
03666                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
03667                 V[2] >>= 1;
03668                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
03669                 V[1] >>= 1;
03670                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
03671                 V[0] >>= 1;
03672             }
03673             y <<= 1;
03674         }
03675     }
03676     X[0] = Z[0];
03677     X[1] = Z[1];
03678     X[2] = Z[2];
03679     X[3] = Z[3];
03680 }
03681 
03682 
03683 static void GHASH(Aes* aes, const byte* a, word32 aSz,
03684                                 const byte* c, word32 cSz, byte* s, word32 sSz)
03685 {
03686     word32 x[4] = {0,0,0,0};
03687     word32 blocks, partial;
03688     word32 bigH[4];
03689 
03690     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
03691     #ifdef LITTLE_ENDIAN_ORDER
03692         ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
03693     #endif
03694 
03695     /* Hash in A, the Additional Authentication Data */
03696     if (aSz != 0 && a != NULL) {
03697         word32 bigA[4];
03698         blocks = aSz / AES_BLOCK_SIZE;
03699         partial = aSz % AES_BLOCK_SIZE;
03700         while (blocks--) {
03701             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
03702             #ifdef LITTLE_ENDIAN_ORDER
03703                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
03704             #endif
03705             x[0] ^= bigA[0];
03706             x[1] ^= bigA[1];
03707             x[2] ^= bigA[2];
03708             x[3] ^= bigA[3];
03709             GMULT(x, bigH);
03710             a += AES_BLOCK_SIZE;
03711         }
03712         if (partial != 0) {
03713             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
03714             XMEMCPY(bigA, a, partial);
03715             #ifdef LITTLE_ENDIAN_ORDER
03716                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
03717             #endif
03718             x[0] ^= bigA[0];
03719             x[1] ^= bigA[1];
03720             x[2] ^= bigA[2];
03721             x[3] ^= bigA[3];
03722             GMULT(x, bigH);
03723         }
03724     }
03725 
03726     /* Hash in C, the Ciphertext */
03727     if (cSz != 0 && c != NULL) {
03728         word32 bigC[4];
03729         blocks = cSz / AES_BLOCK_SIZE;
03730         partial = cSz % AES_BLOCK_SIZE;
03731         while (blocks--) {
03732             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
03733             #ifdef LITTLE_ENDIAN_ORDER
03734                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
03735             #endif
03736             x[0] ^= bigC[0];
03737             x[1] ^= bigC[1];
03738             x[2] ^= bigC[2];
03739             x[3] ^= bigC[3];
03740             GMULT(x, bigH);
03741             c += AES_BLOCK_SIZE;
03742         }
03743         if (partial != 0) {
03744             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
03745             XMEMCPY(bigC, c, partial);
03746             #ifdef LITTLE_ENDIAN_ORDER
03747                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
03748             #endif
03749             x[0] ^= bigC[0];
03750             x[1] ^= bigC[1];
03751             x[2] ^= bigC[2];
03752             x[3] ^= bigC[3];
03753             GMULT(x, bigH);
03754         }
03755     }
03756 
03757     /* Hash in the lengths in bits of A and C */
03758     {
03759         word32 len[4];
03760 
03761         /* Lengths are in bytes. Convert to bits. */
03762         len[0] = (aSz >> (8*sizeof(aSz) - 3));
03763         len[1] = aSz << 3;
03764         len[2] = (cSz >> (8*sizeof(cSz) - 3));
03765         len[3] = cSz << 3;
03766 
03767         x[0] ^= len[0];
03768         x[1] ^= len[1];
03769         x[2] ^= len[2];
03770         x[3] ^= len[3];
03771         GMULT(x, bigH);
03772     }
03773     #ifdef LITTLE_ENDIAN_ORDER
03774         ByteReverseWords(x, x, AES_BLOCK_SIZE);
03775     #endif
03776     XMEMCPY(s, x, sSz);
03777 }
03778 
03779 #endif /* end GCM_WORD32 */
03780 
03781 
03782 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
03783                    const byte* iv, word32 ivSz,
03784                    byte* authTag, word32 authTagSz,
03785                    const byte* authIn, word32 authInSz)
03786 {
03787     word32 blocks = sz / AES_BLOCK_SIZE;
03788     word32 partial = sz % AES_BLOCK_SIZE;
03789     const byte* p = in;
03790     byte* c = out;
03791     byte counter[AES_BLOCK_SIZE];
03792     byte initialCounter[AES_BLOCK_SIZE];
03793     byte *ctr ;
03794     byte scratch[AES_BLOCK_SIZE];
03795 
03796     WOLFSSL_ENTER("AesGcmEncrypt");
03797 
03798 #ifdef WOLFSSL_AESNI
03799     if (haveAESNI) {
03800         AES_GCM_encrypt((void*)in, out, (void*)authIn, (void*)iv, authTag,
03801                     sz, authInSz, ivSz, (byte*)aes->key, aes->rounds);
03802         return 0;
03803     }
03804 #endif
03805 
03806 #ifdef WOLFSSL_PIC32MZ_CRYPT
03807     ctr = (char *)aes->iv_ce ;
03808 #else
03809     ctr = counter ;
03810 #endif
03811 
03812     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
03813     if (ivSz == NONCE_SZ) {
03814         XMEMCPY(initialCounter, iv, ivSz);
03815         initialCounter[AES_BLOCK_SIZE - 1] = 1;
03816     }
03817     else {
03818         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
03819     }
03820     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
03821 
03822 #ifdef WOLFSSL_PIC32MZ_CRYPT
03823     if(blocks)
03824         wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
03825              PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
03826 #endif
03827     while (blocks--) {
03828         IncrementGcmCounter(ctr);
03829         #ifndef WOLFSSL_PIC32MZ_CRYPT
03830             wc_AesEncrypt(aes, ctr, scratch);
03831             xorbuf(scratch, p, AES_BLOCK_SIZE);
03832             XMEMCPY(c, scratch, AES_BLOCK_SIZE);
03833         #endif
03834         p += AES_BLOCK_SIZE;
03835         c += AES_BLOCK_SIZE;
03836     }
03837 
03838     if (partial != 0) {
03839         IncrementGcmCounter(ctr);
03840         wc_AesEncrypt(aes, ctr, scratch);
03841         xorbuf(scratch, p, partial);
03842         XMEMCPY(c, scratch, partial);
03843 
03844     }
03845 
03846     GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
03847     wc_AesEncrypt(aes, initialCounter, scratch);
03848     xorbuf(authTag, scratch, authTagSz);
03849 
03850     return 0;
03851 }
03852 
03853 
03854 #ifdef HAVE_AES_DECRYPT
03855 int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
03856                    const byte* iv, word32 ivSz,
03857                    const byte* authTag, word32 authTagSz,
03858                    const byte* authIn, word32 authInSz)
03859 {
03860     word32 blocks = sz / AES_BLOCK_SIZE;
03861     word32 partial = sz % AES_BLOCK_SIZE;
03862     const byte* c = in;
03863     byte* p = out;
03864     byte counter[AES_BLOCK_SIZE];
03865     byte initialCounter[AES_BLOCK_SIZE];
03866     byte *ctr ;
03867     byte scratch[AES_BLOCK_SIZE];
03868 
03869     WOLFSSL_ENTER("AesGcmDecrypt");
03870 
03871 #ifdef WOLFSSL_AESNI
03872     if (haveAESNI) {
03873         if (AES_GCM_decrypt(in, out, authIn, iv, authTag,
03874                         sz, authInSz, ivSz, (byte*)aes->key, aes->rounds) == 0)
03875             return AES_GCM_AUTH_E;
03876         return 0;
03877     }
03878 #endif
03879 
03880 #ifdef WOLFSSL_PIC32MZ_CRYPT
03881     ctr = (char *)aes->iv_ce ;
03882 #else
03883     ctr = counter ;
03884 #endif
03885 
03886     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
03887     if (ivSz == NONCE_SZ) {
03888         XMEMCPY(initialCounter, iv, ivSz);
03889         initialCounter[AES_BLOCK_SIZE - 1] = 1;
03890     }
03891     else {
03892         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
03893     }
03894     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
03895 
03896     /* Calculate the authTag again using the received auth data and the
03897      * cipher text. */
03898     {
03899         byte Tprime[AES_BLOCK_SIZE];
03900         byte EKY0[AES_BLOCK_SIZE];
03901 
03902         GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
03903         wc_AesEncrypt(aes, ctr, EKY0);
03904         xorbuf(Tprime, EKY0, sizeof(Tprime));
03905 
03906         if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
03907             return AES_GCM_AUTH_E;
03908         }
03909     }
03910 
03911 #ifdef WOLFSSL_PIC32MZ_CRYPT
03912     if(blocks)
03913         wc_AesCrypt(aes, out, in, blocks*AES_BLOCK_SIZE,
03914              PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM );
03915 #endif
03916 
03917     while (blocks--) {
03918         IncrementGcmCounter(ctr);
03919         #ifndef WOLFSSL_PIC32MZ_CRYPT
03920             wc_AesEncrypt(aes, ctr, scratch);
03921             xorbuf(scratch, c, AES_BLOCK_SIZE);
03922             XMEMCPY(p, scratch, AES_BLOCK_SIZE);
03923         #endif
03924         p += AES_BLOCK_SIZE;
03925         c += AES_BLOCK_SIZE;
03926     }
03927     if (partial != 0) {
03928         IncrementGcmCounter(ctr);
03929         wc_AesEncrypt(aes, ctr, scratch);
03930         xorbuf(scratch, c, partial);
03931         XMEMCPY(p, scratch, partial);
03932     }
03933     return 0;
03934 }
03935 
03936 #endif /* HAVE_AES_DECRYPT */
03937 
03938 WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
03939 {
03940     return wc_AesGcmSetKey(&gmac->aes, key, len);
03941 }
03942 
03943 
03944 WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
03945                               const byte* authIn, word32 authInSz,
03946                               byte* authTag, word32 authTagSz)
03947 {
03948     return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
03949                                          authTag, authTagSz, authIn, authInSz);
03950 }
03951 
03952 #endif /* HAVE_AESGCM */
03953 
03954 
03955 #ifdef HAVE_AESCCM
03956 
03957 #ifdef STM32F2_CRYPTO
03958     #error "STM32F2 crypto doesn't currently support AES-CCM mode"
03959 
03960 #elif defined(HAVE_COLDFIRE_SEC)
03961     #error "Coldfire SEC doesn't currently support AES-CCM mode"
03962 
03963 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
03964     #error "PIC32MZ doesn't currently support AES-CCM mode"
03965 
03966 #endif
03967 
03968 void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
03969 {
03970     byte nonce[AES_BLOCK_SIZE];
03971 
03972     if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
03973         return;
03974 
03975     XMEMSET(nonce, 0, sizeof(nonce));
03976     wc_AesSetKey(aes, key, keySz, nonce, AES_ENCRYPTION);
03977 }
03978 
03979 
03980 static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
03981 {
03982     /* process the bulk of the data */
03983     while (inSz >= AES_BLOCK_SIZE) {
03984         xorbuf(out, in, AES_BLOCK_SIZE);
03985         in += AES_BLOCK_SIZE;
03986         inSz -= AES_BLOCK_SIZE;
03987 
03988         wc_AesEncrypt(aes, out, out);
03989     }
03990 
03991     /* process remainder of the data */
03992     if (inSz > 0) {
03993         xorbuf(out, in, inSz);
03994         wc_AesEncrypt(aes, out, out);
03995     }
03996 }
03997 
03998 
03999 static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)
04000 {
04001     word32 authLenSz;
04002     word32 remainder;
04003 
04004     /* encode the length in */
04005     if (inSz <= 0xFEFF) {
04006         authLenSz = 2;
04007         out[0] ^= ((inSz & 0xFF00) >> 8);
04008         out[1] ^=  (inSz & 0x00FF);
04009     }
04010     else if (inSz <= 0xFFFFFFFF) {
04011         authLenSz = 6;
04012         out[0] ^= 0xFF; out[1] ^= 0xFE;
04013         out[2] ^= ((inSz & 0xFF000000) >> 24);
04014         out[3] ^= ((inSz & 0x00FF0000) >> 16);
04015         out[4] ^= ((inSz & 0x0000FF00) >>  8);
04016         out[5] ^=  (inSz & 0x000000FF);
04017     }
04018     /* Note, the protocol handles auth data up to 2^64, but we are
04019      * using 32-bit sizes right now, so the bigger data isn't handled
04020      * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
04021     else
04022         return;
04023 
04024     /* start fill out the rest of the first block */
04025     remainder = AES_BLOCK_SIZE - authLenSz;
04026     if (inSz >= remainder) {
04027         /* plenty of bulk data to fill the remainder of this block */
04028         xorbuf(out + authLenSz, in, remainder);
04029         inSz -= remainder;
04030         in += remainder;
04031     }
04032     else {
04033         /* not enough bulk data, copy what is available, and pad zero */
04034         xorbuf(out + authLenSz, in, inSz);
04035         inSz = 0;
04036     }
04037     wc_AesEncrypt(aes, out, out);
04038 
04039     if (inSz > 0)
04040         roll_x(aes, in, inSz, out);
04041 }
04042 
04043 
04044 static INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
04045 {
04046     word32 i;
04047 
04048     for (i = 0; i < lenSz; i++) {
04049         if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
04050     }
04051 }
04052 
04053 
04054 /* return 0 on success */
04055 int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
04056                    const byte* nonce, word32 nonceSz,
04057                    byte* authTag, word32 authTagSz,
04058                    const byte* authIn, word32 authInSz)
04059 {
04060     byte A[AES_BLOCK_SIZE];
04061     byte B[AES_BLOCK_SIZE];
04062     byte lenSz;
04063     word32 i;
04064     byte mask     = 0xFF;
04065     word32 wordSz = (word32)sizeof(word32);
04066 
04067     /* sanity check on arguments */
04068     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
04069             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
04070         return BAD_FUNC_ARG;
04071 
04072     XMEMCPY(B+1, nonce, nonceSz);
04073     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
04074     B[0] = (authInSz > 0 ? 64 : 0)
04075          + (8 * (((byte)authTagSz - 2) / 2))
04076          + (lenSz - 1);
04077     for (i = 0; i < lenSz; i++) {
04078         if (mask && i >= wordSz)
04079             mask = 0x00;
04080         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
04081     }
04082 
04083     wc_AesEncrypt(aes, B, A);
04084 
04085     if (authInSz > 0)
04086         roll_auth(aes, authIn, authInSz, A);
04087     if (inSz > 0)
04088         roll_x(aes, in, inSz, A);
04089     XMEMCPY(authTag, A, authTagSz);
04090 
04091     B[0] = lenSz - 1;
04092     for (i = 0; i < lenSz; i++)
04093         B[AES_BLOCK_SIZE - 1 - i] = 0;
04094     wc_AesEncrypt(aes, B, A);
04095     xorbuf(authTag, A, authTagSz);
04096 
04097     B[15] = 1;
04098     while (inSz >= AES_BLOCK_SIZE) {
04099         wc_AesEncrypt(aes, B, A);
04100         xorbuf(A, in, AES_BLOCK_SIZE);
04101         XMEMCPY(out, A, AES_BLOCK_SIZE);
04102 
04103         AesCcmCtrInc(B, lenSz);
04104         inSz -= AES_BLOCK_SIZE;
04105         in += AES_BLOCK_SIZE;
04106         out += AES_BLOCK_SIZE;
04107     }
04108     if (inSz > 0) {
04109         wc_AesEncrypt(aes, B, A);
04110         xorbuf(A, in, inSz);
04111         XMEMCPY(out, A, inSz);
04112     }
04113 
04114     ForceZero(A, AES_BLOCK_SIZE);
04115     ForceZero(B, AES_BLOCK_SIZE);
04116 
04117     return 0;
04118 }
04119 
04120 #ifdef HAVE_AES_DECRYPT
04121 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
04122                    const byte* nonce, word32 nonceSz,
04123                    const byte* authTag, word32 authTagSz,
04124                    const byte* authIn, word32 authInSz)
04125 {
04126     byte A[AES_BLOCK_SIZE];
04127     byte B[AES_BLOCK_SIZE];
04128     byte* o;
04129     byte lenSz;
04130     word32 i, oSz;
04131     int result = 0;
04132     byte mask     = 0xFF;
04133     word32 wordSz = (word32)sizeof(word32);
04134 
04135     /* sanity check on arguments */
04136     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
04137             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
04138         return BAD_FUNC_ARG;
04139 
04140     o = out;
04141     oSz = inSz;
04142     XMEMCPY(B+1, nonce, nonceSz);
04143     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
04144 
04145     B[0] = lenSz - 1;
04146     for (i = 0; i < lenSz; i++)
04147         B[AES_BLOCK_SIZE - 1 - i] = 0;
04148     B[15] = 1;
04149 
04150     while (oSz >= AES_BLOCK_SIZE) {
04151         wc_AesEncrypt(aes, B, A);
04152         xorbuf(A, in, AES_BLOCK_SIZE);
04153         XMEMCPY(o, A, AES_BLOCK_SIZE);
04154 
04155         AesCcmCtrInc(B, lenSz);
04156         oSz -= AES_BLOCK_SIZE;
04157         in += AES_BLOCK_SIZE;
04158         o += AES_BLOCK_SIZE;
04159     }
04160     if (inSz > 0) {
04161         wc_AesEncrypt(aes, B, A);
04162         xorbuf(A, in, oSz);
04163         XMEMCPY(o, A, oSz);
04164     }
04165 
04166     for (i = 0; i < lenSz; i++)
04167         B[AES_BLOCK_SIZE - 1 - i] = 0;
04168     wc_AesEncrypt(aes, B, A);
04169 
04170     o = out;
04171     oSz = inSz;
04172 
04173     B[0] = (authInSz > 0 ? 64 : 0)
04174          + (8 * (((byte)authTagSz - 2) / 2))
04175          + (lenSz - 1);
04176     for (i = 0; i < lenSz; i++) {
04177         if (mask && i >= wordSz)
04178             mask = 0x00;
04179         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
04180     }
04181 
04182     wc_AesEncrypt(aes, B, A);
04183 
04184     if (authInSz > 0)
04185         roll_auth(aes, authIn, authInSz, A);
04186     if (inSz > 0)
04187         roll_x(aes, o, oSz, A);
04188 
04189     B[0] = lenSz - 1;
04190     for (i = 0; i < lenSz; i++)
04191         B[AES_BLOCK_SIZE - 1 - i] = 0;
04192     wc_AesEncrypt(aes, B, B);
04193     xorbuf(A, B, authTagSz);
04194 
04195     if (ConstantCompare(A, authTag, authTagSz) != 0) {
04196         /* If the authTag check fails, don't keep the decrypted data.
04197          * Unfortunately, you need the decrypted data to calculate the
04198          * check value. */
04199         XMEMSET(out, 0, inSz);
04200         result = AES_CCM_AUTH_E;
04201     }
04202 
04203     ForceZero(A, AES_BLOCK_SIZE);
04204     ForceZero(B, AES_BLOCK_SIZE);
04205     o = NULL;
04206 
04207     return result;
04208 }
04209 #endif /* HAVE_AES_DECRYPT */
04210 #endif /* HAVE_AESCCM */
04211 
04212 
04213 #ifdef HAVE_CAVIUM
04214 
04215 #include <wolfssl/wolfcrypt/logging.h>
04216 #include "cavium_common.h"
04217 
04218 /* Initialize Aes for use with Nitrox device */
04219 int wc_AesInitCavium(Aes* aes, int devId)
04220 {
04221     if (aes == NULL)
04222         return -1;
04223 
04224     if (CspAllocContext(CONTEXT_SSL, &aes->contextHandle, devId) != 0)
04225         return -1;
04226 
04227     aes->devId = devId;
04228     aes->magic = WOLFSSL_AES_CAVIUM_MAGIC;
04229 
04230     return 0;
04231 }
04232 
04233 
04234 /* Free Aes from use with Nitrox device */
04235 void wc_AesFreeCavium(Aes* aes)
04236 {
04237     if (aes == NULL)
04238         return;
04239 
04240     if (aes->magic != WOLFSSL_AES_CAVIUM_MAGIC)
04241         return;
04242 
04243     CspFreeContext(CONTEXT_SSL, aes->contextHandle, aes->devId);
04244     aes->magic = 0;
04245 }
04246 
04247 
04248 static int wc_AesCaviumSetKey(Aes* aes, const byte* key, word32 length,
04249                            const byte* iv)
04250 {
04251     if (aes == NULL)
04252         return -1;
04253 
04254     XMEMCPY(aes->key, key, length);   /* key still holds key, iv still in reg */
04255     if (length == 16)
04256         aes->type = AES_128;
04257     else if (length == 24)
04258         aes->type = AES_192;
04259     else if (length == 32)
04260         aes->type = AES_256;
04261 
04262     return wc_AesSetIV(aes, iv);
04263 }
04264 
04265 #ifdef HAVE_AES_CBC
04266 static int wc_AesCaviumCbcEncrypt(Aes* aes, byte* out, const byte* in,
04267                                word32 length)
04268 {
04269     wolfssl_word offset = 0;
04270     word32 requestId;
04271 
04272     while (length > WOLFSSL_MAX_16BIT) {
04273         word16 slen = (word16)WOLFSSL_MAX_16BIT;
04274         if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
04275                           aes->type, slen, (byte*)in + offset, out + offset,
04276                           (byte*)aes->reg, (byte*)aes->key, &requestId,
04277                           aes->devId) != 0) {
04278             WOLFSSL_MSG("Bad Cavium Aes Encrypt");
04279             return -1;
04280         }
04281         length -= WOLFSSL_MAX_16BIT;
04282         offset += WOLFSSL_MAX_16BIT;
04283         XMEMCPY(aes->reg, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
04284     }
04285     if (length) {
04286         word16 slen = (word16)length;
04287         if (CspEncryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
04288                           aes->type, slen, (byte*)in + offset, out + offset,
04289                           (byte*)aes->reg, (byte*)aes->key, &requestId,
04290                           aes->devId) != 0) {
04291             WOLFSSL_MSG("Bad Cavium Aes Encrypt");
04292             return -1;
04293         }
04294         XMEMCPY(aes->reg, out + offset+length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
04295     }
04296     return 0;
04297 }
04298 
04299 #ifdef HAVE_AES_DECRYPT
04300 static int wc_AesCaviumCbcDecrypt(Aes* aes, byte* out, const byte* in,
04301                                word32 length)
04302 {
04303     word32 requestId;
04304     wolfssl_word offset = 0;
04305 
04306     while (length > WOLFSSL_MAX_16BIT) {
04307         word16 slen = (word16)WOLFSSL_MAX_16BIT;
04308         XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
04309         if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
04310                           aes->type, slen, (byte*)in + offset, out + offset,
04311                           (byte*)aes->reg, (byte*)aes->key, &requestId,
04312                           aes->devId) != 0) {
04313             WOLFSSL_MSG("Bad Cavium Aes Decrypt");
04314             return -1;
04315         }
04316         length -= WOLFSSL_MAX_16BIT;
04317         offset += WOLFSSL_MAX_16BIT;
04318         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
04319     }
04320     if (length) {
04321         word16 slen = (word16)length;
04322         XMEMCPY(aes->tmp, in + offset + slen - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
04323         if (CspDecryptAes(CAVIUM_BLOCKING, aes->contextHandle, CAVIUM_NO_UPDATE,
04324                           aes->type, slen, (byte*)in + offset, out + offset,
04325                           (byte*)aes->reg, (byte*)aes->key, &requestId,
04326                           aes->devId) != 0) {
04327             WOLFSSL_MSG("Bad Cavium Aes Decrypt");
04328             return -1;
04329         }
04330         XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
04331     }
04332     return 0;
04333 }
04334 #endif /* HAVE_AES_DECRYPT */
04335 #endif /* HAVE_AES_CBC */
04336 
04337 #endif /* HAVE_CAVIUM */
04338 
04339 #endif /* WOLFSSL_TI_CRYPT */
04340 
04341 #endif /* HAVE_FIPS */
04342 
04343 #endif /* NO_AES */
04344