wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

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-2020 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 #include <wolfssl/wolfcrypt/error-crypt.h >
00029 
00030 #if !defined(NO_AES)
00031 
00032 /* Tip: Locate the software cipher modes by searching for "Software AES" */
00033 
00034 #if defined(HAVE_FIPS) && \
00035     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00036 
00037     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00038     #define FIPS_NO_WRAPPERS
00039 
00040     #ifdef USE_WINDOWS_API
00041         #pragma code_seg(".fipsA$g")
00042         #pragma const_seg(".fipsB$g")
00043     #endif
00044 #endif
00045 
00046 #include <wolfssl/wolfcrypt/aes.h >
00047 #include <wolfssl/wolfcrypt/cpuid.h>
00048 
00049 #ifdef WOLF_CRYPTO_CB
00050     #include <wolfssl/wolfcrypt/cryptocb.h>
00051 #endif
00052 
00053 
00054 /* fips wrapper calls, user can call direct */
00055 #if defined(HAVE_FIPS) && \
00056     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
00057 
00058     int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
00059                               int dir)
00060     {
00061         if (aes == NULL ||  !( (len == 16) || (len == 24) || (len == 32)) ) {
00062             return BAD_FUNC_ARG;
00063         }
00064 
00065         return AesSetKey_fips(aes, key, len, iv, dir);
00066     }
00067     int wc_AesSetIV(Aes* aes, const byte* iv)
00068     {
00069         if (aes == NULL) {
00070             return BAD_FUNC_ARG;
00071         }
00072 
00073         return AesSetIV_fips(aes, iv);
00074     }
00075     #ifdef HAVE_AES_CBC
00076         int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00077         {
00078             if (aes == NULL || out == NULL || in == NULL) {
00079                 return BAD_FUNC_ARG;
00080             }
00081 
00082             return AesCbcEncrypt_fips(aes, out, in, sz);
00083         }
00084         #ifdef HAVE_AES_DECRYPT
00085             int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00086             {
00087                 if (aes == NULL || out == NULL || in == NULL
00088                                             || sz % AES_BLOCK_SIZE != 0) {
00089                     return BAD_FUNC_ARG;
00090                 }
00091 
00092                 return AesCbcDecrypt_fips(aes, out, in, sz);
00093             }
00094         #endif /* HAVE_AES_DECRYPT */
00095     #endif /* HAVE_AES_CBC */
00096 
00097     /* AES-CTR */
00098     #ifdef WOLFSSL_AES_COUNTER
00099         int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
00100         {
00101             if (aes == NULL || out == NULL || in == NULL) {
00102                 return BAD_FUNC_ARG;
00103             }
00104 
00105             return AesCtrEncrypt(aes, out, in, sz);
00106         }
00107     #endif
00108 
00109     /* AES-DIRECT */
00110     #if defined(WOLFSSL_AES_DIRECT)
00111         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
00112         {
00113             AesEncryptDirect(aes, out, in);
00114         }
00115 
00116         #ifdef HAVE_AES_DECRYPT
00117             void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
00118             {
00119                 AesDecryptDirect(aes, out, in);
00120             }
00121         #endif /* HAVE_AES_DECRYPT */
00122 
00123         int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
00124                                         const byte* iv, int dir)
00125         {
00126             return AesSetKeyDirect(aes, key, len, iv, dir);
00127         }
00128     #endif /* WOLFSSL_AES_DIRECT */
00129 
00130     /* AES-GCM */
00131     #ifdef HAVE_AESGCM
00132         int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
00133         {
00134             if (aes == NULL || !( (len == 16) || (len == 24) || (len == 32)) ) {
00135                 return BAD_FUNC_ARG;
00136             }
00137 
00138             return AesGcmSetKey_fips(aes, key, len);
00139         }
00140         int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
00141                                       const byte* iv, word32 ivSz,
00142                                       byte* authTag, word32 authTagSz,
00143                                       const byte* authIn, word32 authInSz)
00144         {
00145             if (aes == NULL || authTagSz > AES_BLOCK_SIZE ||
00146                         authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ ||
00147                         ivSz == 0 || ivSz > AES_BLOCK_SIZE) {
00148                 return BAD_FUNC_ARG;
00149             }
00150 
00151             return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag,
00152                 authTagSz, authIn, authInSz);
00153         }
00154 
00155         #ifdef HAVE_AES_DECRYPT
00156             int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
00157                                           const byte* iv, word32 ivSz,
00158                                           const byte* authTag, word32 authTagSz,
00159                                           const byte* authIn, word32 authInSz)
00160             {
00161                 if (aes == NULL || out == NULL || in == NULL || iv == NULL
00162                         || authTag == NULL || authTagSz > AES_BLOCK_SIZE ||
00163                         ivSz == 0 || ivSz > AES_BLOCK_SIZE) {
00164                     return BAD_FUNC_ARG;
00165                 }
00166 
00167                 return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag,
00168                     authTagSz, authIn, authInSz);
00169             }
00170         #endif /* HAVE_AES_DECRYPT */
00171 
00172         int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
00173         {
00174             if (gmac == NULL || key == NULL || !((len == 16) ||
00175                                 (len == 24) || (len == 32)) ) {
00176                 return BAD_FUNC_ARG;
00177             }
00178 
00179             return GmacSetKey(gmac, key, len);
00180         }
00181         int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
00182                                       const byte* authIn, word32 authInSz,
00183                                       byte* authTag, word32 authTagSz)
00184         {
00185             if (gmac == NULL || authTagSz > AES_BLOCK_SIZE ||
00186                                authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
00187                 return BAD_FUNC_ARG;
00188             }
00189 
00190             return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,
00191                               authTag, authTagSz);
00192         }
00193     #endif /* HAVE_AESGCM */
00194 
00195     /* AES-CCM */
00196     #if defined(HAVE_AESCCM) && \
00197         defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00198         int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
00199         {
00200             return AesCcmSetKey(aes, key, keySz);
00201         }
00202         int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
00203                                       const byte* nonce, word32 nonceSz,
00204                                       byte* authTag, word32 authTagSz,
00205                                       const byte* authIn, word32 authInSz)
00206         {
00207             /* sanity check on arguments */
00208             if (aes == NULL || out == NULL || in == NULL || nonce == NULL
00209                     || authTag == NULL || nonceSz < 7 || nonceSz > 13)
00210                 return BAD_FUNC_ARG;
00211 
00212             AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag,
00213                 authTagSz, authIn, authInSz);
00214             return 0;
00215         }
00216 
00217         #ifdef HAVE_AES_DECRYPT
00218             int  wc_AesCcmDecrypt(Aes* aes, byte* out,
00219                 const byte* in, word32 inSz,
00220                 const byte* nonce, word32 nonceSz,
00221                 const byte* authTag, word32 authTagSz,
00222                 const byte* authIn, word32 authInSz)
00223             {
00224 
00225                 if (aes == NULL || out == NULL || in == NULL || nonce == NULL
00226                     || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
00227                         return BAD_FUNC_ARG;
00228                 }
00229 
00230                 return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
00231                     authTag, authTagSz, authIn, authInSz);
00232             }
00233         #endif /* HAVE_AES_DECRYPT */
00234     #endif /* HAVE_AESCCM && HAVE_FIPS_VERSION 2 */
00235 
00236     int wc_AesInit(Aes* aes, void* h, int i)
00237     {
00238         if (aes == NULL)
00239             return BAD_FUNC_ARG;
00240 
00241         (void)h;
00242         (void)i;
00243 
00244         /* FIPS doesn't support:
00245             return AesInit(aes, h, i); */
00246         return 0;
00247     }
00248     void wc_AesFree(Aes* aes)
00249     {
00250         (void)aes;
00251         /* FIPS doesn't support:
00252             AesFree(aes); */
00253     }
00254 
00255 #else /* else build without fips, or for FIPS v2 */
00256 
00257 
00258 #if defined(WOLFSSL_TI_CRYPT)
00259     #include <wolfcrypt/src/port/ti/ti-aes.c>
00260 #else
00261 
00262 #include <wolfssl/wolfcrypt/logging.h >
00263 
00264 #ifdef NO_INLINE
00265     #include <wolfssl/wolfcrypt/misc.h>
00266 #else
00267     #define WOLFSSL_MISC_INCLUDED
00268     #include <wolfcrypt/src/misc.c>
00269 #endif
00270 
00271 #if !defined(WOLFSSL_ARMASM)
00272 
00273 #ifdef WOLFSSL_IMX6_CAAM_BLOB
00274     /* case of possibly not using hardware acceleration for AES but using key
00275        blobs */
00276     #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
00277 #endif
00278 
00279 #ifdef DEBUG_AESNI
00280     #include <stdio.h>
00281 #endif
00282 
00283 #ifdef _MSC_VER
00284     /* 4127 warning constant while(1)  */
00285     #pragma warning(disable: 4127)
00286 #endif
00287 
00288 
00289 /* Define AES implementation includes and functions */
00290 #if defined(STM32_CRYPTO)
00291      /* STM32F2/F4/F7/L4 hardware AES support for ECB, CBC, CTR and GCM modes */
00292 
00293 #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
00294 
00295     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00296     {
00297         int ret = 0;
00298     #ifdef WOLFSSL_STM32_CUBEMX
00299         CRYP_HandleTypeDef hcryp;
00300     #else
00301         CRYP_InitTypeDef cryptInit;
00302         CRYP_KeyInitTypeDef keyInit;
00303     #endif
00304 
00305     #ifdef WOLFSSL_STM32_CUBEMX
00306         ret = wc_Stm32_Aes_Init(aes, &hcryp);
00307         if (ret != 0)
00308             return ret;
00309 
00310     #ifdef STM32_CRYPTO_AES_ONLY
00311         hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
00312         hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
00313         hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
00314     #elif defined(STM32_HAL_V2)
00315         hcryp.Init.Algorithm  = CRYP_AES_ECB;
00316     #endif
00317         HAL_CRYP_Init(&hcryp);
00318 
00319     #ifdef STM32_CRYPTO_AES_ONLY
00320         ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
00321             outBlock, STM32_HAL_TIMEOUT);
00322     #elif defined(STM32_HAL_V2)
00323         ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
00324             (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
00325     #else
00326         ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
00327             outBlock, STM32_HAL_TIMEOUT);
00328     #endif
00329         if (ret != HAL_OK) {
00330             ret = WC_TIMEOUT_E;
00331         }
00332         HAL_CRYP_DeInit(&hcryp);
00333 
00334     #else /* STD_PERI_LIB */
00335         ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
00336         if (ret != 0)
00337             return ret;
00338 
00339         /* reset registers to their default values */
00340         CRYP_DeInit();
00341 
00342         /* setup key */
00343         CRYP_KeyInit(&keyInit);
00344 
00345         /* set direction and mode */
00346         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
00347         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
00348         CRYP_Init(&cryptInit);
00349 
00350         /* enable crypto processor */
00351         CRYP_Cmd(ENABLE);
00352 
00353         /* flush IN/OUT FIFOs */
00354         CRYP_FIFOFlush();
00355 
00356         CRYP_DataIn(*(uint32_t*)&inBlock[0]);
00357         CRYP_DataIn(*(uint32_t*)&inBlock[4]);
00358         CRYP_DataIn(*(uint32_t*)&inBlock[8]);
00359         CRYP_DataIn(*(uint32_t*)&inBlock[12]);
00360 
00361         /* wait until the complete message has been processed */
00362         while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00363 
00364         *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
00365         *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
00366         *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
00367         *(uint32_t*)&outBlock[12] = CRYP_DataOut();
00368 
00369         /* disable crypto processor */
00370         CRYP_Cmd(DISABLE);
00371     #endif /* WOLFSSL_STM32_CUBEMX */
00372 
00373         return ret;
00374     }
00375 #endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
00376 
00377 #ifdef HAVE_AES_DECRYPT
00378     #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM)
00379     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00380     {
00381         int ret = 0;
00382     #ifdef WOLFSSL_STM32_CUBEMX
00383         CRYP_HandleTypeDef hcryp;
00384     #else
00385         CRYP_InitTypeDef cryptInit;
00386         CRYP_KeyInitTypeDef keyInit;
00387     #endif
00388 
00389     #ifdef WOLFSSL_STM32_CUBEMX
00390         ret = wc_Stm32_Aes_Init(aes, &hcryp);
00391         if (ret != 0)
00392             return ret;
00393 
00394     #ifdef STM32_CRYPTO_AES_ONLY
00395         hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
00396         hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
00397         hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
00398     #elif defined(STM32_HAL_V2)
00399         hcryp.Init.Algorithm  = CRYP_AES_ECB;
00400     #endif
00401         HAL_CRYP_Init(&hcryp);
00402 
00403     #ifdef STM32_CRYPTO_AES_ONLY
00404         ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
00405             outBlock, STM32_HAL_TIMEOUT);
00406     #elif defined(STM32_HAL_V2)
00407         ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
00408             (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
00409     #else
00410         ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
00411             outBlock, STM32_HAL_TIMEOUT);
00412     #endif
00413         if (ret != HAL_OK) {
00414             ret = WC_TIMEOUT_E;
00415         }
00416         HAL_CRYP_DeInit(&hcryp);
00417 
00418     #else /* STD_PERI_LIB */
00419         ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
00420         if (ret != 0)
00421             return ret;
00422 
00423         /* reset registers to their default values */
00424         CRYP_DeInit();
00425 
00426         /* set direction and key */
00427         CRYP_KeyInit(&keyInit);
00428         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00429         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
00430         CRYP_Init(&cryptInit);
00431 
00432         /* enable crypto processor */
00433         CRYP_Cmd(ENABLE);
00434 
00435         /* wait until decrypt key has been initialized */
00436         while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00437 
00438         /* set direction and mode */
00439         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00440         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
00441         CRYP_Init(&cryptInit);
00442 
00443         /* enable crypto processor */
00444         CRYP_Cmd(ENABLE);
00445 
00446         /* flush IN/OUT FIFOs */
00447         CRYP_FIFOFlush();
00448 
00449         CRYP_DataIn(*(uint32_t*)&inBlock[0]);
00450         CRYP_DataIn(*(uint32_t*)&inBlock[4]);
00451         CRYP_DataIn(*(uint32_t*)&inBlock[8]);
00452         CRYP_DataIn(*(uint32_t*)&inBlock[12]);
00453 
00454         /* wait until the complete message has been processed */
00455         while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00456 
00457         *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
00458         *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
00459         *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
00460         *(uint32_t*)&outBlock[12] = CRYP_DataOut();
00461 
00462         /* disable crypto processor */
00463         CRYP_Cmd(DISABLE);
00464     #endif /* WOLFSSL_STM32_CUBEMX */
00465 
00466         return ret;
00467     }
00468     #endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */
00469 #endif /* HAVE_AES_DECRYPT */
00470 
00471 #elif defined(HAVE_COLDFIRE_SEC)
00472     /* Freescale Coldfire SEC support for CBC mode.
00473      * NOTE: no support for AES-CTR/GCM/CCM/Direct */
00474     #include <wolfssl/wolfcrypt/types.h >
00475     #include "sec.h"
00476     #include "mcf5475_sec.h"
00477     #include "mcf5475_siu.h"
00478 #elif defined(FREESCALE_LTC)
00479     #include "fsl_ltc.h"
00480     #if defined(FREESCALE_LTC_AES_GCM)
00481         #undef NEED_AES_TABLES
00482         #undef GCM_TABLE
00483     #else
00484         /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
00485         static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00486         {
00487             wc_AesEncryptDirect(aes, outBlock, inBlock);
00488             return 0;
00489         }
00490         static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00491         {
00492             wc_AesDecryptDirect(aes, outBlock, inBlock);
00493             return 0;
00494         }
00495     #endif
00496 #elif defined(FREESCALE_MMCAU)
00497     /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
00498      * through the CAU/mmCAU library. Documentation located in
00499      * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
00500      * Guide (See note in README). */
00501     #ifdef FREESCALE_MMCAU_CLASSIC
00502         /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
00503         #include "cau_api.h"
00504     #else
00505         #include "fsl_mmcau.h"
00506     #endif
00507 
00508     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00509     {
00510         int ret;
00511 
00512     #ifdef FREESCALE_MMCAU_CLASSIC
00513         if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
00514             WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
00515             return BAD_ALIGN_E;
00516         }
00517     #endif
00518 
00519         ret = wolfSSL_CryptHwMutexLock();
00520         if(ret == 0) {
00521         #ifdef FREESCALE_MMCAU_CLASSIC
00522             cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00523         #else
00524             MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
00525                                  outBlock);
00526         #endif
00527             wolfSSL_CryptHwMutexUnLock();
00528         }
00529         return ret;
00530     }
00531     #ifdef HAVE_AES_DECRYPT
00532     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00533     {
00534         int ret;
00535 
00536     #ifdef FREESCALE_MMCAU_CLASSIC
00537         if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
00538             WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
00539             return BAD_ALIGN_E;
00540         }
00541     #endif
00542 
00543         ret = wolfSSL_CryptHwMutexLock();
00544         if(ret == 0) {
00545         #ifdef FREESCALE_MMCAU_CLASSIC
00546             cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00547         #else
00548             MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
00549                                  outBlock);
00550         #endif
00551             wolfSSL_CryptHwMutexUnLock();
00552         }
00553         return ret;
00554     }
00555     #endif /* HAVE_AES_DECRYPT */
00556 
00557 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
00558 
00559     #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
00560 
00561     #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
00562     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00563     {
00564         return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
00565             outBlock, inBlock, AES_BLOCK_SIZE,
00566             PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
00567     }
00568     #endif
00569 
00570     #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
00571     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00572     {
00573         return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
00574             outBlock, inBlock, AES_BLOCK_SIZE,
00575             PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
00576     }
00577     #endif
00578 
00579 #elif defined(WOLFSSL_NRF51_AES)
00580     /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
00581     #include "wolfssl/wolfcrypt/port/nrf51.h"
00582 
00583     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00584     {
00585         return nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
00586     }
00587 
00588     #ifdef HAVE_AES_DECRYPT
00589         #error nRF51 AES Hardware does not support decrypt
00590     #endif /* HAVE_AES_DECRYPT */
00591 
00592 #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
00593     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
00594 
00595     #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
00596 
00597     #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
00598     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00599     {
00600         return wc_esp32AesEncrypt(aes, inBlock, outBlock);
00601     }
00602     #endif
00603 
00604     #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
00605     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00606     {
00607        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
00608     }
00609     #endif
00610 
00611 #elif defined(WOLFSSL_AESNI)
00612 
00613     #define NEED_AES_TABLES
00614 
00615     /* Each platform needs to query info type 1 from cpuid to see if aesni is
00616      * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
00617      */
00618 
00619     #ifndef AESNI_ALIGN
00620         #define AESNI_ALIGN 16
00621     #endif
00622 
00623     #ifdef _MSC_VER
00624         #define XASM_LINK(f)
00625     #elif defined(__APPLE__)
00626         #define XASM_LINK(f) asm("_" f)
00627     #else
00628         #define XASM_LINK(f) asm(f)
00629     #endif /* _MSC_VER */
00630 
00631     static int checkAESNI = 0;
00632     static int haveAESNI  = 0;
00633     static word32 intel_flags = 0;
00634 
00635     static int Check_CPU_support_AES(void)
00636     {
00637         intel_flags = cpuid_get_flags();
00638 
00639         return IS_INTEL_AESNI(intel_flags) != 0;
00640     }
00641 
00642 
00643     /* tell C compiler these are asm functions in case any mix up of ABI underscore
00644        prefix between clang/gcc/llvm etc */
00645     #ifdef HAVE_AES_CBC
00646         void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
00647                              unsigned char* ivec, unsigned long length,
00648                              const unsigned char* KS, int nr)
00649                              XASM_LINK("AES_CBC_encrypt");
00650 
00651         #ifdef HAVE_AES_DECRYPT
00652             #if defined(WOLFSSL_AESNI_BY4)
00653                 void AES_CBC_decrypt_by4(const unsigned char* in, unsigned char* out,
00654                                          unsigned char* ivec, unsigned long length,
00655                                          const unsigned char* KS, int nr)
00656                                          XASM_LINK("AES_CBC_decrypt_by4");
00657             #elif defined(WOLFSSL_AESNI_BY6)
00658                 void AES_CBC_decrypt_by6(const unsigned char* in, unsigned char* out,
00659                                          unsigned char* ivec, unsigned long length,
00660                                          const unsigned char* KS, int nr)
00661                                          XASM_LINK("AES_CBC_decrypt_by6");
00662             #else /* WOLFSSL_AESNI_BYx */
00663                 void AES_CBC_decrypt_by8(const unsigned char* in, unsigned char* out,
00664                                          unsigned char* ivec, unsigned long length,
00665                                          const unsigned char* KS, int nr)
00666                                          XASM_LINK("AES_CBC_decrypt_by8");
00667             #endif /* WOLFSSL_AESNI_BYx */
00668         #endif /* HAVE_AES_DECRYPT */
00669     #endif /* HAVE_AES_CBC */
00670 
00671     void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
00672                          unsigned long length, const unsigned char* KS, int nr)
00673                          XASM_LINK("AES_ECB_encrypt");
00674 
00675     #ifdef HAVE_AES_DECRYPT
00676         void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
00677                              unsigned long length, const unsigned char* KS, int nr)
00678                              XASM_LINK("AES_ECB_decrypt");
00679     #endif
00680 
00681     void AES_128_Key_Expansion(const unsigned char* userkey,
00682                                unsigned char* key_schedule)
00683                                XASM_LINK("AES_128_Key_Expansion");
00684 
00685     void AES_192_Key_Expansion(const unsigned char* userkey,
00686                                unsigned char* key_schedule)
00687                                XASM_LINK("AES_192_Key_Expansion");
00688 
00689     void AES_256_Key_Expansion(const unsigned char* userkey,
00690                                unsigned char* key_schedule)
00691                                XASM_LINK("AES_256_Key_Expansion");
00692 
00693 
00694     static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
00695                                    Aes* aes)
00696     {
00697         int ret;
00698 
00699         if (!userKey || !aes)
00700             return BAD_FUNC_ARG;
00701 
00702         switch (bits) {
00703             case 128:
00704                AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
00705                return 0;
00706             case 192:
00707                AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
00708                return 0;
00709             case 256:
00710                AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
00711                return 0;
00712             default:
00713                 ret = BAD_FUNC_ARG;
00714         }
00715 
00716         return ret;
00717     }
00718 
00719     #ifdef HAVE_AES_DECRYPT
00720         static int AES_set_decrypt_key(const unsigned char* userKey,
00721                                                     const int bits, Aes* aes)
00722         {
00723             int nr;
00724             Aes temp_key;
00725             __m128i *Key_Schedule = (__m128i*)aes->key;
00726             __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
00727 
00728             if (!userKey || !aes)
00729                 return BAD_FUNC_ARG;
00730 
00731             if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
00732                 return BAD_FUNC_ARG;
00733 
00734             nr = temp_key.rounds;
00735             aes->rounds = nr;
00736 
00737             Key_Schedule[nr] = Temp_Key_Schedule[0];
00738             Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
00739             Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
00740             Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
00741             Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
00742             Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
00743             Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
00744             Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
00745             Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
00746             Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
00747 
00748             if (nr>10) {
00749                 Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
00750                 Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
00751             }
00752 
00753             if (nr>12) {
00754                 Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
00755                 Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
00756             }
00757 
00758             Key_Schedule[0] = Temp_Key_Schedule[nr];
00759 
00760             return 0;
00761         }
00762     #endif /* HAVE_AES_DECRYPT */
00763 
00764 #elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)) || \
00765       ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
00766         defined(HAVE_AESCCM))
00767         static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00768         {
00769             wc_AesEncryptDirect(aes, outBlock, inBlock);
00770             return 0;
00771         }
00772 
00773 #elif defined(WOLFSSL_AFALG)
00774 #elif defined(WOLFSSL_DEVCRYPTO_AES)
00775 
00776 #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
00777     #include "hal_data.h"
00778 
00779     #ifndef WOLFSSL_SCE_AES256_HANDLE
00780         #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
00781     #endif
00782 
00783     #ifndef WOLFSSL_SCE_AES192_HANDLE
00784         #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
00785     #endif
00786 
00787     #ifndef WOLFSSL_SCE_AES128_HANDLE
00788         #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
00789     #endif
00790 
00791     static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock,
00792             int sz)
00793     {
00794         uint32_t ret;
00795 
00796         if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
00797                 CRYPTO_WORD_ENDIAN_BIG) {
00798             ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
00799         }
00800 
00801         switch (aes->keylen) {
00802         #ifdef WOLFSSL_AES_128
00803             case AES_128_KEY_SIZE:
00804                 ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
00805                         WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
00806                         NULL, (sz / sizeof(word32)), (word32*)inBlock,
00807                         (word32*)outBlock);
00808                 break;
00809         #endif
00810         #ifdef WOLFSSL_AES_192
00811             case AES_192_KEY_SIZE:
00812                 ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
00813                         WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
00814                         NULL, (sz / sizeof(word32)), (word32*)inBlock,
00815                         (word32*)outBlock);
00816                 break;
00817         #endif
00818         #ifdef WOLFSSL_AES_256
00819             case AES_256_KEY_SIZE:
00820                 ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
00821                         WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
00822                         NULL, (sz / sizeof(word32)), (word32*)inBlock,
00823                         (word32*)outBlock);
00824                 break;
00825         #endif
00826             default:
00827                 WOLFSSL_MSG("Unknown key size");
00828                 return BAD_FUNC_ARG;
00829         }
00830 
00831         if (ret != SSP_SUCCESS) {
00832            /* revert input */
00833             ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
00834             return WC_HW_E;
00835         }
00836 
00837         if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
00838                 CRYPTO_WORD_ENDIAN_BIG) {
00839             ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
00840             if (inBlock != outBlock) {
00841                 /* revert input */
00842                 ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
00843             }
00844         }
00845         return 0;
00846     }
00847 
00848     #if defined(HAVE_AES_DECRYPT)
00849     static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock,
00850             int sz)
00851     {
00852         uint32_t ret;
00853 
00854         if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
00855                 CRYPTO_WORD_ENDIAN_BIG) {
00856             ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
00857         }
00858 
00859         switch (aes->keylen) {
00860         #ifdef WOLFSSL_AES_128
00861             case AES_128_KEY_SIZE:
00862                 ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
00863                         WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
00864                         (sz / sizeof(word32)), (word32*)inBlock,
00865                         (word32*)outBlock);
00866                 break;
00867         #endif
00868         #ifdef WOLFSSL_AES_192
00869             case AES_192_KEY_SIZE:
00870                 ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
00871                         WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
00872                         (sz / sizeof(word32)), (word32*)inBlock,
00873                         (word32*)outBlock);
00874                 break;
00875         #endif
00876         #ifdef WOLFSSL_AES_256
00877             case AES_256_KEY_SIZE:
00878                 ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
00879                         WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
00880                         (sz / sizeof(word32)), (word32*)inBlock,
00881                         (word32*)outBlock);
00882                 break;
00883         #endif
00884             default:
00885                 WOLFSSL_MSG("Unknown key size");
00886                 return BAD_FUNC_ARG;
00887         }
00888         if (ret != SSP_SUCCESS) {
00889             return WC_HW_E;
00890         }
00891 
00892         if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
00893                 CRYPTO_WORD_ENDIAN_BIG) {
00894             ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
00895             if (inBlock != outBlock) {
00896                 /* revert input */
00897                 ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
00898             }
00899         }
00900 
00901         return 0;
00902     }
00903 
00904     #endif
00905 
00906     #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
00907     static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00908     {
00909         return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
00910     }
00911     #endif
00912 
00913     #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
00914     static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
00915     {
00916         return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
00917     }
00918     #endif
00919 #else
00920 
00921     /* using wolfCrypt software implementation */
00922     #define NEED_AES_TABLES
00923 #endif
00924 
00925 
00926 
00927 #ifdef NEED_AES_TABLES
00928 
00929 static const word32 rcon[] = {
00930     0x01000000, 0x02000000, 0x04000000, 0x08000000,
00931     0x10000000, 0x20000000, 0x40000000, 0x80000000,
00932     0x1B000000, 0x36000000,
00933     /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
00934 };
00935 
00936 #ifndef WOLFSSL_AES_SMALL_TABLES
00937 static const word32 Te[4][256] = {
00938 {
00939     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
00940     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
00941     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
00942     0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
00943     0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
00944     0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
00945     0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
00946     0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
00947     0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
00948     0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
00949     0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
00950     0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
00951     0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
00952     0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
00953     0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
00954     0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
00955     0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
00956     0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
00957     0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
00958     0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
00959     0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
00960     0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
00961     0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
00962     0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
00963     0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
00964     0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
00965     0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
00966     0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
00967     0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
00968     0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
00969     0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
00970     0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
00971     0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
00972     0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
00973     0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
00974     0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
00975     0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
00976     0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
00977     0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
00978     0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
00979     0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
00980     0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
00981     0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
00982     0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
00983     0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
00984     0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
00985     0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
00986     0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
00987     0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
00988     0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
00989     0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
00990     0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
00991     0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
00992     0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
00993     0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
00994     0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
00995     0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
00996     0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
00997     0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
00998     0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
00999     0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
01000     0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
01001     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
01002     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
01003 },
01004 {
01005     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
01006     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
01007     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
01008     0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
01009     0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
01010     0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
01011     0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
01012     0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
01013     0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
01014     0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
01015     0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
01016     0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
01017     0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
01018     0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
01019     0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
01020     0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
01021     0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
01022     0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
01023     0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
01024     0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
01025     0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
01026     0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
01027     0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
01028     0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
01029     0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
01030     0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
01031     0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
01032     0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
01033     0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
01034     0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
01035     0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
01036     0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
01037     0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
01038     0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
01039     0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
01040     0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
01041     0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
01042     0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
01043     0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
01044     0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
01045     0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
01046     0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
01047     0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
01048     0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
01049     0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
01050     0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
01051     0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
01052     0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
01053     0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
01054     0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
01055     0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
01056     0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
01057     0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
01058     0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
01059     0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
01060     0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
01061     0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
01062     0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
01063     0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
01064     0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
01065     0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
01066     0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
01067     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
01068     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
01069 },
01070 {
01071     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
01072     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
01073     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
01074     0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
01075     0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
01076     0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
01077     0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
01078     0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
01079     0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
01080     0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
01081     0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
01082     0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
01083     0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
01084     0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
01085     0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
01086     0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
01087     0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
01088     0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
01089     0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
01090     0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
01091     0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
01092     0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
01093     0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
01094     0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
01095     0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
01096     0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
01097     0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
01098     0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
01099     0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
01100     0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
01101     0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
01102     0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
01103     0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
01104     0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
01105     0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
01106     0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
01107     0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
01108     0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
01109     0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
01110     0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
01111     0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
01112     0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
01113     0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
01114     0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
01115     0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
01116     0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
01117     0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
01118     0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
01119     0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
01120     0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
01121     0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
01122     0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
01123     0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
01124     0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
01125     0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
01126     0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
01127     0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
01128     0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
01129     0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
01130     0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
01131     0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
01132     0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
01133     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
01134     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
01135 },
01136 {
01137     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
01138     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
01139     0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
01140     0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
01141     0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
01142     0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
01143     0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
01144     0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
01145     0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
01146     0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
01147     0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
01148     0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
01149     0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
01150     0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
01151     0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
01152     0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
01153     0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
01154     0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
01155     0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
01156     0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
01157     0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
01158     0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
01159     0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
01160     0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
01161     0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
01162     0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
01163     0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
01164     0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
01165     0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
01166     0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
01167     0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
01168     0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
01169     0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
01170     0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
01171     0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
01172     0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
01173     0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
01174     0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
01175     0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
01176     0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
01177     0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
01178     0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
01179     0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
01180     0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
01181     0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
01182     0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
01183     0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
01184     0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
01185     0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
01186     0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
01187     0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
01188     0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
01189     0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
01190     0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
01191     0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
01192     0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
01193     0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
01194     0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
01195     0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
01196     0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
01197     0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
01198     0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
01199     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
01200     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
01201 }
01202 };
01203 
01204 #ifdef HAVE_AES_DECRYPT
01205 static const word32 Td[4][256] = {
01206 {
01207     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
01208     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
01209     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
01210     0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
01211     0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
01212     0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
01213     0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
01214     0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
01215     0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
01216     0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
01217     0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
01218     0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
01219     0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
01220     0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
01221     0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
01222     0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
01223     0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
01224     0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
01225     0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
01226     0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
01227     0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
01228     0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
01229     0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
01230     0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
01231     0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
01232     0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
01233     0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
01234     0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
01235     0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
01236     0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
01237     0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
01238     0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
01239     0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
01240     0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
01241     0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
01242     0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
01243     0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
01244     0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
01245     0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
01246     0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
01247     0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
01248     0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
01249     0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
01250     0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
01251     0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
01252     0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
01253     0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
01254     0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
01255     0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
01256     0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
01257     0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
01258     0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
01259     0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
01260     0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
01261     0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
01262     0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
01263     0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
01264     0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
01265     0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
01266     0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
01267     0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
01268     0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
01269     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
01270     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
01271 },
01272 {
01273     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
01274     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
01275     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
01276     0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
01277     0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
01278     0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
01279     0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
01280     0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
01281     0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
01282     0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
01283     0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
01284     0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
01285     0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
01286     0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
01287     0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
01288     0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
01289     0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
01290     0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
01291     0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
01292     0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
01293     0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
01294     0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
01295     0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
01296     0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
01297     0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
01298     0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
01299     0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
01300     0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
01301     0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
01302     0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
01303     0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
01304     0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
01305     0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
01306     0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
01307     0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
01308     0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
01309     0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
01310     0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
01311     0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
01312     0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
01313     0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
01314     0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
01315     0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
01316     0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
01317     0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
01318     0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
01319     0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
01320     0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
01321     0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
01322     0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
01323     0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
01324     0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
01325     0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
01326     0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
01327     0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
01328     0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
01329     0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
01330     0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
01331     0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
01332     0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
01333     0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
01334     0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
01335     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
01336     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
01337 },
01338 {
01339     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
01340     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
01341     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
01342     0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
01343     0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
01344     0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
01345     0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
01346     0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
01347     0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
01348     0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
01349     0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
01350     0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
01351     0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
01352     0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
01353     0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
01354     0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
01355     0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
01356     0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
01357     0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
01358     0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
01359 
01360     0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
01361     0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
01362     0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
01363     0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
01364     0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
01365     0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
01366     0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
01367     0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
01368     0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
01369     0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
01370     0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
01371     0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
01372     0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
01373     0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
01374     0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
01375     0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
01376     0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
01377     0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
01378     0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
01379     0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
01380     0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
01381     0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
01382     0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
01383     0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
01384     0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
01385     0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
01386     0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
01387     0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
01388     0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
01389     0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
01390     0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
01391     0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
01392     0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
01393     0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
01394     0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
01395     0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
01396     0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
01397     0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
01398     0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
01399     0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
01400     0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
01401     0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
01402     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
01403     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
01404 },
01405 {
01406     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
01407     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
01408     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
01409     0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
01410     0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
01411     0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
01412     0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
01413     0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
01414     0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
01415     0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
01416     0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
01417     0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
01418     0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
01419     0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
01420     0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
01421     0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
01422     0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
01423     0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
01424     0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
01425     0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
01426     0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
01427     0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
01428     0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
01429     0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
01430     0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
01431     0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
01432     0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
01433     0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
01434     0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
01435     0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
01436     0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
01437     0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
01438     0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
01439     0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
01440     0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
01441     0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
01442     0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
01443     0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
01444     0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
01445     0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
01446     0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
01447     0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
01448     0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
01449     0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
01450     0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
01451     0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
01452     0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
01453     0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
01454     0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
01455     0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
01456     0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
01457     0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
01458     0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
01459     0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
01460     0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
01461     0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
01462     0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
01463     0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
01464     0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
01465     0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
01466     0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
01467     0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
01468     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
01469     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
01470 }
01471 };
01472 #endif /* HAVE_AES_DECRYPT */
01473 #endif
01474 
01475 #ifdef HAVE_AES_DECRYPT
01476 #if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) \
01477             || defined(WOLFSSL_AES_DIRECT)
01478 static const byte Td4[256] =
01479 {
01480     0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
01481     0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
01482     0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
01483     0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
01484     0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
01485     0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
01486     0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
01487     0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
01488     0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
01489     0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
01490     0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
01491     0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
01492     0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
01493     0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
01494     0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
01495     0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
01496     0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
01497     0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
01498     0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
01499     0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
01500     0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
01501     0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
01502     0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
01503     0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
01504     0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
01505     0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
01506     0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
01507     0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
01508     0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
01509     0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
01510     0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
01511     0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
01512 };
01513 #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
01514 #endif /* HAVE_AES_DECRYPT */
01515 
01516 #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
01517 
01518 #ifdef WOLFSSL_AES_SMALL_TABLES
01519 static const byte Tsbox[256] = {
01520     0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
01521     0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
01522     0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
01523     0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
01524     0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
01525     0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
01526     0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
01527     0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
01528     0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
01529     0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
01530     0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
01531     0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
01532     0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
01533     0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
01534     0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
01535     0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
01536     0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
01537     0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
01538     0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
01539     0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
01540     0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
01541     0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
01542     0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
01543     0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
01544     0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
01545     0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
01546     0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
01547     0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
01548     0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
01549     0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
01550     0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
01551     0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
01552 };
01553 
01554 #define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
01555 
01556 static word32 col_mul(word32 t, int i2, int i3, int ia, int ib)
01557 {
01558     byte t3 = GETBYTE(t, i3);
01559     byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
01560 
01561     return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
01562 }
01563 
01564 static word32 inv_col_mul(word32 t, int i9, int ib, int id, int ie)
01565 {
01566     byte t9 = GETBYTE(t, i9);
01567     byte tb = GETBYTE(t, ib);
01568     byte td = GETBYTE(t, id);
01569     byte te = GETBYTE(t, ie);
01570     byte t0 = t9 ^ tb ^ td;
01571     return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
01572 }
01573 #endif
01574 
01575 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM)
01576 
01577 #ifndef WC_CACHE_LINE_SZ
01578     #if defined(__x86_64__) || defined(_M_X64) || \
01579        (defined(__ILP32__) && (__ILP32__ >= 1))
01580         #define WC_CACHE_LINE_SZ 64
01581     #else
01582         /* default cache line size */
01583         #define WC_CACHE_LINE_SZ 32
01584     #endif
01585 #endif
01586 
01587 
01588 #ifndef WOLFSSL_AES_SMALL_TABLES
01589 /* load 4 Te Tables into cache by cache line stride */
01590 static WC_INLINE word32 PreFetchTe(void)
01591 {
01592     word32 x = 0;
01593     int i,j;
01594 
01595     for (i = 0; i < 4; i++) {
01596         /* 256 elements, each one is 4 bytes */
01597         for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
01598             x &= Te[i][j];
01599         }
01600     }
01601     return x;
01602 }
01603 #else
01604 /* load sbox into cache by cache line stride */
01605 static WC_INLINE word32 PreFetchSBox(void)
01606 {
01607     word32 x = 0;
01608     int i;
01609 
01610     for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
01611         x &= Tsbox[i];
01612     }
01613     return x;
01614 }
01615 #endif
01616 
01617 /* Software AES - ECB Encrypt */
01618 static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
01619 {
01620     word32 s0, s1, s2, s3;
01621     word32 t0, t1, t2, t3;
01622     word32 r = aes->rounds >> 1;
01623     const word32* rk = aes->key;
01624 
01625     if (r > 7 || r == 0) {
01626         WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
01627         return;  /* stop instead of seg-faulting, set up your keys! */
01628     }
01629 
01630 #ifdef WOLFSSL_AESNI
01631     if (haveAESNI && aes->use_aesni) {
01632         #ifdef DEBUG_AESNI
01633             printf("about to aes encrypt\n");
01634             printf("in  = %p\n", inBlock);
01635             printf("out = %p\n", outBlock);
01636             printf("aes->key = %p\n", aes->key);
01637             printf("aes->rounds = %d\n", aes->rounds);
01638             printf("sz = %d\n", AES_BLOCK_SIZE);
01639         #endif
01640 
01641         /* check alignment, decrypt doesn't need alignment */
01642         if ((wolfssl_word)inBlock % AESNI_ALIGN) {
01643         #ifndef NO_WOLFSSL_ALLOC_ALIGN
01644             byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
01645                                                       DYNAMIC_TYPE_TMP_BUFFER);
01646             byte* tmp_align;
01647             if (tmp == NULL) return;
01648 
01649             tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));
01650 
01651             XMEMCPY(tmp_align, inBlock, AES_BLOCK_SIZE);
01652             AES_ECB_encrypt(tmp_align, tmp_align, AES_BLOCK_SIZE,
01653                     (byte*)aes->key, aes->rounds);
01654             XMEMCPY(outBlock, tmp_align, AES_BLOCK_SIZE);
01655             XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
01656             return;
01657         #else
01658             WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
01659             return;
01660         #endif
01661         }
01662 
01663         AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
01664                         aes->rounds);
01665 
01666         return;
01667     }
01668     else {
01669         #ifdef DEBUG_AESNI
01670             printf("Skipping AES-NI\n");
01671         #endif
01672     }
01673 #endif
01674 #if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
01675     AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
01676     return;
01677 #endif
01678 
01679     /*
01680      * map byte array block to cipher state
01681      * and add initial round key:
01682      */
01683     XMEMCPY(&s0, inBlock,                  sizeof(s0));
01684     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
01685     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
01686     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
01687 
01688 #ifdef LITTLE_ENDIAN_ORDER
01689     s0 = ByteReverseWord32(s0);
01690     s1 = ByteReverseWord32(s1);
01691     s2 = ByteReverseWord32(s2);
01692     s3 = ByteReverseWord32(s3);
01693 #endif
01694 
01695     /* AddRoundKey */
01696     s0 ^= rk[0];
01697     s1 ^= rk[1];
01698     s2 ^= rk[2];
01699     s3 ^= rk[3];
01700 
01701 #ifndef WOLFSSL_AES_SMALL_TABLES
01702     s0 |= PreFetchTe();
01703 
01704     /*
01705      * Nr - 1 full rounds:
01706      */
01707 
01708     for (;;) {
01709         t0 =
01710             Te[0][GETBYTE(s0, 3)] ^
01711             Te[1][GETBYTE(s1, 2)] ^
01712             Te[2][GETBYTE(s2, 1)] ^
01713             Te[3][GETBYTE(s3, 0)] ^
01714             rk[4];
01715         t1 =
01716             Te[0][GETBYTE(s1, 3)] ^
01717             Te[1][GETBYTE(s2, 2)] ^
01718             Te[2][GETBYTE(s3, 1)] ^
01719             Te[3][GETBYTE(s0, 0)] ^
01720             rk[5];
01721         t2 =
01722             Te[0][GETBYTE(s2, 3)] ^
01723             Te[1][GETBYTE(s3, 2)] ^
01724             Te[2][GETBYTE(s0, 1)] ^
01725             Te[3][GETBYTE(s1, 0)] ^
01726             rk[6];
01727         t3 =
01728             Te[0][GETBYTE(s3, 3)] ^
01729             Te[1][GETBYTE(s0, 2)] ^
01730             Te[2][GETBYTE(s1, 1)] ^
01731             Te[3][GETBYTE(s2, 0)] ^
01732             rk[7];
01733 
01734         rk += 8;
01735         if (--r == 0) {
01736             break;
01737         }
01738 
01739         s0 =
01740             Te[0][GETBYTE(t0, 3)] ^
01741             Te[1][GETBYTE(t1, 2)] ^
01742             Te[2][GETBYTE(t2, 1)] ^
01743             Te[3][GETBYTE(t3, 0)] ^
01744             rk[0];
01745         s1 =
01746             Te[0][GETBYTE(t1, 3)] ^
01747             Te[1][GETBYTE(t2, 2)] ^
01748             Te[2][GETBYTE(t3, 1)] ^
01749             Te[3][GETBYTE(t0, 0)] ^
01750             rk[1];
01751         s2 =
01752             Te[0][GETBYTE(t2, 3)] ^
01753             Te[1][GETBYTE(t3, 2)] ^
01754             Te[2][GETBYTE(t0, 1)] ^
01755             Te[3][GETBYTE(t1, 0)] ^
01756             rk[2];
01757         s3 =
01758             Te[0][GETBYTE(t3, 3)] ^
01759             Te[1][GETBYTE(t0, 2)] ^
01760             Te[2][GETBYTE(t1, 1)] ^
01761             Te[3][GETBYTE(t2, 0)] ^
01762             rk[3];
01763     }
01764 
01765     /*
01766      * apply last round and
01767      * map cipher state to byte array block:
01768      */
01769 
01770     s0 =
01771         (Te[2][GETBYTE(t0, 3)] & 0xff000000) ^
01772         (Te[3][GETBYTE(t1, 2)] & 0x00ff0000) ^
01773         (Te[0][GETBYTE(t2, 1)] & 0x0000ff00) ^
01774         (Te[1][GETBYTE(t3, 0)] & 0x000000ff) ^
01775         rk[0];
01776     s1 =
01777         (Te[2][GETBYTE(t1, 3)] & 0xff000000) ^
01778         (Te[3][GETBYTE(t2, 2)] & 0x00ff0000) ^
01779         (Te[0][GETBYTE(t3, 1)] & 0x0000ff00) ^
01780         (Te[1][GETBYTE(t0, 0)] & 0x000000ff) ^
01781         rk[1];
01782     s2 =
01783         (Te[2][GETBYTE(t2, 3)] & 0xff000000) ^
01784         (Te[3][GETBYTE(t3, 2)] & 0x00ff0000) ^
01785         (Te[0][GETBYTE(t0, 1)] & 0x0000ff00) ^
01786         (Te[1][GETBYTE(t1, 0)] & 0x000000ff) ^
01787         rk[2];
01788     s3 =
01789         (Te[2][GETBYTE(t3, 3)] & 0xff000000) ^
01790         (Te[3][GETBYTE(t0, 2)] & 0x00ff0000) ^
01791         (Te[0][GETBYTE(t1, 1)] & 0x0000ff00) ^
01792         (Te[1][GETBYTE(t2, 0)] & 0x000000ff) ^
01793         rk[3];
01794 #else
01795     s0 |= PreFetchSBox();
01796 
01797     r *= 2;
01798     /* Two rounds at a time */
01799     for (rk += 4; r > 1; r--, rk += 4) {
01800         t0 =
01801             ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^
01802             ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^
01803             ((word32)Tsbox[GETBYTE(s2, 1)] <<  8) ^
01804             ((word32)Tsbox[GETBYTE(s3, 0)]);
01805         t1 =
01806             ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^
01807             ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^
01808             ((word32)Tsbox[GETBYTE(s3, 1)] <<  8) ^
01809             ((word32)Tsbox[GETBYTE(s0, 0)]);
01810         t2 =
01811             ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^
01812             ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^
01813             ((word32)Tsbox[GETBYTE(s0, 1)] <<  8) ^
01814             ((word32)Tsbox[GETBYTE(s1, 0)]);
01815         t3 =
01816             ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^
01817             ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^
01818             ((word32)Tsbox[GETBYTE(s1, 1)] <<  8) ^
01819             ((word32)Tsbox[GETBYTE(s2, 0)]);
01820 
01821         s0 =
01822             (col_mul(t0, 3, 2, 0, 1) << 24) ^
01823             (col_mul(t0, 2, 1, 0, 3) << 16) ^
01824             (col_mul(t0, 1, 0, 2, 3) <<  8) ^
01825             (col_mul(t0, 0, 3, 2, 1)      ) ^
01826             rk[0];
01827         s1 =
01828             (col_mul(t1, 3, 2, 0, 1) << 24) ^
01829             (col_mul(t1, 2, 1, 0, 3) << 16) ^
01830             (col_mul(t1, 1, 0, 2, 3) <<  8) ^
01831             (col_mul(t1, 0, 3, 2, 1)      ) ^
01832             rk[1];
01833         s2 =
01834             (col_mul(t2, 3, 2, 0, 1) << 24) ^
01835             (col_mul(t2, 2, 1, 0, 3) << 16) ^
01836             (col_mul(t2, 1, 0, 2, 3) <<  8) ^
01837             (col_mul(t2, 0, 3, 2, 1)      ) ^
01838             rk[2];
01839         s3 =
01840             (col_mul(t3, 3, 2, 0, 1) << 24) ^
01841             (col_mul(t3, 2, 1, 0, 3) << 16) ^
01842             (col_mul(t3, 1, 0, 2, 3) <<  8) ^
01843             (col_mul(t3, 0, 3, 2, 1)      ) ^
01844             rk[3];
01845     }
01846 
01847     t0 =
01848         ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^
01849         ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^
01850         ((word32)Tsbox[GETBYTE(s2, 1)] <<  8) ^
01851         ((word32)Tsbox[GETBYTE(s3, 0)]);
01852     t1 =
01853         ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^
01854         ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^
01855         ((word32)Tsbox[GETBYTE(s3, 1)] <<  8) ^
01856         ((word32)Tsbox[GETBYTE(s0, 0)]);
01857     t2 =
01858         ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^
01859         ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^
01860         ((word32)Tsbox[GETBYTE(s0, 1)] <<  8) ^
01861         ((word32)Tsbox[GETBYTE(s1, 0)]);
01862     t3 =
01863         ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^
01864         ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^
01865         ((word32)Tsbox[GETBYTE(s1, 1)] <<  8) ^
01866         ((word32)Tsbox[GETBYTE(s2, 0)]);
01867     s0 = t0 ^ rk[0];
01868     s1 = t1 ^ rk[1];
01869     s2 = t2 ^ rk[2];
01870     s3 = t3 ^ rk[3];
01871 #endif
01872 
01873     /* write out */
01874 #ifdef LITTLE_ENDIAN_ORDER
01875     s0 = ByteReverseWord32(s0);
01876     s1 = ByteReverseWord32(s1);
01877     s2 = ByteReverseWord32(s2);
01878     s3 = ByteReverseWord32(s3);
01879 #endif
01880 
01881     XMEMCPY(outBlock,                  &s0, sizeof(s0));
01882     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
01883     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
01884     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
01885 
01886 }
01887 #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
01888 
01889 #if defined(HAVE_AES_DECRYPT)
01890 #if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
01891      defined(WOLFSSL_AES_DIRECT)
01892 
01893 #ifndef WOLFSSL_AES_SMALL_TABLES
01894 /* load 4 Td Tables into cache by cache line stride */
01895 static WC_INLINE word32 PreFetchTd(void)
01896 {
01897     word32 x = 0;
01898     int i,j;
01899 
01900     for (i = 0; i < 4; i++) {
01901         /* 256 elements, each one is 4 bytes */
01902         for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
01903             x &= Td[i][j];
01904         }
01905     }
01906     return x;
01907 }
01908 #endif
01909 
01910 /* load Td Table4 into cache by cache line stride */
01911 static WC_INLINE word32 PreFetchTd4(void)
01912 {
01913     word32 x = 0;
01914     int i;
01915 
01916     for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
01917         x &= (word32)Td4[i];
01918     }
01919     return x;
01920 }
01921 
01922 /* Software AES - ECB Decrypt */
01923 static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
01924 {
01925     word32 s0, s1, s2, s3;
01926     word32 t0, t1, t2, t3;
01927     word32 r = aes->rounds >> 1;
01928 
01929     const word32* rk = aes->key;
01930     if (r > 7 || r == 0) {
01931         WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
01932         return;  /* stop instead of seg-faulting, set up your keys! */
01933     }
01934 #ifdef WOLFSSL_AESNI
01935     if (haveAESNI && aes->use_aesni) {
01936         #ifdef DEBUG_AESNI
01937             printf("about to aes decrypt\n");
01938             printf("in  = %p\n", inBlock);
01939             printf("out = %p\n", outBlock);
01940             printf("aes->key = %p\n", aes->key);
01941             printf("aes->rounds = %d\n", aes->rounds);
01942             printf("sz = %d\n", AES_BLOCK_SIZE);
01943         #endif
01944 
01945         /* if input and output same will overwrite input iv */
01946         if ((const byte*)aes->tmp != inBlock)
01947             XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
01948         AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
01949                         aes->rounds);
01950         return;
01951     }
01952     else {
01953         #ifdef DEBUG_AESNI
01954             printf("Skipping AES-NI\n");
01955         #endif
01956     }
01957 #endif /* WOLFSSL_AESNI */
01958 #if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
01959     return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
01960 #endif
01961 
01962     /*
01963      * map byte array block to cipher state
01964      * and add initial round key:
01965      */
01966     XMEMCPY(&s0, inBlock,                  sizeof(s0));
01967     XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
01968     XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
01969     XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
01970 
01971 #ifdef LITTLE_ENDIAN_ORDER
01972     s0 = ByteReverseWord32(s0);
01973     s1 = ByteReverseWord32(s1);
01974     s2 = ByteReverseWord32(s2);
01975     s3 = ByteReverseWord32(s3);
01976 #endif
01977 
01978     s0 ^= rk[0];
01979     s1 ^= rk[1];
01980     s2 ^= rk[2];
01981     s3 ^= rk[3];
01982 
01983 #ifndef WOLFSSL_AES_SMALL_TABLES
01984     s0 |= PreFetchTd();
01985 
01986     /*
01987      * Nr - 1 full rounds:
01988      */
01989 
01990     for (;;) {
01991         t0 =
01992             Td[0][GETBYTE(s0, 3)] ^
01993             Td[1][GETBYTE(s3, 2)] ^
01994             Td[2][GETBYTE(s2, 1)] ^
01995             Td[3][GETBYTE(s1, 0)] ^
01996             rk[4];
01997         t1 =
01998             Td[0][GETBYTE(s1, 3)] ^
01999             Td[1][GETBYTE(s0, 2)] ^
02000             Td[2][GETBYTE(s3, 1)] ^
02001             Td[3][GETBYTE(s2, 0)] ^
02002             rk[5];
02003         t2 =
02004             Td[0][GETBYTE(s2, 3)] ^
02005             Td[1][GETBYTE(s1, 2)] ^
02006             Td[2][GETBYTE(s0, 1)] ^
02007             Td[3][GETBYTE(s3, 0)] ^
02008             rk[6];
02009         t3 =
02010             Td[0][GETBYTE(s3, 3)] ^
02011             Td[1][GETBYTE(s2, 2)] ^
02012             Td[2][GETBYTE(s1, 1)] ^
02013             Td[3][GETBYTE(s0, 0)] ^
02014             rk[7];
02015 
02016         rk += 8;
02017         if (--r == 0) {
02018             break;
02019         }
02020 
02021         s0 =
02022             Td[0][GETBYTE(t0, 3)] ^
02023             Td[1][GETBYTE(t3, 2)] ^
02024             Td[2][GETBYTE(t2, 1)] ^
02025             Td[3][GETBYTE(t1, 0)] ^
02026             rk[0];
02027         s1 =
02028             Td[0][GETBYTE(t1, 3)] ^
02029             Td[1][GETBYTE(t0, 2)] ^
02030             Td[2][GETBYTE(t3, 1)] ^
02031             Td[3][GETBYTE(t2, 0)] ^
02032             rk[1];
02033         s2 =
02034             Td[0][GETBYTE(t2, 3)] ^
02035             Td[1][GETBYTE(t1, 2)] ^
02036             Td[2][GETBYTE(t0, 1)] ^
02037             Td[3][GETBYTE(t3, 0)] ^
02038             rk[2];
02039         s3 =
02040             Td[0][GETBYTE(t3, 3)] ^
02041             Td[1][GETBYTE(t2, 2)] ^
02042             Td[2][GETBYTE(t1, 1)] ^
02043             Td[3][GETBYTE(t0, 0)] ^
02044             rk[3];
02045     }
02046     /*
02047      * apply last round and
02048      * map cipher state to byte array block:
02049      */
02050 
02051     t0 |= PreFetchTd4();
02052 
02053     s0 =
02054         ((word32)Td4[GETBYTE(t0, 3)] << 24) ^
02055         ((word32)Td4[GETBYTE(t3, 2)] << 16) ^
02056         ((word32)Td4[GETBYTE(t2, 1)] <<  8) ^
02057         ((word32)Td4[GETBYTE(t1, 0)]) ^
02058         rk[0];
02059     s1 =
02060         ((word32)Td4[GETBYTE(t1, 3)] << 24) ^
02061         ((word32)Td4[GETBYTE(t0, 2)] << 16) ^
02062         ((word32)Td4[GETBYTE(t3, 1)] <<  8) ^
02063         ((word32)Td4[GETBYTE(t2, 0)]) ^
02064         rk[1];
02065     s2 =
02066         ((word32)Td4[GETBYTE(t2, 3)] << 24) ^
02067         ((word32)Td4[GETBYTE(t1, 2)] << 16) ^
02068         ((word32)Td4[GETBYTE(t0, 1)] <<  8) ^
02069         ((word32)Td4[GETBYTE(t3, 0)]) ^
02070         rk[2];
02071     s3 =
02072         ((word32)Td4[GETBYTE(t3, 3)] << 24) ^
02073         ((word32)Td4[GETBYTE(t2, 2)] << 16) ^
02074         ((word32)Td4[GETBYTE(t1, 1)] <<  8) ^
02075         ((word32)Td4[GETBYTE(t0, 0)]) ^
02076         rk[3];
02077 #else
02078     s0 |= PreFetchTd4();
02079 
02080     r *= 2;
02081     for (rk += 4; r > 1; r--, rk += 4) {
02082         t0 =
02083             ((word32)Td4[GETBYTE(s0, 3)] << 24) ^
02084             ((word32)Td4[GETBYTE(s3, 2)] << 16) ^
02085             ((word32)Td4[GETBYTE(s2, 1)] <<  8) ^
02086             ((word32)Td4[GETBYTE(s1, 0)]) ^
02087             rk[0];
02088         t1 =
02089             ((word32)Td4[GETBYTE(s1, 3)] << 24) ^
02090             ((word32)Td4[GETBYTE(s0, 2)] << 16) ^
02091             ((word32)Td4[GETBYTE(s3, 1)] <<  8) ^
02092             ((word32)Td4[GETBYTE(s2, 0)]) ^
02093             rk[1];
02094         t2 =
02095             ((word32)Td4[GETBYTE(s2, 3)] << 24) ^
02096             ((word32)Td4[GETBYTE(s1, 2)] << 16) ^
02097             ((word32)Td4[GETBYTE(s0, 1)] <<  8) ^
02098             ((word32)Td4[GETBYTE(s3, 0)]) ^
02099             rk[2];
02100         t3 =
02101             ((word32)Td4[GETBYTE(s3, 3)] << 24) ^
02102             ((word32)Td4[GETBYTE(s2, 2)] << 16) ^
02103             ((word32)Td4[GETBYTE(s1, 1)] <<  8) ^
02104             ((word32)Td4[GETBYTE(s0, 0)]) ^
02105             rk[3];
02106 
02107         s0 =
02108             (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
02109             (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
02110             (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
02111             (inv_col_mul(t0, 1, 3, 2, 0)      );
02112         s1 =
02113             (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
02114             (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
02115             (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
02116             (inv_col_mul(t1, 1, 3, 2, 0)      );
02117         s2 =
02118             (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
02119             (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
02120             (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
02121             (inv_col_mul(t2, 1, 3, 2, 0)      );
02122         s3 =
02123             (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
02124             (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
02125             (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
02126             (inv_col_mul(t3, 1, 3, 2, 0)      );
02127     }
02128 
02129     t0 =
02130         ((word32)Td4[GETBYTE(s0, 3)] << 24) ^
02131         ((word32)Td4[GETBYTE(s3, 2)] << 16) ^
02132         ((word32)Td4[GETBYTE(s2, 1)] <<  8) ^
02133         ((word32)Td4[GETBYTE(s1, 0)]);
02134     t1 =
02135         ((word32)Td4[GETBYTE(s1, 3)] << 24) ^
02136         ((word32)Td4[GETBYTE(s0, 2)] << 16) ^
02137         ((word32)Td4[GETBYTE(s3, 1)] <<  8) ^
02138         ((word32)Td4[GETBYTE(s2, 0)]);
02139     t2 =
02140         ((word32)Td4[GETBYTE(s2, 3)] << 24) ^
02141         ((word32)Td4[GETBYTE(s1, 2)] << 16) ^
02142         ((word32)Td4[GETBYTE(s0, 1)] <<  8) ^
02143         ((word32)Td4[GETBYTE(s3, 0)]);
02144     t3 =
02145         ((word32)Td4[GETBYTE(s3, 3)] << 24) ^
02146         ((word32)Td4[GETBYTE(s2, 2)] << 16) ^
02147         ((word32)Td4[GETBYTE(s1, 1)] <<  8) ^
02148         ((word32)Td4[GETBYTE(s0, 0)]);
02149     s0 = t0 ^ rk[0];
02150     s1 = t1 ^ rk[1];
02151     s2 = t2 ^ rk[2];
02152     s3 = t3 ^ rk[3];
02153 #endif
02154 
02155     /* write out */
02156 #ifdef LITTLE_ENDIAN_ORDER
02157     s0 = ByteReverseWord32(s0);
02158     s1 = ByteReverseWord32(s1);
02159     s2 = ByteReverseWord32(s2);
02160     s3 = ByteReverseWord32(s3);
02161 #endif
02162 
02163     XMEMCPY(outBlock,                  &s0, sizeof(s0));
02164     XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
02165     XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
02166     XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
02167 }
02168 #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
02169 #endif /* HAVE_AES_DECRYPT */
02170 
02171 #endif /* NEED_AES_TABLES */
02172 
02173 
02174 
02175 /* wc_AesSetKey */
02176 #if defined(STM32_CRYPTO)
02177 
02178     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02179             const byte* iv, int dir)
02180     {
02181         word32 *rk;
02182 
02183         (void)dir;
02184 
02185         if (aes == NULL || (keylen != 16 &&
02186         #ifdef WOLFSSL_AES_192
02187             keylen != 24 &&
02188         #endif
02189             keylen != 32)) {
02190             return BAD_FUNC_ARG;
02191         }
02192 
02193         rk = aes->key;
02194         aes->keylen = keylen;
02195         aes->rounds = keylen/4 + 6;
02196         XMEMCPY(rk, userKey, keylen);
02197     #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
02198         ByteReverseWords(rk, rk, keylen);
02199     #endif
02200     #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02201         defined(WOLFSSL_AES_OFB)
02202         aes->left = 0;
02203     #endif
02204 
02205         return wc_AesSetIV(aes, iv);
02206     }
02207     #if defined(WOLFSSL_AES_DIRECT)
02208         int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02209                             const byte* iv, int dir)
02210         {
02211             return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02212         }
02213     #endif
02214 
02215 #elif defined(HAVE_COLDFIRE_SEC)
02216     #if defined (HAVE_THREADX)
02217         #include "memory_pools.h"
02218         extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
02219     #endif
02220 
02221     #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
02222     static unsigned char *AESBuffIn = NULL;
02223     static unsigned char *AESBuffOut = NULL;
02224     static byte *secReg;
02225     static byte *secKey;
02226     static volatile SECdescriptorType *secDesc;
02227 
02228     static wolfSSL_Mutex Mutex_AesSEC;
02229 
02230     #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
02231     #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
02232 
02233     extern volatile unsigned char __MBAR[];
02234 
02235     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02236         const byte* iv, int dir)
02237     {
02238         if (AESBuffIn == NULL) {
02239         #if defined (HAVE_THREADX)
02240             int s1, s2, s3, s4, s5;
02241             s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
02242                                   sizeof(SECdescriptorType), TX_NO_WAIT);
02243             s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
02244                                   AES_BUFFER_SIZE, TX_NO_WAIT);
02245             s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
02246                                   AES_BUFFER_SIZE, TX_NO_WAIT);
02247             s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
02248                                   AES_BLOCK_SIZE*2, TX_NO_WAIT);
02249             s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
02250                                   AES_BLOCK_SIZE, TX_NO_WAIT);
02251 
02252             if (s1 || s2 || s3 || s4 || s5)
02253                 return BAD_FUNC_ARG;
02254         #else
02255             #warning "Allocate non-Cache buffers"
02256         #endif
02257 
02258             wc_InitMutex(&Mutex_AesSEC);
02259         }
02260 
02261         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
02262             return BAD_FUNC_ARG;
02263 
02264         if (aes == NULL)
02265             return BAD_FUNC_ARG;
02266 
02267         aes->keylen = keylen;
02268         aes->rounds = keylen/4 + 6;
02269         XMEMCPY(aes->key, userKey, keylen);
02270 
02271         if (iv)
02272             XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
02273 
02274     #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02275         defined(WOLFSSL_AES_OFB)
02276         aes->left = 0;
02277     #endif
02278 
02279         return 0;
02280     }
02281 #elif defined(FREESCALE_LTC)
02282     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
02283                   int dir)
02284     {
02285         if (aes == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32)))
02286             return BAD_FUNC_ARG;
02287 
02288         aes->rounds = keylen/4 + 6;
02289         XMEMCPY(aes->key, userKey, keylen);
02290 
02291     #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02292         defined(WOLFSSL_AES_OFB)
02293         aes->left = 0;
02294     #endif
02295 
02296         return wc_AesSetIV(aes, iv);
02297     }
02298 
02299     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02300                         const byte* iv, int dir)
02301     {
02302         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02303     }
02304 #elif defined(FREESCALE_MMCAU)
02305     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02306         const byte* iv, int dir)
02307     {
02308         int ret;
02309         byte* rk;
02310         byte* tmpKey = (byte*)userKey;
02311         int tmpKeyDynamic = 0;
02312         word32 alignOffset = 0;
02313 
02314         (void)dir;
02315 
02316         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
02317             return BAD_FUNC_ARG;
02318         if (aes == NULL)
02319             return BAD_FUNC_ARG;
02320 
02321         rk = (byte*)aes->key;
02322         if (rk == NULL)
02323             return BAD_FUNC_ARG;
02324 
02325     #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02326         defined(WOLFSSL_AES_OFB)
02327         aes->left = 0;
02328     #endif
02329 
02330         aes->rounds = keylen/4 + 6;
02331 
02332     #ifdef FREESCALE_MMCAU_CLASSIC
02333         if ((wolfssl_word)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
02334         #ifndef NO_WOLFSSL_ALLOC_ALIGN
02335             byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
02336                                        aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
02337             if (tmp == NULL) {
02338                 return MEMORY_E;
02339             }
02340             alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
02341                           ((wolfssl_word)tmp % WOLFSSL_MMCAU_ALIGNMENT);
02342             tmpKey = tmp + alignOffset;
02343             XMEMCPY(tmpKey, userKey, keylen);
02344             tmpKeyDynamic = 1;
02345         #else
02346             WOLFSSL_MSG("Bad cau_aes_set_key alignment");
02347             return BAD_ALIGN_E;
02348         #endif
02349         }
02350     #endif
02351 
02352         ret = wolfSSL_CryptHwMutexLock();
02353         if(ret == 0) {
02354         #ifdef FREESCALE_MMCAU_CLASSIC
02355             cau_aes_set_key(tmpKey, keylen*8, rk);
02356         #else
02357             MMCAU_AES_SetKey(tmpKey, keylen, rk);
02358         #endif
02359             wolfSSL_CryptHwMutexUnLock();
02360 
02361             ret = wc_AesSetIV(aes, iv);
02362         }
02363 
02364         if (tmpKeyDynamic == 1) {
02365             XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
02366         }
02367 
02368         return ret;
02369     }
02370 
02371     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02372                         const byte* iv, int dir)
02373     {
02374         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02375     }
02376 
02377 #elif defined(WOLFSSL_NRF51_AES)
02378     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02379         const byte* iv, int dir)
02380     {
02381         int ret;
02382 
02383         (void)dir;
02384         (void)iv;
02385 
02386         if (aes == NULL || keylen != 16)
02387             return BAD_FUNC_ARG;
02388 
02389         aes->keylen = keylen;
02390         aes->rounds = keylen/4 + 6;
02391         ret = nrf51_aes_set_key(userKey);
02392 
02393     #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02394         defined(WOLFSSL_AES_OFB)
02395         aes->left = 0;
02396     #endif
02397 
02398         return ret;
02399     }
02400 
02401     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02402                         const byte* iv, int dir)
02403     {
02404         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02405     }
02406 #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
02407     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
02408 
02409     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02410         const byte* iv, int dir)
02411     {
02412         (void)dir;
02413         (void)iv;
02414 
02415         if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
02416             return BAD_FUNC_ARG;
02417         }
02418 
02419         aes->keylen = keylen;
02420         aes->rounds = keylen/4 + 6;
02421 
02422         XMEMCPY(aes->key, userKey, keylen);
02423         #if defined(WOLFSSL_AES_COUNTER)
02424             aes->left = 0;
02425         #endif
02426         return wc_AesSetIV(aes, iv);
02427     }
02428 
02429     int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02430                         const byte* iv, int dir)
02431     {
02432         return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02433     }
02434 #elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
02435 
02436     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
02437                     int dir)
02438     {
02439         SaSiError_t ret = SASI_OK;
02440         SaSiAesIv_t iv_aes;
02441 
02442         if (aes == NULL ||
02443            (keylen != AES_128_KEY_SIZE &&
02444             keylen != AES_192_KEY_SIZE &&
02445             keylen != AES_256_KEY_SIZE)) {
02446             return BAD_FUNC_ARG;
02447         }
02448     #if defined(AES_MAX_KEY_SIZE)
02449         if (keylen > (AES_MAX_KEY_SIZE/8)) {
02450             return BAD_FUNC_ARG;
02451         }
02452     #endif
02453         if (dir != AES_ENCRYPTION &&
02454             dir != AES_DECRYPTION) {
02455             return BAD_FUNC_ARG;
02456         }
02457 
02458         if (dir == AES_ENCRYPTION) {
02459             aes->ctx.mode = SASI_AES_ENCRYPT;
02460             SaSi_AesInit(&aes->ctx.user_ctx,
02461                          SASI_AES_ENCRYPT,
02462                          SASI_AES_MODE_CBC,
02463                          SASI_AES_PADDING_NONE);
02464         }
02465         else {
02466             aes->ctx.mode = SASI_AES_DECRYPT;
02467             SaSi_AesInit(&aes->ctx.user_ctx,
02468                          SASI_AES_DECRYPT,
02469                          SASI_AES_MODE_CBC,
02470                          SASI_AES_PADDING_NONE);
02471         }
02472 
02473         aes->keylen = keylen;
02474         aes->rounds = keylen/4 + 6;
02475         XMEMCPY(aes->key, userKey, keylen);
02476 
02477         aes->ctx.key.pKey = (uint8_t*)aes->key;
02478         aes->ctx.key.keySize= keylen;
02479 
02480         ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
02481                              SASI_AES_USER_KEY,
02482                              &aes->ctx.key,
02483                              sizeof(aes->ctx.key));
02484         if (ret != SASI_OK) {
02485             return BAD_FUNC_ARG;
02486         }
02487 
02488         ret = wc_AesSetIV(aes, iv);
02489 
02490         if (iv)
02491             XMEMCPY(iv_aes, iv, AES_BLOCK_SIZE);
02492         else
02493             XMEMSET(iv_aes,  0, AES_BLOCK_SIZE);
02494 
02495 
02496         ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
02497         if (ret != SASI_OK) {
02498             return ret;
02499         }
02500        return ret;
02501     }
02502     #if defined(WOLFSSL_AES_DIRECT)
02503         int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02504                             const byte* iv, int dir)
02505         {
02506             return wc_AesSetKey(aes, userKey, keylen, iv, dir);
02507         }
02508     #endif
02509 
02510 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
02511       /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
02512 
02513 #elif defined(WOLFSSL_AFALG)
02514     /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
02515 
02516 #elif defined(WOLFSSL_DEVCRYPTO_AES)
02517     /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
02518 
02519 #else
02520 
02521     /* Software AES - SetKey */
02522     static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
02523                 const byte* iv, int dir)
02524     {
02525         word32 *rk = aes->key;
02526     #ifdef NEED_AES_TABLES
02527         word32 temp;
02528         unsigned int i = 0;
02529     #endif
02530 
02531         #ifdef WOLFSSL_AESNI
02532             aes->use_aesni = 0;
02533         #endif /* WOLFSSL_AESNI */
02534         #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
02535             defined(WOLFSSL_AES_OFB)
02536             aes->left = 0;
02537         #endif
02538 
02539         aes->keylen = keylen;
02540         aes->rounds = (keylen/4) + 6;
02541 
02542         XMEMCPY(rk, userKey, keylen);
02543     #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
02544         (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
02545           defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES))
02546         ByteReverseWords(rk, rk, keylen);
02547     #endif
02548 
02549 #ifdef NEED_AES_TABLES
02550         switch (keylen) {
02551     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
02552             defined(WOLFSSL_AES_128)
02553         case 16:
02554             while (1)
02555             {
02556                 temp  = rk[3];
02557                 rk[4] = rk[0] ^
02558             #ifndef WOLFSSL_AES_SMALL_TABLES
02559                     (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
02560                     (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
02561                     (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
02562                     (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
02563             #else
02564                     ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
02565                     ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
02566                     ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
02567                     ((word32)Tsbox[GETBYTE(temp, 3)]) ^
02568             #endif
02569                     rcon[i];
02570                 rk[5] = rk[1] ^ rk[4];
02571                 rk[6] = rk[2] ^ rk[5];
02572                 rk[7] = rk[3] ^ rk[6];
02573                 if (++i == 10)
02574                     break;
02575                 rk += 4;
02576             }
02577             break;
02578     #endif /* 128 */
02579 
02580     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
02581             defined(WOLFSSL_AES_192)
02582         case 24:
02583             /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
02584             while (1)
02585             {
02586                 temp = rk[ 5];
02587                 rk[ 6] = rk[ 0] ^
02588             #ifndef WOLFSSL_AES_SMALL_TABLES
02589                     (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
02590                     (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
02591                     (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
02592                     (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
02593             #else
02594                     ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
02595                     ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
02596                     ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
02597                     ((word32)Tsbox[GETBYTE(temp, 3)]) ^
02598             #endif
02599                     rcon[i];
02600                 rk[ 7] = rk[ 1] ^ rk[ 6];
02601                 rk[ 8] = rk[ 2] ^ rk[ 7];
02602                 rk[ 9] = rk[ 3] ^ rk[ 8];
02603                 if (++i == 8)
02604                     break;
02605                 rk[10] = rk[ 4] ^ rk[ 9];
02606                 rk[11] = rk[ 5] ^ rk[10];
02607                 rk += 6;
02608             }
02609             break;
02610     #endif /* 192 */
02611 
02612     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
02613             defined(WOLFSSL_AES_256)
02614         case 32:
02615             while (1)
02616             {
02617                 temp = rk[ 7];
02618                 rk[ 8] = rk[ 0] ^
02619             #ifndef WOLFSSL_AES_SMALL_TABLES
02620                     (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^
02621                     (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^
02622                     (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^
02623                     (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^
02624             #else
02625                     ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^
02626                     ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^
02627                     ((word32)Tsbox[GETBYTE(temp, 0)] <<  8) ^
02628                     ((word32)Tsbox[GETBYTE(temp, 3)]) ^
02629             #endif
02630                     rcon[i];
02631                 rk[ 9] = rk[ 1] ^ rk[ 8];
02632                 rk[10] = rk[ 2] ^ rk[ 9];
02633                 rk[11] = rk[ 3] ^ rk[10];
02634                 if (++i == 7)
02635                     break;
02636                 temp = rk[11];
02637                 rk[12] = rk[ 4] ^
02638             #ifndef WOLFSSL_AES_SMALL_TABLES
02639                     (Te[2][GETBYTE(temp, 3)] & 0xff000000) ^
02640                     (Te[3][GETBYTE(temp, 2)] & 0x00ff0000) ^
02641                     (Te[0][GETBYTE(temp, 1)] & 0x0000ff00) ^
02642                     (Te[1][GETBYTE(temp, 0)] & 0x000000ff);
02643             #else
02644                     ((word32)Tsbox[GETBYTE(temp, 3)] << 24) ^
02645                     ((word32)Tsbox[GETBYTE(temp, 2)] << 16) ^
02646                     ((word32)Tsbox[GETBYTE(temp, 1)] <<  8) ^
02647                     ((word32)Tsbox[GETBYTE(temp, 0)]);
02648             #endif
02649                 rk[13] = rk[ 5] ^ rk[12];
02650                 rk[14] = rk[ 6] ^ rk[13];
02651                 rk[15] = rk[ 7] ^ rk[14];
02652 
02653                 rk += 8;
02654             }
02655             break;
02656     #endif /* 256 */
02657 
02658         default:
02659             return BAD_FUNC_ARG;
02660         } /* switch */
02661 
02662     #if defined(HAVE_AES_DECRYPT)
02663         if (dir == AES_DECRYPTION) {
02664             unsigned int j;
02665             rk = aes->key;
02666 
02667             /* invert the order of the round keys: */
02668             for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
02669                 temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
02670                 temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
02671                 temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
02672                 temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
02673             }
02674         #if !defined(WOLFSSL_AES_SMALL_TABLES)
02675             /* apply the inverse MixColumn transform to all round keys but the
02676                first and the last: */
02677             for (i = 1; i < aes->rounds; i++) {
02678                 rk += 4;
02679                 rk[0] =
02680                     Td[0][Te[1][GETBYTE(rk[0], 3)] & 0xff] ^
02681                     Td[1][Te[1][GETBYTE(rk[0], 2)] & 0xff] ^
02682                     Td[2][Te[1][GETBYTE(rk[0], 1)] & 0xff] ^
02683                     Td[3][Te[1][GETBYTE(rk[0], 0)] & 0xff];
02684                 rk[1] =
02685                     Td[0][Te[1][GETBYTE(rk[1], 3)] & 0xff] ^
02686                     Td[1][Te[1][GETBYTE(rk[1], 2)] & 0xff] ^
02687                     Td[2][Te[1][GETBYTE(rk[1], 1)] & 0xff] ^
02688                     Td[3][Te[1][GETBYTE(rk[1], 0)] & 0xff];
02689                 rk[2] =
02690                     Td[0][Te[1][GETBYTE(rk[2], 3)] & 0xff] ^
02691                     Td[1][Te[1][GETBYTE(rk[2], 2)] & 0xff] ^
02692                     Td[2][Te[1][GETBYTE(rk[2], 1)] & 0xff] ^
02693                     Td[3][Te[1][GETBYTE(rk[2], 0)] & 0xff];
02694                 rk[3] =
02695                     Td[0][Te[1][GETBYTE(rk[3], 3)] & 0xff] ^
02696                     Td[1][Te[1][GETBYTE(rk[3], 2)] & 0xff] ^
02697                     Td[2][Te[1][GETBYTE(rk[3], 1)] & 0xff] ^
02698                     Td[3][Te[1][GETBYTE(rk[3], 0)] & 0xff];
02699             }
02700         #endif
02701         }
02702     #else
02703         (void)dir;
02704     #endif /* HAVE_AES_DECRYPT */
02705         (void)temp;
02706 #endif /* NEED_AES_TABLES */
02707 
02708 #if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
02709         XMEMCPY((byte*)aes->key, userKey, keylen);
02710         if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
02711             ByteReverseWords(aes->key, aes->key, 32);
02712         }
02713 #endif
02714 
02715         return wc_AesSetIV(aes, iv);
02716     }
02717 
02718     int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
02719         const byte* iv, int dir)
02720     {
02721         int ret;
02722     #if defined(AES_MAX_KEY_SIZE)
02723         const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
02724     #endif
02725 
02726     #ifdef WOLFSSL_IMX6_CAAM_BLOB
02727         byte   local[32];
02728         word32 localSz = 32;
02729 
02730         if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
02731                 keylen == (24 + WC_CAAM_BLOB_SZ) ||
02732                 keylen == (32 + WC_CAAM_BLOB_SZ)) {
02733             if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
02734                 return BAD_FUNC_ARG;
02735             }
02736 
02737             /* set local values */
02738             userKey = local;
02739             keylen = localSz;
02740         }
02741     #endif
02742         if (aes == NULL ||
02743                 !((keylen == 16) || (keylen == 24) || (keylen == 32))) {
02744             return BAD_FUNC_ARG;
02745         }
02746 
02747     #if defined(AES_MAX_KEY_SIZE)
02748         /* Check key length */
02749         if (keylen > max_key_len) {
02750             return BAD_FUNC_ARG;
02751         }
02752     #endif
02753         aes->keylen = keylen;
02754         aes->rounds = keylen/4 + 6;
02755 
02756     #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
02757         (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
02758         (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
02759         #ifdef WOLF_CRYPTO_CB
02760         if (aes->devId != INVALID_DEVID)
02761         #endif
02762         {
02763             XMEMCPY(aes->devKey, userKey, keylen);
02764         }
02765     #endif
02766 
02767     #ifdef WOLFSSL_AESNI
02768         if (checkAESNI == 0) {
02769             haveAESNI  = Check_CPU_support_AES();
02770             checkAESNI = 1;
02771         }
02772         if (haveAESNI) {
02773             #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
02774                 defined(WOLFSSL_AES_OFB)
02775                 aes->left = 0;
02776             #endif /* WOLFSSL_AES_COUNTER */
02777             aes->use_aesni = 1;
02778             if (iv)
02779                 XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
02780             else
02781                 XMEMSET(aes->reg, 0, AES_BLOCK_SIZE);
02782             if (dir == AES_ENCRYPTION)
02783                 return AES_set_encrypt_key(userKey, keylen * 8, aes);
02784         #ifdef HAVE_AES_DECRYPT
02785             else
02786                 return AES_set_decrypt_key(userKey, keylen * 8, aes);
02787         #endif
02788         }
02789     #endif /* WOLFSSL_AESNI */
02790 
02791         ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
02792 
02793     #if defined(WOLFSSL_DEVCRYPTO) && \
02794         (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
02795         aes->ctx.cfd = -1;
02796     #endif
02797     #ifdef WOLFSSL_IMX6_CAAM_BLOB
02798         ForceZero(local, sizeof(local));
02799     #endif
02800         return ret;
02801     }
02802 
02803     #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
02804         /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */
02805         int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
02806                             const byte* iv, int dir)
02807         {
02808             int ret;
02809 
02810         #ifdef WOLFSSL_IMX6_CAAM_BLOB
02811             byte   local[32];
02812             word32 localSz = 32;
02813 
02814             if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
02815              keylen == (24 + WC_CAAM_BLOB_SZ) ||
02816              keylen == (32 + WC_CAAM_BLOB_SZ)) {
02817                 if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz)
02818                         != 0) {
02819                     return BAD_FUNC_ARG;
02820                 }
02821 
02822                 /* set local values */
02823                 userKey = local;
02824                 keylen = localSz;
02825             }
02826         #endif
02827             ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
02828 
02829         #ifdef WOLFSSL_IMX6_CAAM_BLOB
02830             ForceZero(local, sizeof(local));
02831         #endif
02832 
02833             return ret;
02834         }
02835     #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
02836 #endif /* wc_AesSetKey block */
02837 
02838 
02839 /* wc_AesSetIV is shared between software and hardware */
02840 int wc_AesSetIV(Aes* aes, const byte* iv)
02841 {
02842     if (aes == NULL)
02843         return BAD_FUNC_ARG;
02844 
02845     if (iv)
02846         XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
02847     else
02848         XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
02849 
02850     return 0;
02851 }
02852 
02853 /* AES-DIRECT */
02854 #if defined(WOLFSSL_AES_DIRECT)
02855     #if defined(HAVE_COLDFIRE_SEC)
02856         #error "Coldfire SEC doesn't yet support AES direct"
02857 
02858     #elif defined(FREESCALE_LTC)
02859         /* Allow direct access to one block encrypt */
02860         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
02861         {
02862             byte *key;
02863             uint32_t keySize;
02864 
02865             key = (byte*)aes->key;
02866             wc_AesGetKeySize(aes, &keySize);
02867 
02868             LTC_AES_EncryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
02869                 key, keySize);
02870         }
02871 
02872         /* Allow direct access to one block decrypt */
02873         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
02874         {
02875             byte *key;
02876             uint32_t keySize;
02877 
02878             key = (byte*)aes->key;
02879             wc_AesGetKeySize(aes, &keySize);
02880 
02881             LTC_AES_DecryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,
02882                 key, keySize, kLTC_EncryptKey);
02883         }
02884 
02885     #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
02886         /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
02887 
02888     #elif defined(WOLFSSL_AFALG)
02889         /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
02890 
02891     #elif defined(WOLFSSL_DEVCRYPTO_AES)
02892         /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
02893 
02894     #elif defined(STM32_CRYPTO)
02895         /* Allow direct access to one block encrypt */
02896         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
02897         {
02898             if (wolfSSL_CryptHwMutexLock() == 0) {
02899                 wc_AesEncrypt(aes, in, out);
02900                 wolfSSL_CryptHwMutexUnLock();
02901             }
02902         }
02903         #ifdef HAVE_AES_DECRYPT
02904         /* Allow direct access to one block decrypt */
02905         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
02906         {
02907             if (wolfSSL_CryptHwMutexLock() == 0) {
02908                 wc_AesDecrypt(aes, in, out);
02909                 wolfSSL_CryptHwMutexUnLock();
02910             }
02911         }
02912         #endif /* HAVE_AES_DECRYPT */
02913 
02914     #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
02915         !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
02916         
02917         /* Allow direct access to one block encrypt */
02918         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
02919         {
02920             wc_AesEncrypt(aes, in, out);
02921         }
02922         #ifdef HAVE_AES_DECRYPT
02923         /* Allow direct access to one block decrypt */
02924         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
02925         {
02926             wc_AesDecrypt(aes, in, out);
02927         }
02928         #endif /* HAVE_AES_DECRYPT */
02929     #else
02930         /* Allow direct access to one block encrypt */
02931         void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
02932         {
02933             wc_AesEncrypt(aes, in, out);
02934         }
02935         #ifdef HAVE_AES_DECRYPT
02936         /* Allow direct access to one block decrypt */
02937         void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
02938         {
02939             wc_AesDecrypt(aes, in, out);
02940         }
02941         #endif /* HAVE_AES_DECRYPT */
02942     #endif /* AES direct block */
02943 #endif /* WOLFSSL_AES_DIRECT */
02944 
02945 
02946 /* AES-CBC */
02947 #ifdef HAVE_AES_CBC
02948 #if defined(STM32_CRYPTO)
02949 
02950 #ifdef WOLFSSL_STM32_CUBEMX
02951     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
02952     {
02953         int ret = 0;
02954         word32 blocks = (sz / AES_BLOCK_SIZE);
02955         CRYP_HandleTypeDef hcryp;
02956 
02957         ret = wc_Stm32_Aes_Init(aes, &hcryp);
02958         if (ret != 0)
02959             return ret;
02960 
02961         ret = wolfSSL_CryptHwMutexLock();
02962         if (ret != 0) {
02963             return ret;
02964         }
02965 
02966     #ifdef STM32_CRYPTO_AES_ONLY
02967         hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
02968         hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
02969         hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
02970     #elif defined(STM32_HAL_V2)
02971         hcryp.Init.Algorithm  = CRYP_AES_CBC;
02972         ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
02973     #endif
02974         hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
02975         HAL_CRYP_Init(&hcryp);
02976 
02977         while (blocks--) {
02978         #ifdef STM32_CRYPTO_AES_ONLY
02979             ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
02980                 out, STM32_HAL_TIMEOUT);
02981         #elif defined(STM32_HAL_V2)
02982             ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
02983                 (uint32_t*)out, STM32_HAL_TIMEOUT);
02984         #else
02985             ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
02986                 out, STM32_HAL_TIMEOUT);
02987         #endif
02988             if (ret != HAL_OK) {
02989                 ret = WC_TIMEOUT_E;
02990                 break;
02991             }
02992 
02993             /* store iv for next call */
02994             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
02995 
02996             sz  -= AES_BLOCK_SIZE;
02997             in  += AES_BLOCK_SIZE;
02998             out += AES_BLOCK_SIZE;
02999         }
03000 
03001         HAL_CRYP_DeInit(&hcryp);
03002 
03003         wolfSSL_CryptHwMutexUnLock();
03004 
03005         return ret;
03006     }
03007     #ifdef HAVE_AES_DECRYPT
03008     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03009     {
03010         int ret = 0;
03011         word32 blocks = (sz / AES_BLOCK_SIZE);
03012         CRYP_HandleTypeDef hcryp;
03013 
03014         ret = wc_Stm32_Aes_Init(aes, &hcryp);
03015         if (ret != 0)
03016             return ret;
03017 
03018         ret = wolfSSL_CryptHwMutexLock();
03019         if (ret != 0) {
03020             return ret;
03021         }
03022 
03023         /* if input and output same will overwrite input iv */
03024         XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03025 
03026     #ifdef STM32_CRYPTO_AES_ONLY
03027         hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
03028         hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
03029         hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
03030     #elif defined(STM32_HAL_V2)
03031         hcryp.Init.Algorithm  = CRYP_AES_CBC;
03032         ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
03033     #endif
03034 
03035         hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
03036         HAL_CRYP_Init(&hcryp);
03037 
03038         while (blocks--) {
03039         #ifdef STM32_CRYPTO_AES_ONLY
03040             ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
03041                 out, STM32_HAL_TIMEOUT);
03042         #elif defined(STM32_HAL_V2)
03043             ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
03044                 (uint32_t*)out, STM32_HAL_TIMEOUT);
03045         #else
03046             ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
03047                 out, STM32_HAL_TIMEOUT);
03048         #endif
03049             if (ret != HAL_OK) {
03050                 ret = WC_TIMEOUT_E;
03051                 break;
03052             }
03053 
03054             /* store iv for next call */
03055             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
03056 
03057             in  += AES_BLOCK_SIZE;
03058             out += AES_BLOCK_SIZE;
03059         }
03060 
03061         HAL_CRYP_DeInit(&hcryp);
03062         wolfSSL_CryptHwMutexUnLock();
03063 
03064         return ret;
03065     }
03066     #endif /* HAVE_AES_DECRYPT */
03067 
03068 #else /* STD_PERI_LIB */
03069     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03070     {
03071         int ret;
03072         word32 *iv;
03073         word32 blocks = (sz / AES_BLOCK_SIZE);
03074         CRYP_InitTypeDef cryptInit;
03075         CRYP_KeyInitTypeDef keyInit;
03076         CRYP_IVInitTypeDef ivInit;
03077 
03078         ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
03079         if (ret != 0)
03080             return ret;
03081 
03082         ret = wolfSSL_CryptHwMutexLock();
03083         if (ret != 0) {
03084             return ret;
03085         }
03086 
03087         /* reset registers to their default values */
03088         CRYP_DeInit();
03089 
03090         /* set key */
03091         CRYP_KeyInit(&keyInit);
03092 
03093         /* set iv */
03094         iv = aes->reg;
03095         CRYP_IVStructInit(&ivInit);
03096         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
03097         ivInit.CRYP_IV0Left  = iv[0];
03098         ivInit.CRYP_IV0Right = iv[1];
03099         ivInit.CRYP_IV1Left  = iv[2];
03100         ivInit.CRYP_IV1Right = iv[3];
03101         CRYP_IVInit(&ivInit);
03102 
03103         /* set direction and mode */
03104         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
03105         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
03106         CRYP_Init(&cryptInit);
03107 
03108         /* enable crypto processor */
03109         CRYP_Cmd(ENABLE);
03110 
03111         while (blocks--) {
03112             /* flush IN/OUT FIFOs */
03113             CRYP_FIFOFlush();
03114 
03115             CRYP_DataIn(*(uint32_t*)&in[0]);
03116             CRYP_DataIn(*(uint32_t*)&in[4]);
03117             CRYP_DataIn(*(uint32_t*)&in[8]);
03118             CRYP_DataIn(*(uint32_t*)&in[12]);
03119 
03120             /* wait until the complete message has been processed */
03121             while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
03122 
03123             *(uint32_t*)&out[0]  = CRYP_DataOut();
03124             *(uint32_t*)&out[4]  = CRYP_DataOut();
03125             *(uint32_t*)&out[8]  = CRYP_DataOut();
03126             *(uint32_t*)&out[12] = CRYP_DataOut();
03127 
03128             /* store iv for next call */
03129             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03130 
03131             sz  -= AES_BLOCK_SIZE;
03132             in  += AES_BLOCK_SIZE;
03133             out += AES_BLOCK_SIZE;
03134         }
03135 
03136         /* disable crypto processor */
03137         CRYP_Cmd(DISABLE);
03138         wolfSSL_CryptHwMutexUnLock();
03139 
03140         return ret;
03141     }
03142 
03143     #ifdef HAVE_AES_DECRYPT
03144     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03145     {
03146         int ret;
03147         word32 *iv;
03148         word32 blocks = (sz / AES_BLOCK_SIZE);
03149         CRYP_InitTypeDef cryptInit;
03150         CRYP_KeyInitTypeDef keyInit;
03151         CRYP_IVInitTypeDef ivInit;
03152 
03153         ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
03154         if (ret != 0)
03155             return ret;
03156 
03157         ret = wolfSSL_CryptHwMutexLock();
03158         if (ret != 0) {
03159             return ret;
03160         }
03161 
03162         /* if input and output same will overwrite input iv */
03163         XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03164 
03165         /* reset registers to their default values */
03166         CRYP_DeInit();
03167 
03168         /* set direction and key */
03169         CRYP_KeyInit(&keyInit);
03170         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
03171         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
03172         CRYP_Init(&cryptInit);
03173 
03174         /* enable crypto processor */
03175         CRYP_Cmd(ENABLE);
03176 
03177         /* wait until key has been prepared */
03178         while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
03179 
03180         /* set direction and mode */
03181         cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
03182         cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
03183         CRYP_Init(&cryptInit);
03184 
03185         /* set iv */
03186         iv = aes->reg;
03187         CRYP_IVStructInit(&ivInit);
03188         ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
03189         ivInit.CRYP_IV0Left  = iv[0];
03190         ivInit.CRYP_IV0Right = iv[1];
03191         ivInit.CRYP_IV1Left  = iv[2];
03192         ivInit.CRYP_IV1Right = iv[3];
03193         CRYP_IVInit(&ivInit);
03194 
03195         /* enable crypto processor */
03196         CRYP_Cmd(ENABLE);
03197 
03198         while (blocks--) {
03199             /* flush IN/OUT FIFOs */
03200             CRYP_FIFOFlush();
03201 
03202             CRYP_DataIn(*(uint32_t*)&in[0]);
03203             CRYP_DataIn(*(uint32_t*)&in[4]);
03204             CRYP_DataIn(*(uint32_t*)&in[8]);
03205             CRYP_DataIn(*(uint32_t*)&in[12]);
03206 
03207             /* wait until the complete message has been processed */
03208             while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
03209 
03210             *(uint32_t*)&out[0]  = CRYP_DataOut();
03211             *(uint32_t*)&out[4]  = CRYP_DataOut();
03212             *(uint32_t*)&out[8]  = CRYP_DataOut();
03213             *(uint32_t*)&out[12] = CRYP_DataOut();
03214 
03215             /* store iv for next call */
03216             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
03217 
03218             in  += AES_BLOCK_SIZE;
03219             out += AES_BLOCK_SIZE;
03220         }
03221 
03222         /* disable crypto processor */
03223         CRYP_Cmd(DISABLE);
03224         wolfSSL_CryptHwMutexUnLock();
03225 
03226         return ret;
03227     }
03228     #endif /* HAVE_AES_DECRYPT */
03229 #endif /* WOLFSSL_STM32_CUBEMX */
03230 
03231 #elif defined(HAVE_COLDFIRE_SEC)
03232     static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,
03233         word32 descHeader)
03234     {
03235         #ifdef DEBUG_WOLFSSL
03236             int i; int stat1, stat2; int ret;
03237         #endif
03238 
03239         int size;
03240         volatile int v;
03241 
03242         if ((pi == NULL) || (po == NULL))
03243             return BAD_FUNC_ARG;    /*wrong pointer*/
03244 
03245         wc_LockMutex(&Mutex_AesSEC);
03246 
03247         /* Set descriptor for SEC */
03248         secDesc->length1 = 0x0;
03249         secDesc->pointer1 = NULL;
03250 
03251         secDesc->length2 = AES_BLOCK_SIZE;
03252         secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
03253 
03254         switch(aes->rounds) {
03255             case 10: secDesc->length3 = 16; break;
03256             case 12: secDesc->length3 = 24; break;
03257             case 14: secDesc->length3 = 32; break;
03258         }
03259         XMEMCPY(secKey, aes->key, secDesc->length3);
03260 
03261         secDesc->pointer3 = (byte *)secKey;
03262         secDesc->pointer4 = AESBuffIn;
03263         secDesc->pointer5 = AESBuffOut;
03264         secDesc->length6 = 0x0;
03265         secDesc->pointer6 = NULL;
03266         secDesc->length7 = 0x0;
03267         secDesc->pointer7 = NULL;
03268         secDesc->nextDescriptorPtr = NULL;
03269 
03270         while (sz) {
03271             secDesc->header = descHeader;
03272             XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
03273             if ((sz % AES_BUFFER_SIZE) == sz) {
03274                 size = sz;
03275                 sz = 0;
03276             } else {
03277                 size = AES_BUFFER_SIZE;
03278                 sz -= AES_BUFFER_SIZE;
03279             }
03280             secDesc->length4 = size;
03281             secDesc->length5 = size;
03282 
03283             XMEMCPY(AESBuffIn, pi, size);
03284             if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
03285                 XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
03286                         AES_BLOCK_SIZE);
03287             }
03288 
03289             /* Point SEC to the location of the descriptor */
03290             MCF_SEC_FR0 = (uint32)secDesc;
03291             /* Initialize SEC and wait for encryption to complete */
03292             MCF_SEC_CCCR0 = 0x0000001a;
03293             /* poll SISR to determine when channel is complete */
03294             v=0;
03295 
03296             while ((secDesc->header>> 24) != 0xff) v++;
03297 
03298             #ifdef DEBUG_WOLFSSL
03299                 ret = MCF_SEC_SISRH;
03300                 stat1 = MCF_SEC_AESSR;
03301                 stat2 = MCF_SEC_AESISR;
03302                 if (ret & 0xe0000000) {
03303                     db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
03304                               "AESISR=%08x\n", i, ret, stat1, stat2);
03305                 }
03306             #endif
03307 
03308             XMEMCPY(po, AESBuffOut, size);
03309 
03310             if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
03311                 XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
03312                         AES_BLOCK_SIZE);
03313             } else {
03314                 XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
03315             }
03316 
03317             pi += size;
03318             po += size;
03319         }
03320 
03321         wc_UnLockMutex(&Mutex_AesSEC);
03322         return 0;
03323     }
03324 
03325     int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
03326     {
03327         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
03328     }
03329 
03330     #ifdef HAVE_AES_DECRYPT
03331     int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
03332     {
03333         return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
03334     }
03335     #endif /* HAVE_AES_DECRYPT */
03336 
03337 #elif defined(FREESCALE_LTC)
03338     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03339     {
03340         uint32_t keySize;
03341         status_t status;
03342         byte *iv, *enc_key;
03343         word32 blocks = (sz / AES_BLOCK_SIZE);
03344 
03345         iv      = (byte*)aes->reg;
03346         enc_key = (byte*)aes->key;
03347 
03348         status = wc_AesGetKeySize(aes, &keySize);
03349         if (status != 0) {
03350             return status;
03351         }
03352 
03353         status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
03354             iv, enc_key, keySize);
03355 
03356         /* store iv for next call */
03357         if (status == kStatus_Success) {
03358             XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03359         }
03360 
03361         return (status == kStatus_Success) ? 0 : -1;
03362     }
03363 
03364     #ifdef HAVE_AES_DECRYPT
03365     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03366     {
03367         uint32_t keySize;
03368         status_t status;
03369         byte* iv, *dec_key;
03370         word32 blocks = (sz / AES_BLOCK_SIZE);
03371         byte temp_block[AES_BLOCK_SIZE];
03372 
03373         iv      = (byte*)aes->reg;
03374         dec_key = (byte*)aes->key;
03375 
03376         status = wc_AesGetKeySize(aes, &keySize);
03377         if (status != 0) {
03378             return status;
03379         }
03380 
03381         /* get IV for next call */
03382         XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03383 
03384         status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
03385             iv, dec_key, keySize, kLTC_EncryptKey);
03386 
03387         /* store IV for next call */
03388         if (status == kStatus_Success) {
03389             XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
03390         }
03391 
03392         return (status == kStatus_Success) ? 0 : -1;
03393     }
03394     #endif /* HAVE_AES_DECRYPT */
03395 
03396 #elif defined(FREESCALE_MMCAU)
03397     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03398     {
03399         int i;
03400         int offset = 0;
03401         word32 blocks = (sz / AES_BLOCK_SIZE);
03402         byte *iv;
03403         byte temp_block[AES_BLOCK_SIZE];
03404 
03405         iv      = (byte*)aes->reg;
03406 
03407         while (blocks--) {
03408             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
03409 
03410             /* XOR block with IV for CBC */
03411             for (i = 0; i < AES_BLOCK_SIZE; i++)
03412                 temp_block[i] ^= iv[i];
03413 
03414             wc_AesEncrypt(aes, temp_block, out + offset);
03415 
03416             offset += AES_BLOCK_SIZE;
03417 
03418             /* store IV for next block */
03419             XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03420         }
03421 
03422         return 0;
03423     }
03424     #ifdef HAVE_AES_DECRYPT
03425     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03426     {
03427         int i;
03428         int offset = 0;
03429         word32 blocks = (sz / AES_BLOCK_SIZE);
03430         byte* iv;
03431         byte temp_block[AES_BLOCK_SIZE];
03432 
03433         iv      = (byte*)aes->reg;
03434 
03435         while (blocks--) {
03436             XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
03437 
03438             wc_AesDecrypt(aes, in + offset, out + offset);
03439 
03440             /* XOR block with IV for CBC */
03441             for (i = 0; i < AES_BLOCK_SIZE; i++)
03442                 (out + offset)[i] ^= iv[i];
03443 
03444             /* store IV for next block */
03445             XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
03446 
03447             offset += AES_BLOCK_SIZE;
03448         }
03449 
03450         return 0;
03451     }
03452     #endif /* HAVE_AES_DECRYPT */
03453 
03454 #elif defined(WOLFSSL_PIC32MZ_CRYPT)
03455 
03456     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03457     {
03458         int ret;
03459 
03460         /* hardware fails on input that is not a multiple of AES block size */
03461         if (sz % AES_BLOCK_SIZE != 0) {
03462             return BAD_FUNC_ARG;
03463         }
03464 
03465         ret = wc_Pic32AesCrypt(
03466             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
03467             out, in, sz, PIC32_ENCRYPTION,
03468             PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
03469 
03470         /* store iv for next call */
03471         if (ret == 0) {
03472             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03473         }
03474 
03475         return ret;
03476     }
03477     #ifdef HAVE_AES_DECRYPT
03478     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03479     {
03480         int ret;
03481         byte scratch[AES_BLOCK_SIZE];
03482 
03483         /* hardware fails on input that is not a multiple of AES block size */
03484         if (sz % AES_BLOCK_SIZE != 0) {
03485             return BAD_FUNC_ARG;
03486         }
03487         XMEMCPY(scratch, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03488 
03489         ret = wc_Pic32AesCrypt(
03490             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
03491             out, in, sz, PIC32_DECRYPTION,
03492             PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
03493 
03494         /* store iv for next call */
03495         if (ret == 0) {
03496             XMEMCPY((byte*)aes->reg, scratch, AES_BLOCK_SIZE);
03497         }
03498 
03499         return ret;
03500     }
03501     #endif /* HAVE_AES_DECRYPT */
03502 #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
03503     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
03504 
03505     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03506     {
03507         return wc_esp32AesCbcEncrypt(aes, out, in, sz);
03508     }
03509     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03510     {
03511         return wc_esp32AesCbcDecrypt(aes, out, in, sz);
03512     }
03513 #elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
03514     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03515     {
03516         return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);
03517     }
03518     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03519     {
03520         return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);
03521     }
03522 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
03523       /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
03524 
03525 #elif defined(WOLFSSL_AFALG)
03526     /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
03527 
03528 #elif defined(WOLFSSL_DEVCRYPTO_CBC)
03529     /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
03530 
03531 #else
03532 
03533     /* Software AES - CBC Encrypt */
03534     int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03535     {
03536         word32 blocks = (sz / AES_BLOCK_SIZE);
03537 
03538         if (aes == NULL || out == NULL || in == NULL) {
03539             return BAD_FUNC_ARG;
03540         }
03541 
03542     #ifdef WOLF_CRYPTO_CB
03543         if (aes->devId != INVALID_DEVID) {
03544             int ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
03545             if (ret != CRYPTOCB_UNAVAILABLE)
03546                 return ret;
03547             /* fall-through when unavailable */
03548         }
03549     #endif
03550     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
03551         /* if async and byte count above threshold */
03552         if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
03553                                                 sz >= WC_ASYNC_THRESH_AES_CBC) {
03554         #if defined(HAVE_CAVIUM)
03555             return NitroxAesCbcEncrypt(aes, out, in, sz);
03556         #elif defined(HAVE_INTEL_QA)
03557             return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
03558                 (const byte*)aes->devKey, aes->keylen,
03559                 (byte*)aes->reg, AES_BLOCK_SIZE);
03560         #else /* WOLFSSL_ASYNC_CRYPT_TEST */
03561             if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_ENCRYPT)) {
03562                 WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
03563                 testDev->aes.aes = aes;
03564                 testDev->aes.out = out;
03565                 testDev->aes.in = in;
03566                 testDev->aes.sz = sz;
03567                 return WC_PENDING_E;
03568             }
03569         #endif
03570         }
03571     #endif /* WOLFSSL_ASYNC_CRYPT */
03572 
03573     #ifdef WOLFSSL_AESNI
03574         if (haveAESNI) {
03575             #ifdef DEBUG_AESNI
03576                 printf("about to aes cbc encrypt\n");
03577                 printf("in  = %p\n", in);
03578                 printf("out = %p\n", out);
03579                 printf("aes->key = %p\n", aes->key);
03580                 printf("aes->reg = %p\n", aes->reg);
03581                 printf("aes->rounds = %d\n", aes->rounds);
03582                 printf("sz = %d\n", sz);
03583             #endif
03584 
03585             /* check alignment, decrypt doesn't need alignment */
03586             if ((wolfssl_word)in % AESNI_ALIGN) {
03587             #ifndef NO_WOLFSSL_ALLOC_ALIGN
03588                 byte* tmp = (byte*)XMALLOC(sz + AES_BLOCK_SIZE + AESNI_ALIGN,
03589                                             aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
03590                 byte* tmp_align;
03591                 if (tmp == NULL) return MEMORY_E;
03592 
03593                 tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));
03594                 XMEMCPY(tmp_align, in, sz);
03595                 AES_CBC_encrypt(tmp_align, tmp_align, (byte*)aes->reg, sz,
03596                                                   (byte*)aes->key, aes->rounds);
03597                 /* store iv for next call */
03598                 XMEMCPY(aes->reg, tmp_align + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03599 
03600                 XMEMCPY(out, tmp_align, sz);
03601                 XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
03602                 return 0;
03603             #else
03604                 WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
03605                 return BAD_ALIGN_E;
03606             #endif
03607             }
03608 
03609             AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
03610                             aes->rounds);
03611             /* store iv for next call */
03612             XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03613 
03614             return 0;
03615         }
03616     #endif
03617 
03618         while (blocks--) {
03619             xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
03620             wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
03621             XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
03622 
03623             out += AES_BLOCK_SIZE;
03624             in  += AES_BLOCK_SIZE;
03625         }
03626 
03627         return 0;
03628     }
03629 
03630     #ifdef HAVE_AES_DECRYPT
03631     /* Software AES - CBC Decrypt */
03632     int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03633     {
03634         word32 blocks;
03635 
03636         if (aes == NULL || out == NULL || in == NULL
03637                                        || sz % AES_BLOCK_SIZE != 0) {
03638             return BAD_FUNC_ARG;
03639         }
03640 
03641     #ifdef WOLF_CRYPTO_CB
03642         if (aes->devId != INVALID_DEVID) {
03643             int ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
03644             if (ret != CRYPTOCB_UNAVAILABLE)
03645                 return ret;
03646             /* fall-through when unavailable */
03647         }
03648     #endif
03649     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
03650         /* if async and byte count above threshold */
03651         if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
03652                                                 sz >= WC_ASYNC_THRESH_AES_CBC) {
03653         #if defined(HAVE_CAVIUM)
03654             return NitroxAesCbcDecrypt(aes, out, in, sz);
03655         #elif defined(HAVE_INTEL_QA)
03656             return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
03657                 (const byte*)aes->devKey, aes->keylen,
03658                 (byte*)aes->reg, AES_BLOCK_SIZE);
03659         #else /* WOLFSSL_ASYNC_CRYPT_TEST */
03660             if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_DECRYPT)) {
03661                 WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
03662                 testDev->aes.aes = aes;
03663                 testDev->aes.out = out;
03664                 testDev->aes.in = in;
03665                 testDev->aes.sz = sz;
03666                 return WC_PENDING_E;
03667             }
03668         #endif
03669         }
03670     #endif
03671 
03672     #ifdef WOLFSSL_AESNI
03673         if (haveAESNI) {
03674             #ifdef DEBUG_AESNI
03675                 printf("about to aes cbc decrypt\n");
03676                 printf("in  = %p\n", in);
03677                 printf("out = %p\n", out);
03678                 printf("aes->key = %p\n", aes->key);
03679                 printf("aes->reg = %p\n", aes->reg);
03680                 printf("aes->rounds = %d\n", aes->rounds);
03681                 printf("sz = %d\n", sz);
03682             #endif
03683 
03684             /* if input and output same will overwrite input iv */
03685             XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
03686             #if defined(WOLFSSL_AESNI_BY4)
03687             AES_CBC_decrypt_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
03688                             aes->rounds);
03689             #elif defined(WOLFSSL_AESNI_BY6)
03690             AES_CBC_decrypt_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
03691                             aes->rounds);
03692             #else /* WOLFSSL_AESNI_BYx */
03693             AES_CBC_decrypt_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
03694                             aes->rounds);
03695             #endif /* WOLFSSL_AESNI_BYx */
03696             /* store iv for next call */
03697             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
03698             return 0;
03699         }
03700     #endif
03701 
03702         blocks = sz / AES_BLOCK_SIZE;
03703         while (blocks--) {
03704             XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
03705             wc_AesDecrypt(aes, (byte*)aes->tmp, out);
03706             xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
03707             /* store iv for next call */
03708             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
03709 
03710             out += AES_BLOCK_SIZE;
03711             in  += AES_BLOCK_SIZE;
03712         }
03713 
03714         return 0;
03715     }
03716     #endif
03717 
03718 #endif /* AES-CBC block */
03719 #endif /* HAVE_AES_CBC */
03720 
03721 /* AES-CTR */
03722 #if defined(WOLFSSL_AES_COUNTER)
03723 
03724     #ifdef STM32_CRYPTO
03725         #define NEED_AES_CTR_SOFT
03726         #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
03727 
03728         int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
03729         {
03730             int ret = 0;
03731         #ifdef WOLFSSL_STM32_CUBEMX
03732             CRYP_HandleTypeDef hcryp;
03733             #ifdef STM32_HAL_V2
03734             word32 iv[AES_BLOCK_SIZE/sizeof(word32)];
03735             #endif
03736         #else
03737             word32 *iv;
03738             CRYP_InitTypeDef cryptInit;
03739             CRYP_KeyInitTypeDef keyInit;
03740             CRYP_IVInitTypeDef ivInit;
03741         #endif
03742 
03743             ret = wolfSSL_CryptHwMutexLock();
03744             if (ret != 0) {
03745                 return ret;
03746             }
03747 
03748         #ifdef WOLFSSL_STM32_CUBEMX
03749             ret = wc_Stm32_Aes_Init(aes, &hcryp);
03750             if (ret != 0) {
03751                 wolfSSL_CryptHwMutexUnLock();
03752                 return ret;
03753             }
03754 
03755         #ifdef STM32_CRYPTO_AES_ONLY
03756             hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
03757             hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
03758             hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
03759             hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
03760         #elif defined(STM32_HAL_V2)
03761             hcryp.Init.Algorithm  = CRYP_AES_CTR;
03762             ByteReverseWords(iv, aes->reg, AES_BLOCK_SIZE);
03763             hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
03764         #else
03765             hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
03766         #endif
03767             HAL_CRYP_Init(&hcryp);
03768 
03769         #ifdef STM32_CRYPTO_AES_ONLY
03770             ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE,
03771                 out, STM32_HAL_TIMEOUT);
03772         #elif defined(STM32_HAL_V2)
03773             ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
03774                 (uint32_t*)out, STM32_HAL_TIMEOUT);
03775         #else
03776             ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE,
03777                 out, STM32_HAL_TIMEOUT);
03778         #endif
03779             if (ret != HAL_OK) {
03780                 ret = WC_TIMEOUT_E;
03781             }
03782             HAL_CRYP_DeInit(&hcryp);
03783 
03784         #else /* STD_PERI_LIB */
03785             ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
03786             if (ret != 0) {
03787                 wolfSSL_CryptHwMutexUnLock();
03788                 return ret;
03789             }
03790 
03791             /* reset registers to their default values */
03792             CRYP_DeInit();
03793 
03794             /* set key */
03795             CRYP_KeyInit(&keyInit);
03796 
03797             /* set iv */
03798             iv = aes->reg;
03799             CRYP_IVStructInit(&ivInit);
03800             ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
03801             ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
03802             ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
03803             ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
03804             CRYP_IVInit(&ivInit);
03805 
03806             /* set direction and mode */
03807             cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
03808             cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
03809             CRYP_Init(&cryptInit);
03810 
03811             /* enable crypto processor */
03812             CRYP_Cmd(ENABLE);
03813 
03814             /* flush IN/OUT FIFOs */
03815             CRYP_FIFOFlush();
03816 
03817             CRYP_DataIn(*(uint32_t*)&in[0]);
03818             CRYP_DataIn(*(uint32_t*)&in[4]);
03819             CRYP_DataIn(*(uint32_t*)&in[8]);
03820             CRYP_DataIn(*(uint32_t*)&in[12]);
03821 
03822             /* wait until the complete message has been processed */
03823             while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
03824 
03825             *(uint32_t*)&out[0]  = CRYP_DataOut();
03826             *(uint32_t*)&out[4]  = CRYP_DataOut();
03827             *(uint32_t*)&out[8]  = CRYP_DataOut();
03828             *(uint32_t*)&out[12] = CRYP_DataOut();
03829 
03830             /* disable crypto processor */
03831             CRYP_Cmd(DISABLE);
03832 
03833         #endif /* WOLFSSL_STM32_CUBEMX */
03834 
03835             wolfSSL_CryptHwMutexUnLock();
03836             return ret;
03837         }
03838 
03839 
03840     #elif defined(WOLFSSL_PIC32MZ_CRYPT)
03841 
03842         #define NEED_AES_CTR_SOFT
03843         #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
03844 
03845         int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
03846         {
03847             word32 tmpIv[AES_BLOCK_SIZE / sizeof(word32)];
03848             XMEMCPY(tmpIv, aes->reg, AES_BLOCK_SIZE);
03849             return wc_Pic32AesCrypt(
03850                 aes->key, aes->keylen, tmpIv, AES_BLOCK_SIZE,
03851                 out, in, AES_BLOCK_SIZE,
03852                 PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
03853         }
03854 
03855     #elif defined(HAVE_COLDFIRE_SEC)
03856         #error "Coldfire SEC doesn't currently support AES-CTR mode"
03857 
03858     #elif defined(FREESCALE_LTC)
03859         int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03860         {
03861             uint32_t keySize;
03862             byte *iv, *enc_key;
03863             byte* tmp;
03864 
03865             if (aes == NULL || out == NULL || in == NULL) {
03866                 return BAD_FUNC_ARG;
03867             }
03868 
03869             /* consume any unused bytes left in aes->tmp */
03870             tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
03871             while (aes->left && sz) {
03872                 *(out++) = *(in++) ^ *(tmp++);
03873                 aes->left--;
03874                 sz--;
03875             }
03876 
03877             if (sz) {
03878                 iv      = (byte*)aes->reg;
03879                 enc_key = (byte*)aes->key;
03880 
03881                 wc_AesGetKeySize(aes, &keySize);
03882 
03883                 LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
03884                     iv, enc_key, keySize, (byte*)aes->tmp,
03885                     (uint32_t*)&aes->left);
03886             }
03887 
03888             return 0;
03889         }
03890 
03891     #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
03892         /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
03893 
03894     #elif defined(WOLFSSL_AFALG)
03895         /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
03896 
03897     #elif defined(WOLFSSL_DEVCRYPTO_AES)
03898         /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
03899    
03900     #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
03901         !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)
03902         /* esp32 doesn't support CRT mode by hw.     */
03903         /* use aes ecnryption plus sw implementation */
03904         #define NEED_AES_CTR_SOFT
03905 
03906     #else
03907 
03908         /* Use software based AES counter */
03909         #define NEED_AES_CTR_SOFT
03910     #endif
03911 
03912     #ifdef NEED_AES_CTR_SOFT
03913         /* Increment AES counter */
03914         static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
03915         {
03916             /* in network byte order so start at end and work back */
03917             int i;
03918             for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
03919                 if (++inOutCtr[i])  /* we're done unless we overflow */
03920                     return;
03921             }
03922         }
03923 
03924         /* Software AES - CTR Encrypt */
03925         int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
03926         {
03927             byte* tmp;
03928             byte scratch[AES_BLOCK_SIZE];
03929 
03930             if (aes == NULL || out == NULL || in == NULL) {
03931                 return BAD_FUNC_ARG;
03932             }
03933 
03934             /* consume any unused bytes left in aes->tmp */
03935             tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
03936             while (aes->left && sz) {
03937                *(out++) = *(in++) ^ *(tmp++);
03938                aes->left--;
03939                sz--;
03940             }
03941 
03942             /* do as many block size ops as possible */
03943             while (sz >= AES_BLOCK_SIZE) {
03944             #ifdef XTRANSFORM_AESCTRBLOCK
03945                 XTRANSFORM_AESCTRBLOCK(aes, out, in);
03946             #else
03947                 wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
03948                 xorbuf(scratch, in, AES_BLOCK_SIZE);
03949                 XMEMCPY(out, scratch, AES_BLOCK_SIZE);
03950             #endif
03951                 IncrementAesCounter((byte*)aes->reg);
03952 
03953                 out += AES_BLOCK_SIZE;
03954                 in  += AES_BLOCK_SIZE;
03955                 sz  -= AES_BLOCK_SIZE;
03956                 aes->left = 0;
03957             }
03958             ForceZero(scratch, AES_BLOCK_SIZE);
03959 
03960             /* handle non block size remaining and store unused byte count in left */
03961             if (sz) {
03962                 wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
03963                 IncrementAesCounter((byte*)aes->reg);
03964 
03965                 aes->left = AES_BLOCK_SIZE;
03966                 tmp = (byte*)aes->tmp;
03967 
03968                 while (sz--) {
03969                     *(out++) = *(in++) ^ *(tmp++);
03970                     aes->left--;
03971                 }
03972             }
03973 
03974             return 0;
03975         }
03976 
03977     #endif /* NEED_AES_CTR_SOFT */
03978 
03979 #endif /* WOLFSSL_AES_COUNTER */
03980 #endif /* !WOLFSSL_ARMASM */
03981 
03982 
03983 /*
03984  * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
03985  * of two parts in order:
03986  *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
03987  *      to the implicit IV.
03988  *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
03989  *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
03990  * The IV may be a 96-bit random value, or the 32-bit fixed value and a
03991  * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
03992  * block counter during the encryption.
03993  */
03994 
03995 #if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
03996 static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
03997 {
03998     int i;
03999     for (i = ctrSz-1; i >= 0; i--) {
04000         if (++ctr[i])
04001             break;
04002     }
04003 }
04004 #endif /* HAVE_AESGCM || HAVE_AESCCM */
04005 
04006 
04007 #ifdef HAVE_AESGCM
04008 
04009 #if defined(HAVE_COLDFIRE_SEC)
04010     #error "Coldfire SEC doesn't currently support AES-GCM mode"
04011 
04012 #elif defined(WOLFSSL_NRF51_AES)
04013     #error "nRF51 doesn't currently support AES-GCM mode"
04014 
04015 #endif
04016 
04017 #ifdef WOLFSSL_ARMASM
04018     /* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */
04019 
04020 #elif defined(WOLFSSL_AFALG)
04021     /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
04022 
04023 #elif defined(WOLFSSL_DEVCRYPTO_AES)
04024     /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
04025 
04026 #else /* software + AESNI implementation */
04027 
04028 #if !defined(FREESCALE_LTC_AES_GCM)
04029 static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
04030 {
04031     int i;
04032 
04033     /* in network byte order so start at end and work back */
04034     for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
04035         if (++inOutCtr[i])  /* we're done unless we overflow */
04036             return;
04037     }
04038 }
04039 #ifdef STM32_CRYPTO_AES_GCM
04040 static WC_INLINE void DecrementGcmCounter(byte* inOutCtr)
04041 {
04042     int i;
04043 
04044     /* in network byte order so start at end and work back */
04045     for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
04046         if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
04047             return;
04048     }
04049 }
04050 #endif /* STM32_CRYPTO_AES_GCM */
04051 #endif /* !FREESCALE_LTC_AES_GCM */
04052 
04053 #if defined(GCM_SMALL) || defined(GCM_TABLE)
04054 
04055 static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
04056 {
04057     /* Multiply the sz by 8 */
04058     word32 szHi = (sz >> (8*sizeof(sz) - 3));
04059     sz <<= 3;
04060 
04061     /* copy over the words of the sz into the destination buffer */
04062     buf[0] = (szHi >> 24) & 0xff;
04063     buf[1] = (szHi >> 16) & 0xff;
04064     buf[2] = (szHi >>  8) & 0xff;
04065     buf[3] = szHi & 0xff;
04066     buf[4] = (sz >> 24) & 0xff;
04067     buf[5] = (sz >> 16) & 0xff;
04068     buf[6] = (sz >>  8) & 0xff;
04069     buf[7] = sz & 0xff;
04070 }
04071 
04072 
04073 static WC_INLINE void RIGHTSHIFTX(byte* x)
04074 {
04075     int i;
04076     int carryOut = 0;
04077     int carryIn = 0;
04078     int borrow = x[15] & 0x01;
04079 
04080     for (i = 0; i < AES_BLOCK_SIZE; i++) {
04081         carryOut = x[i] & 0x01;
04082         x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
04083         carryIn = carryOut;
04084     }
04085     if (borrow) x[0] ^= 0xE1;
04086 }
04087 
04088 #endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
04089 
04090 
04091 #ifdef GCM_TABLE
04092 
04093 static void GenerateM0(Aes* aes)
04094 {
04095     int i, j;
04096     byte (*m)[AES_BLOCK_SIZE] = aes->M0;
04097 
04098     XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
04099 
04100     for (i = 64; i > 0; i /= 2) {
04101         XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
04102         RIGHTSHIFTX(m[i]);
04103     }
04104 
04105     for (i = 2; i < 256; i *= 2) {
04106         for (j = 1; j < i; j++) {
04107             XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
04108             xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
04109         }
04110     }
04111 
04112     XMEMSET(m[0], 0, AES_BLOCK_SIZE);
04113 }
04114 
04115 #endif /* GCM_TABLE */
04116 
04117 /* Software AES - GCM SetKey */
04118 int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
04119 {
04120     int  ret;
04121     byte iv[AES_BLOCK_SIZE];
04122 
04123     #ifdef WOLFSSL_IMX6_CAAM_BLOB
04124         byte   local[32];
04125         word32 localSz = 32;
04126 
04127         if (len == (16 + WC_CAAM_BLOB_SZ) ||
04128           len == (24 + WC_CAAM_BLOB_SZ) ||
04129           len == (32 + WC_CAAM_BLOB_SZ)) {
04130             if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
04131                  return BAD_FUNC_ARG;
04132             }
04133 
04134             /* set local values */
04135             key = local;
04136             len = localSz;
04137         }
04138     #endif
04139 
04140     if (!((len == 16) || (len == 24) || (len == 32)))
04141         return BAD_FUNC_ARG;
04142 
04143 #ifdef OPENSSL_EXTRA
04144     if (aes != NULL) {
04145         XMEMSET(aes->aadH, 0, sizeof(aes->aadH));
04146         aes->aadLen = 0;
04147     }
04148 #endif
04149     XMEMSET(iv, 0, AES_BLOCK_SIZE);
04150     ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
04151 
04152     #ifdef WOLFSSL_AESNI
04153         /* AES-NI code generates its own H value. */
04154         if (haveAESNI)
04155             return ret;
04156     #endif /* WOLFSSL_AESNI */
04157 
04158 #if !defined(FREESCALE_LTC_AES_GCM)
04159     if (ret == 0) {
04160         wc_AesEncrypt(aes, iv, aes->H);
04161     #ifdef GCM_TABLE
04162         GenerateM0(aes);
04163     #endif /* GCM_TABLE */
04164     }
04165 #endif /* FREESCALE_LTC_AES_GCM */
04166 
04167 #if defined(WOLFSSL_XILINX_CRYPT)
04168     wc_AesGcmSetKey_ex(aes, key, len, XSECURE_CSU_AES_KEY_SRC_KUP);
04169 #elif defined(WOLFSSL_AFALG_XILINX_AES)
04170     wc_AesGcmSetKey_ex(aes, key, len, 0);
04171 #endif
04172 
04173 #ifdef WOLF_CRYPTO_CB
04174     if (aes->devId != INVALID_DEVID) {
04175         XMEMCPY(aes->devKey, key, len);
04176     }
04177 #endif
04178 
04179 #ifdef WOLFSSL_IMX6_CAAM_BLOB
04180     ForceZero(local, sizeof(local));
04181 #endif
04182 
04183     return ret;
04184 }
04185 
04186 
04187 #ifdef WOLFSSL_AESNI
04188 
04189 #if defined(USE_INTEL_SPEEDUP)
04190     #define HAVE_INTEL_AVX1
04191     #define HAVE_INTEL_AVX2
04192 #endif /* USE_INTEL_SPEEDUP */
04193 
04194 #ifndef _MSC_VER
04195 
04196 void AES_GCM_encrypt(const unsigned char *in, unsigned char *out,
04197                      const unsigned char* addt, const unsigned char* ivec,
04198                      unsigned char *tag, unsigned int nbytes,
04199                      unsigned int abytes, unsigned int ibytes,
04200                      unsigned int tbytes, const unsigned char* key, int nr)
04201                      XASM_LINK("AES_GCM_encrypt");
04202 #ifdef HAVE_INTEL_AVX1
04203 void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
04204                           const unsigned char* addt, const unsigned char* ivec,
04205                           unsigned char *tag, unsigned int nbytes,
04206                           unsigned int abytes, unsigned int ibytes,
04207                           unsigned int tbytes, const unsigned char* key,
04208                           int nr)
04209                           XASM_LINK("AES_GCM_encrypt_avx1");
04210 #ifdef HAVE_INTEL_AVX2
04211 void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
04212                           const unsigned char* addt, const unsigned char* ivec,
04213                           unsigned char *tag, unsigned int nbytes,
04214                           unsigned int abytes, unsigned int ibytes,
04215                           unsigned int tbytes, const unsigned char* key,
04216                           int nr)
04217                           XASM_LINK("AES_GCM_encrypt_avx2");
04218 #endif /* HAVE_INTEL_AVX2 */
04219 #endif /* HAVE_INTEL_AVX1 */
04220 
04221 #ifdef HAVE_AES_DECRYPT
04222 void AES_GCM_decrypt(const unsigned char *in, unsigned char *out,
04223                      const unsigned char* addt, const unsigned char* ivec,
04224                      const unsigned char *tag, int nbytes, int abytes,
04225                      int ibytes, int tbytes, const unsigned char* key, int nr,
04226                      int* res)
04227                      XASM_LINK("AES_GCM_decrypt");
04228 #ifdef HAVE_INTEL_AVX1
04229 void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
04230                           const unsigned char* addt, const unsigned char* ivec,
04231                           const unsigned char *tag, int nbytes, int abytes,
04232                           int ibytes, int tbytes, const unsigned char* key,
04233                           int nr, int* res)
04234                           XASM_LINK("AES_GCM_decrypt_avx1");
04235 #ifdef HAVE_INTEL_AVX2
04236 void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
04237                           const unsigned char* addt, const unsigned char* ivec,
04238                           const unsigned char *tag, int nbytes, int abytes,
04239                           int ibytes, int tbytes, const unsigned char* key,
04240                           int nr, int* res)
04241                           XASM_LINK("AES_GCM_decrypt_avx2");
04242 #endif /* HAVE_INTEL_AVX2 */
04243 #endif /* HAVE_INTEL_AVX1 */
04244 #endif /* HAVE_AES_DECRYPT */
04245 
04246 #else /* _MSC_VER */
04247 
04248 #define S(w,z) ((char)((unsigned long long)(w) >> (8*(7-(z))) & 0xFF))
04249 #define M128_INIT(x,y) { S((x),7), S((x),6), S((x),5), S((x),4), \
04250                          S((x),3), S((x),2), S((x),1), S((x),0), \
04251                          S((y),7), S((y),6), S((y),5), S((y),4), \
04252                          S((y),3), S((y),2), S((y),1), S((y),0) }
04253 
04254 static const __m128i MOD2_128 =
04255         M128_INIT(0x1, (long long int)0xc200000000000000UL);
04256 
04257 
04258 /* See Intel® Carry-Less Multiplication Instruction
04259  * and its Usage for Computing the GCM Mode White Paper
04260  * by Shay Gueron, Intel Mobility Group, Israel Development Center;
04261  * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */
04262 
04263 
04264 /* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */
04265 
04266 static const __m128i ONE   = M128_INIT(0x0, 0x1);
04267 #ifndef AES_GCM_AESNI_NO_UNROLL
04268 static const __m128i TWO   = M128_INIT(0x0, 0x2);
04269 static const __m128i THREE = M128_INIT(0x0, 0x3);
04270 static const __m128i FOUR  = M128_INIT(0x0, 0x4);
04271 static const __m128i FIVE  = M128_INIT(0x0, 0x5);
04272 static const __m128i SIX   = M128_INIT(0x0, 0x6);
04273 static const __m128i SEVEN = M128_INIT(0x0, 0x7);
04274 static const __m128i EIGHT = M128_INIT(0x0, 0x8);
04275 #endif
04276 static const __m128i BSWAP_EPI64 =
04277         M128_INIT(0x0001020304050607, 0x08090a0b0c0d0e0f);
04278 static const __m128i BSWAP_MASK =
04279         M128_INIT(0x08090a0b0c0d0e0f, 0x0001020304050607);
04280 
04281 
04282 /* The following are for MSC based builds which do not allow
04283  * inline assembly. Intrinsic functions are used instead. */
04284 
04285 #define aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T)         \
04286 do                                                         \
04287 {                                                          \
04288     word32 iv12[4];                                        \
04289     iv12[0] = *(word32*)&ivec[0];                          \
04290     iv12[1] = *(word32*)&ivec[4];                          \
04291     iv12[2] = *(word32*)&ivec[8];                          \
04292     iv12[3] = 0x01000000;                                  \
04293     Y = _mm_loadu_si128((__m128i*)iv12);                   \
04294                                                            \
04295     /* (Compute E[ZERO, KS] and E[Y0, KS] together */      \
04296     tmp1 = _mm_load_si128(&KEY[0]);                        \
04297     tmp2 = _mm_xor_si128(Y, KEY[0]);                       \
04298     tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                 \
04299     tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);                 \
04300     tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                 \
04301     tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);                 \
04302     tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                 \
04303     tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);                 \
04304     tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                 \
04305     tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);                 \
04306     tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                 \
04307     tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);                 \
04308     tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                 \
04309     tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);                 \
04310     tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                 \
04311     tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);                 \
04312     tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                 \
04313     tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);                 \
04314     tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                 \
04315     tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);                 \
04316     lastKey = KEY[10];                                     \
04317     if (nr > 10) {                                         \
04318         tmp1 = _mm_aesenc_si128(tmp1, lastKey);            \
04319         tmp2 = _mm_aesenc_si128(tmp2, lastKey);            \
04320         tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);            \
04321         tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);            \
04322         lastKey = KEY[12];                                 \
04323         if (nr > 12) {                                     \
04324             tmp1 = _mm_aesenc_si128(tmp1, lastKey);        \
04325             tmp2 = _mm_aesenc_si128(tmp2, lastKey);        \
04326             tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);        \
04327             tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);        \
04328             lastKey = KEY[14];                             \
04329         }                                                  \
04330     }                                                      \
04331     H = _mm_aesenclast_si128(tmp1, lastKey);               \
04332     T = _mm_aesenclast_si128(tmp2, lastKey);               \
04333     H = _mm_shuffle_epi8(H, BSWAP_MASK);                   \
04334 }                                                          \
04335 while (0)
04336 
04337 #define aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T)         \
04338 do                                                              \
04339 {                                                               \
04340     if (ibytes % 16) {                                          \
04341         i = ibytes / 16;                                        \
04342         for (j=0; j < (int)(ibytes%16); j++)                    \
04343             ((unsigned char*)&last_block)[j] = ivec[i*16+j];    \
04344     }                                                           \
04345     tmp1 = _mm_load_si128(&KEY[0]);                             \
04346     tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
04347     tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
04348     tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
04349     tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
04350     tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
04351     tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
04352     tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
04353     tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
04354     tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
04355     lastKey = KEY[10];                                          \
04356     if (nr > 10) {                                              \
04357         tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
04358         tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
04359         lastKey = KEY[12];                                      \
04360         if (nr > 12) {                                          \
04361             tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
04362             tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
04363             lastKey = KEY[14];                                  \
04364         }                                                       \
04365     }                                                           \
04366     H = _mm_aesenclast_si128(tmp1, lastKey);                    \
04367     H = _mm_shuffle_epi8(H, BSWAP_MASK);                        \
04368     Y = _mm_setzero_si128();                                    \
04369     for (i=0; i < (int)(ibytes/16); i++) {                      \
04370         tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);           \
04371         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
04372         Y = _mm_xor_si128(Y, tmp1);                             \
04373         Y = gfmul_sw(Y, H);                                     \
04374     }                                                           \
04375     if (ibytes % 16) {                                          \
04376         tmp1 = last_block;                                      \
04377         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
04378         Y = _mm_xor_si128(Y, tmp1);                             \
04379         Y = gfmul_sw(Y, H);                                     \
04380     }                                                           \
04381     tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);                 \
04382     tmp1 = _mm_insert_epi64(tmp1, 0, 1);                        \
04383     Y = _mm_xor_si128(Y, tmp1);                                 \
04384     Y = gfmul_sw(Y, H);                                         \
04385     Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */ \
04386     tmp1 = _mm_xor_si128(Y, KEY[0]);                            \
04387     tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
04388     tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
04389     tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
04390     tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
04391     tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
04392     tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
04393     tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
04394     tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
04395     tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
04396     lastKey = KEY[10];                                          \
04397     if (nr > 10) {                                              \
04398         tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
04399         tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
04400         lastKey = KEY[12];                                      \
04401         if (nr > 12) {                                          \
04402             tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
04403             tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
04404             lastKey = KEY[14];                                  \
04405         }                                                       \
04406     }                                                           \
04407     T = _mm_aesenclast_si128(tmp1, lastKey);                    \
04408 }                                                               \
04409 while (0)
04410 
04411 #define AES_ENC_8(j)                       \
04412     tmp1 = _mm_aesenc_si128(tmp1, KEY[j]); \
04413     tmp2 = _mm_aesenc_si128(tmp2, KEY[j]); \
04414     tmp3 = _mm_aesenc_si128(tmp3, KEY[j]); \
04415     tmp4 = _mm_aesenc_si128(tmp4, KEY[j]); \
04416     tmp5 = _mm_aesenc_si128(tmp5, KEY[j]); \
04417     tmp6 = _mm_aesenc_si128(tmp6, KEY[j]); \
04418     tmp7 = _mm_aesenc_si128(tmp7, KEY[j]); \
04419     tmp8 = _mm_aesenc_si128(tmp8, KEY[j]);
04420 
04421 #define AES_ENC_LAST_8()                                                  \
04422     tmp1 =_mm_aesenclast_si128(tmp1, lastKey);                            \
04423     tmp2 =_mm_aesenclast_si128(tmp2, lastKey);                            \
04424     tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));  \
04425     tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));  \
04426     _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);                      \
04427     _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);                      \
04428     tmp3 =_mm_aesenclast_si128(tmp3, lastKey);                            \
04429     tmp4 =_mm_aesenclast_si128(tmp4, lastKey);                            \
04430     tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));  \
04431     tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));  \
04432     _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);                      \
04433     _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);                      \
04434     tmp5 =_mm_aesenclast_si128(tmp5, lastKey);                            \
04435     tmp6 =_mm_aesenclast_si128(tmp6, lastKey);                            \
04436     tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));  \
04437     tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));  \
04438     _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);                      \
04439     _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);                      \
04440     tmp7 =_mm_aesenclast_si128(tmp7, lastKey);                            \
04441     tmp8 =_mm_aesenclast_si128(tmp8, lastKey);                            \
04442     tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));  \
04443     tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));  \
04444     _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);                      \
04445     _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);
04446 
04447 
04448 static __m128i gfmul_sw(__m128i a, __m128i b)
04449 {
04450     __m128i r, t1, t2, t3, t4, t5, t6, t7;
04451     t2 = _mm_shuffle_epi32(b, 78);
04452     t3 = _mm_shuffle_epi32(a, 78);
04453     t2 = _mm_xor_si128(t2, b);
04454     t3 = _mm_xor_si128(t3, a);
04455     t4 = _mm_clmulepi64_si128(b, a, 0x11);
04456     t1 = _mm_clmulepi64_si128(b, a, 0x00);
04457     t2 = _mm_clmulepi64_si128(t2, t3, 0x00);
04458     t2 = _mm_xor_si128(t2, t1);
04459     t2 = _mm_xor_si128(t2, t4);
04460     t3 = _mm_slli_si128(t2, 8);
04461     t2 = _mm_srli_si128(t2, 8);
04462     t1 = _mm_xor_si128(t1, t3);
04463     t4 = _mm_xor_si128(t4, t2);
04464 
04465     t5 = _mm_srli_epi32(t1, 31);
04466     t6 = _mm_srli_epi32(t4, 31);
04467     t1 = _mm_slli_epi32(t1, 1);
04468     t4 = _mm_slli_epi32(t4, 1);
04469     t7 = _mm_srli_si128(t5, 12);
04470     t5 = _mm_slli_si128(t5, 4);
04471     t6 = _mm_slli_si128(t6, 4);
04472     t4 = _mm_or_si128(t4, t7);
04473     t1 = _mm_or_si128(t1, t5);
04474     t4 = _mm_or_si128(t4, t6);
04475 
04476     t5 = _mm_slli_epi32(t1, 31);
04477     t6 = _mm_slli_epi32(t1, 30);
04478     t7 = _mm_slli_epi32(t1, 25);
04479     t5 = _mm_xor_si128(t5, t6);
04480     t5 = _mm_xor_si128(t5, t7);
04481 
04482     t6 = _mm_srli_si128(t5, 4);
04483     t5 = _mm_slli_si128(t5, 12);
04484     t1 = _mm_xor_si128(t1, t5);
04485     t7 = _mm_srli_epi32(t1, 1);
04486     t3 = _mm_srli_epi32(t1, 2);
04487     t2 = _mm_srli_epi32(t1, 7);
04488 
04489     t7 = _mm_xor_si128(t7, t3);
04490     t7 = _mm_xor_si128(t7, t2);
04491     t7 = _mm_xor_si128(t7, t6);
04492     t7 = _mm_xor_si128(t7, t1);
04493     r = _mm_xor_si128(t4, t7);
04494 
04495     return r;
04496 }
04497 
04498 static void gfmul_only(__m128i a, __m128i b, __m128i* r0, __m128i* r1)
04499 {
04500     __m128i t1, t2, t3, t4;
04501 
04502     /* 128 x 128 Carryless Multiply */
04503     t2 = _mm_shuffle_epi32(b, 78);
04504     t3 = _mm_shuffle_epi32(a, 78);
04505     t2 = _mm_xor_si128(t2, b);
04506     t3 = _mm_xor_si128(t3, a);
04507     t4 = _mm_clmulepi64_si128(b, a, 0x11);
04508     t1 = _mm_clmulepi64_si128(b, a, 0x00);
04509     t2 = _mm_clmulepi64_si128(t2, t3, 0x00);
04510     t2 = _mm_xor_si128(t2, t1);
04511     t2 = _mm_xor_si128(t2, t4);
04512     t3 = _mm_slli_si128(t2, 8);
04513     t2 = _mm_srli_si128(t2, 8);
04514     t1 = _mm_xor_si128(t1, t3);
04515     t4 = _mm_xor_si128(t4, t2);
04516     *r0 = _mm_xor_si128(t1, *r0);
04517     *r1 = _mm_xor_si128(t4, *r1);
04518 }
04519 
04520 static __m128i gfmul_shl1(__m128i a)
04521 {
04522     __m128i t1 = a, t2;
04523     t2 = _mm_srli_epi64(t1, 63);
04524     t1 = _mm_slli_epi64(t1, 1);
04525     t2 = _mm_slli_si128(t2, 8);
04526     t1 = _mm_or_si128(t1, t2);
04527     /* if (a[1] >> 63) t1 = _mm_xor_si128(t1, MOD2_128); */
04528     a = _mm_shuffle_epi32(a, 0xff);
04529     a = _mm_srai_epi32(a, 31);
04530     a = _mm_and_si128(a, MOD2_128);
04531     t1 = _mm_xor_si128(t1, a);
04532     return t1;
04533 }
04534 
04535 static __m128i ghash_red(__m128i r0, __m128i r1)
04536 {
04537     __m128i t2, t3;
04538     __m128i t5, t6, t7;
04539 
04540     t5 = _mm_slli_epi32(r0, 31);
04541     t6 = _mm_slli_epi32(r0, 30);
04542     t7 = _mm_slli_epi32(r0, 25);
04543     t5 = _mm_xor_si128(t5, t6);
04544     t5 = _mm_xor_si128(t5, t7);
04545 
04546     t6 = _mm_srli_si128(t5, 4);
04547     t5 = _mm_slli_si128(t5, 12);
04548     r0 = _mm_xor_si128(r0, t5);
04549     t7 = _mm_srli_epi32(r0, 1);
04550     t3 = _mm_srli_epi32(r0, 2);
04551     t2 = _mm_srli_epi32(r0, 7);
04552 
04553     t7 = _mm_xor_si128(t7, t3);
04554     t7 = _mm_xor_si128(t7, t2);
04555     t7 = _mm_xor_si128(t7, t6);
04556     t7 = _mm_xor_si128(t7, r0);
04557     return _mm_xor_si128(r1, t7);
04558 }
04559 
04560 static __m128i gfmul_shifted(__m128i a, __m128i b)
04561 {
04562     __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();
04563     gfmul_only(a, b, &t0, &t1);
04564     return ghash_red(t0, t1);
04565 }
04566 
04567 #ifndef AES_GCM_AESNI_NO_UNROLL
04568 static __m128i gfmul8(__m128i a1, __m128i a2, __m128i a3, __m128i a4,
04569                       __m128i a5, __m128i a6, __m128i a7, __m128i a8,
04570                       __m128i b1, __m128i b2, __m128i b3, __m128i b4,
04571                       __m128i b5, __m128i b6, __m128i b7, __m128i b8)
04572 {
04573     __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();
04574     gfmul_only(a1, b8, &t0, &t1);
04575     gfmul_only(a2, b7, &t0, &t1);
04576     gfmul_only(a3, b6, &t0, &t1);
04577     gfmul_only(a4, b5, &t0, &t1);
04578     gfmul_only(a5, b4, &t0, &t1);
04579     gfmul_only(a6, b3, &t0, &t1);
04580     gfmul_only(a7, b2, &t0, &t1);
04581     gfmul_only(a8, b1, &t0, &t1);
04582     return ghash_red(t0, t1);
04583 }
04584 #endif
04585 
04586 
04587 static void AES_GCM_encrypt(const unsigned char *in,
04588                               unsigned char *out,
04589                               const unsigned char* addt,
04590                               const unsigned char* ivec,
04591                               unsigned char *tag, unsigned int nbytes,
04592                               unsigned int abytes, unsigned int ibytes,
04593                               unsigned int tbytes,
04594                               const unsigned char* key, int nr)
04595 {
04596     int i, j ,k;
04597     __m128i ctr1;
04598     __m128i H, Y, T;
04599     __m128i X = _mm_setzero_si128();
04600     __m128i *KEY = (__m128i*)key, lastKey;
04601     __m128i last_block = _mm_setzero_si128();
04602     __m128i tmp1, tmp2;
04603 #ifndef AES_GCM_AESNI_NO_UNROLL
04604     __m128i HT[8];
04605     __m128i r0, r1;
04606     __m128i XV;
04607     __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
04608 #endif
04609 
04610     if (ibytes == GCM_NONCE_MID_SZ)
04611         aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
04612     else
04613         aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
04614 
04615     for (i=0; i < (int)(abytes/16); i++) {
04616         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
04617         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04618         X = _mm_xor_si128(X, tmp1);
04619         X = gfmul_sw(X, H);
04620     }
04621     if (abytes%16) {
04622         last_block = _mm_setzero_si128();
04623         for (j=0; j < (int)(abytes%16); j++)
04624             ((unsigned char*)&last_block)[j] = addt[i*16+j];
04625         tmp1 = last_block;
04626         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04627         X = _mm_xor_si128(X, tmp1);
04628         X = gfmul_sw(X, H);
04629     }
04630     tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
04631     ctr1 = _mm_add_epi32(tmp1, ONE);
04632     H = gfmul_shl1(H);
04633 
04634 #ifndef AES_GCM_AESNI_NO_UNROLL
04635     i = 0;
04636     if (nbytes >= 16*8) {
04637         HT[0] = H;
04638         HT[1] = gfmul_shifted(H, H);
04639         HT[2] = gfmul_shifted(H, HT[1]);
04640         HT[3] = gfmul_shifted(HT[1], HT[1]);
04641         HT[4] = gfmul_shifted(HT[1], HT[2]);
04642         HT[5] = gfmul_shifted(HT[2], HT[2]);
04643         HT[6] = gfmul_shifted(HT[2], HT[3]);
04644         HT[7] = gfmul_shifted(HT[3], HT[3]);
04645 
04646         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04647         tmp2 = _mm_add_epi32(ctr1, ONE);
04648         tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
04649         tmp3 = _mm_add_epi32(ctr1, TWO);
04650         tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
04651         tmp4 = _mm_add_epi32(ctr1, THREE);
04652         tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
04653         tmp5 = _mm_add_epi32(ctr1, FOUR);
04654         tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
04655         tmp6 = _mm_add_epi32(ctr1, FIVE);
04656         tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
04657         tmp7 = _mm_add_epi32(ctr1, SIX);
04658         tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
04659         tmp8 = _mm_add_epi32(ctr1, SEVEN);
04660         tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
04661         ctr1 = _mm_add_epi32(ctr1, EIGHT);
04662         tmp1 =_mm_xor_si128(tmp1, KEY[0]);
04663         tmp2 =_mm_xor_si128(tmp2, KEY[0]);
04664         tmp3 =_mm_xor_si128(tmp3, KEY[0]);
04665         tmp4 =_mm_xor_si128(tmp4, KEY[0]);
04666         tmp5 =_mm_xor_si128(tmp5, KEY[0]);
04667         tmp6 =_mm_xor_si128(tmp6, KEY[0]);
04668         tmp7 =_mm_xor_si128(tmp7, KEY[0]);
04669         tmp8 =_mm_xor_si128(tmp8, KEY[0]);
04670         AES_ENC_8(1);
04671         AES_ENC_8(2);
04672         AES_ENC_8(3);
04673         AES_ENC_8(4);
04674         AES_ENC_8(5);
04675         AES_ENC_8(6);
04676         AES_ENC_8(7);
04677         AES_ENC_8(8);
04678         AES_ENC_8(9);
04679         lastKey = KEY[10];
04680         if (nr > 10) {
04681             AES_ENC_8(10);
04682             AES_ENC_8(11);
04683             lastKey = KEY[12];
04684             if (nr > 12) {
04685                 AES_ENC_8(12);
04686                 AES_ENC_8(13);
04687                 lastKey = KEY[14];
04688             }
04689         }
04690         AES_ENC_LAST_8();
04691 
04692         for (i=1; i < (int)(nbytes/16/8); i++) {
04693                 r0 = _mm_setzero_si128();
04694                 r1 = _mm_setzero_si128();
04695             tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04696             tmp2 = _mm_add_epi32(ctr1, ONE);
04697             tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
04698             tmp3 = _mm_add_epi32(ctr1, TWO);
04699             tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
04700             tmp4 = _mm_add_epi32(ctr1, THREE);
04701             tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
04702             tmp5 = _mm_add_epi32(ctr1, FOUR);
04703             tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
04704             tmp6 = _mm_add_epi32(ctr1, FIVE);
04705             tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
04706             tmp7 = _mm_add_epi32(ctr1, SIX);
04707             tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
04708             tmp8 = _mm_add_epi32(ctr1, SEVEN);
04709             tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
04710             ctr1 = _mm_add_epi32(ctr1, EIGHT);
04711             tmp1 =_mm_xor_si128(tmp1, KEY[0]);
04712             tmp2 =_mm_xor_si128(tmp2, KEY[0]);
04713             tmp3 =_mm_xor_si128(tmp3, KEY[0]);
04714             tmp4 =_mm_xor_si128(tmp4, KEY[0]);
04715             tmp5 =_mm_xor_si128(tmp5, KEY[0]);
04716             tmp6 =_mm_xor_si128(tmp6, KEY[0]);
04717             tmp7 =_mm_xor_si128(tmp7, KEY[0]);
04718             tmp8 =_mm_xor_si128(tmp8, KEY[0]);
04719                 /* 128 x 128 Carryless Multiply */
04720                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+0]);
04721                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04722                 XV = _mm_xor_si128(XV, X);
04723                 gfmul_only(XV, HT[7], &r0, &r1);
04724             tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
04725             tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
04726             tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);
04727             tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);
04728             tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);
04729             tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);
04730             tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);
04731             tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);
04732                 /* 128 x 128 Carryless Multiply */
04733                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+1]);
04734                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04735                 gfmul_only(XV, HT[6], &r0, &r1);
04736             tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
04737             tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
04738             tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);
04739             tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);
04740             tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);
04741             tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);
04742             tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);
04743             tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);
04744                 /* 128 x 128 Carryless Multiply */
04745                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+2]);
04746                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04747                 gfmul_only(XV, HT[5], &r0, &r1);
04748             tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
04749             tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
04750             tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);
04751             tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);
04752             tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);
04753             tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);
04754             tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);
04755             tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);
04756                 /* 128 x 128 Carryless Multiply */
04757                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+3]);
04758                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04759                 gfmul_only(XV, HT[4], &r0, &r1);
04760             tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
04761             tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
04762             tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);
04763             tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);
04764             tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);
04765             tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);
04766             tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);
04767             tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);
04768                 /* 128 x 128 Carryless Multiply */
04769                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+4]);
04770                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04771                 gfmul_only(XV, HT[3], &r0, &r1);
04772             tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
04773             tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
04774             tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);
04775             tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);
04776             tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);
04777             tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);
04778             tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);
04779             tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);
04780                 /* 128 x 128 Carryless Multiply */
04781                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+5]);
04782                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04783                 gfmul_only(XV, HT[2], &r0, &r1);
04784             tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
04785             tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
04786             tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);
04787             tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);
04788             tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);
04789             tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);
04790             tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);
04791             tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);
04792                 /* 128 x 128 Carryless Multiply */
04793                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+6]);
04794                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04795                 gfmul_only(XV, HT[1], &r0, &r1);
04796             tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
04797             tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
04798             tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);
04799             tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);
04800             tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);
04801             tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);
04802             tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);
04803             tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);
04804                 /* 128 x 128 Carryless Multiply */
04805                 XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+7]);
04806                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
04807                 gfmul_only(XV, HT[0], &r0, &r1);
04808             tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
04809             tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
04810             tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);
04811             tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);
04812             tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);
04813             tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);
04814             tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);
04815             tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);
04816                 /* Reduction */
04817                 X = ghash_red(r0, r1);
04818             tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
04819             tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
04820             tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);
04821             tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);
04822             tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);
04823             tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);
04824             tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);
04825             tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);
04826             lastKey = KEY[10];
04827             if (nr > 10) {
04828                 tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);
04829                 tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);
04830                 tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);
04831                 tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);
04832                 tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);
04833                 tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);
04834                 tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);
04835                 tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);
04836                 tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
04837                 tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
04838                 tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);
04839                 tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);
04840                 tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);
04841                 tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);
04842                 tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);
04843                 tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);
04844                 lastKey = KEY[12];
04845                 if (nr > 12) {
04846                     tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);
04847                     tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);
04848                     tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);
04849                     tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);
04850                     tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);
04851                     tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);
04852                     tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);
04853                     tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);
04854                     tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
04855                     tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
04856                     tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);
04857                     tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);
04858                     tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);
04859                     tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);
04860                     tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);
04861                     tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
04862                     lastKey = KEY[14];
04863                 }
04864             }
04865             AES_ENC_LAST_8();
04866         }
04867 
04868         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04869         tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);
04870         tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);
04871         tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);
04872         tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_MASK);
04873         tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_MASK);
04874         tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_MASK);
04875         tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_MASK);
04876         tmp1 = _mm_xor_si128(X, tmp1);
04877         X = gfmul8(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8,
04878                    HT[0], HT[1], HT[2], HT[3], HT[4], HT[5], HT[6], HT[7]);
04879     }
04880     for (k = i*8; k < (int)(nbytes/16); k++) {
04881         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04882         ctr1 = _mm_add_epi32(ctr1, ONE);
04883         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
04884         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
04885         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
04886         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
04887         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
04888         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
04889         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
04890         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
04891         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
04892         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
04893         lastKey = KEY[10];
04894         if (nr > 10) {
04895             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04896             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
04897             lastKey = KEY[12];
04898             if (nr > 12) {
04899                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04900                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
04901                 lastKey = KEY[14];
04902             }
04903         }
04904         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
04905         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
04906         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
04907         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04908         X =_mm_xor_si128(X, tmp1);
04909         X = gfmul_shifted(X, H);
04910     }
04911 #else /* AES_GCM_AESNI_NO_UNROLL */
04912     for (k = 0; k < (int)(nbytes/16) && k < 1; k++) {
04913         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04914         ctr1 = _mm_add_epi32(ctr1, ONE);
04915         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
04916         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
04917         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
04918         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
04919         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
04920         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
04921         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
04922         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
04923         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
04924         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
04925         lastKey = KEY[10];
04926         if (nr > 10) {
04927             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04928             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
04929             lastKey = KEY[12];
04930             if (nr > 12) {
04931                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04932                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
04933                 lastKey = KEY[14];
04934             }
04935         }
04936         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
04937         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
04938         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
04939         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04940         X =_mm_xor_si128(X, tmp1);
04941     }
04942     for (; k < (int)(nbytes/16); k++) {
04943         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04944         ctr1 = _mm_add_epi32(ctr1, ONE);
04945         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
04946         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
04947         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
04948         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
04949         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
04950         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
04951         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
04952         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
04953         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
04954         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
04955         X = gfmul_shifted(X, H);
04956         lastKey = KEY[10];
04957         if (nr > 10) {
04958             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04959             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
04960             lastKey = KEY[12];
04961             if (nr > 12) {
04962                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04963                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
04964                 lastKey = KEY[14];
04965             }
04966         }
04967         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
04968         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
04969         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
04970         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
04971         X =_mm_xor_si128(X, tmp1);
04972     }
04973     if (k > 0) {
04974         X = gfmul_shifted(X, H);
04975     }
04976 #endif /* AES_GCM_AESNI_NO_UNROLL */
04977 
04978     /* If one partial block remains */
04979     if (nbytes % 16) {
04980         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
04981         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
04982         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
04983         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
04984         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
04985         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
04986         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
04987         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
04988         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
04989         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
04990         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
04991         lastKey = KEY[10];
04992         if (nr > 10) {
04993             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04994             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
04995             lastKey = KEY[12];
04996             if (nr > 12) {
04997                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
04998                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
04999                 lastKey = KEY[14];
05000             }
05001         }
05002         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
05003         last_block = tmp1;
05004         for (j=0; j < (int)(nbytes%16); j++)
05005             ((unsigned char*)&last_block)[j] = in[k*16+j];
05006         tmp1 = _mm_xor_si128(tmp1, last_block);
05007         last_block = tmp1;
05008         for (j=0; j < (int)(nbytes%16); j++)
05009             out[k*16+j] = ((unsigned char*)&last_block)[j];
05010         tmp1 = last_block;
05011         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
05012         X =_mm_xor_si128(X, tmp1);
05013         X = gfmul_shifted(X, H);
05014     }
05015     tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
05016     tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
05017     X = _mm_xor_si128(X, tmp1);
05018     X = gfmul_shifted(X, H);
05019     X = _mm_shuffle_epi8(X, BSWAP_MASK);
05020     T = _mm_xor_si128(X, T);
05021     /*_mm_storeu_si128((__m128i*)tag, T);*/
05022     XMEMCPY(tag, &T, tbytes);
05023 }
05024 
05025 #ifdef HAVE_AES_DECRYPT
05026 
05027 static void AES_GCM_decrypt(const unsigned char *in,
05028                            unsigned char *out,
05029                            const unsigned char* addt,
05030                            const unsigned char* ivec,
05031                            const unsigned char *tag, int nbytes, int abytes,
05032                            int ibytes, word32 tbytes, const unsigned char* key,
05033                            int nr, int* res)
05034 {
05035     int i, j ,k;
05036     __m128i H, Y, T;
05037     __m128i *KEY = (__m128i*)key, lastKey;
05038     __m128i ctr1;
05039     __m128i last_block = _mm_setzero_si128();
05040     __m128i X = _mm_setzero_si128();
05041     __m128i tmp1, tmp2, XV;
05042 #ifndef AES_GCM_AESNI_NO_UNROLL
05043     __m128i HT[8];
05044     __m128i r0, r1;
05045     __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
05046 #endif /* AES_GCM_AESNI_NO_UNROLL */
05047 
05048     if (ibytes == GCM_NONCE_MID_SZ)
05049         aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
05050     else
05051         aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
05052 
05053     for (i=0; i<abytes/16; i++) {
05054         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
05055         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
05056         X = _mm_xor_si128(X, tmp1);
05057         X = gfmul_sw(X, H);
05058     }
05059     if (abytes%16) {
05060         last_block = _mm_setzero_si128();
05061         for (j=0; j<abytes%16; j++)
05062             ((unsigned char*)&last_block)[j] = addt[i*16+j];
05063         tmp1 = last_block;
05064         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
05065         X = _mm_xor_si128(X, tmp1);
05066         X = gfmul_sw(X, H);
05067     }
05068 
05069     tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
05070     ctr1 = _mm_add_epi32(tmp1, ONE);
05071     H = gfmul_shl1(H);
05072     i = 0;
05073 
05074 #ifndef AES_GCM_AESNI_NO_UNROLL
05075 
05076     if (0 < nbytes/16/8) {
05077         HT[0] = H;
05078         HT[1] = gfmul_shifted(H, H);
05079         HT[2] = gfmul_shifted(H, HT[1]);
05080         HT[3] = gfmul_shifted(HT[1], HT[1]);
05081         HT[4] = gfmul_shifted(HT[1], HT[2]);
05082         HT[5] = gfmul_shifted(HT[2], HT[2]);
05083         HT[6] = gfmul_shifted(HT[2], HT[3]);
05084         HT[7] = gfmul_shifted(HT[3], HT[3]);
05085 
05086         for (; i < nbytes/16/8; i++) {
05087                 r0 = _mm_setzero_si128();
05088                 r1 = _mm_setzero_si128();
05089 
05090             tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
05091             tmp2 = _mm_add_epi32(ctr1, ONE);
05092             tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);
05093             tmp3 = _mm_add_epi32(ctr1, TWO);
05094             tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);
05095             tmp4 = _mm_add_epi32(ctr1, THREE);
05096             tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);
05097             tmp5 = _mm_add_epi32(ctr1, FOUR);
05098             tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);
05099             tmp6 = _mm_add_epi32(ctr1, FIVE);
05100             tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);
05101             tmp7 = _mm_add_epi32(ctr1, SIX);
05102             tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);
05103             tmp8 = _mm_add_epi32(ctr1, SEVEN);
05104             tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);
05105             ctr1 = _mm_add_epi32(ctr1, EIGHT);
05106             tmp1 =_mm_xor_si128(tmp1, KEY[0]);
05107             tmp2 =_mm_xor_si128(tmp2, KEY[0]);
05108             tmp3 =_mm_xor_si128(tmp3, KEY[0]);
05109             tmp4 =_mm_xor_si128(tmp4, KEY[0]);
05110             tmp5 =_mm_xor_si128(tmp5, KEY[0]);
05111             tmp6 =_mm_xor_si128(tmp6, KEY[0]);
05112             tmp7 =_mm_xor_si128(tmp7, KEY[0]);
05113             tmp8 =_mm_xor_si128(tmp8, KEY[0]);
05114                 /* 128 x 128 Carryless Multiply */
05115                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+0]);
05116                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05117                 XV = _mm_xor_si128(XV, X);
05118                 gfmul_only(XV, HT[7], &r0, &r1);
05119             tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
05120             tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
05121             tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);
05122             tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);
05123             tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);
05124             tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);
05125             tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);
05126             tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);
05127                 /* 128 x 128 Carryless Multiply */
05128                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+1]);
05129                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05130                 gfmul_only(XV, HT[6], &r0, &r1);
05131             tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
05132             tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
05133             tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);
05134             tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);
05135             tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);
05136             tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);
05137             tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);
05138             tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);
05139                 /* 128 x 128 Carryless Multiply */
05140                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+2]);
05141                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05142                 gfmul_only(XV, HT[5], &r0, &r1);
05143             tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
05144             tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
05145             tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);
05146             tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);
05147             tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);
05148             tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);
05149             tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);
05150             tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);
05151                 /* 128 x 128 Carryless Multiply */
05152                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+3]);
05153                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05154                 gfmul_only(XV, HT[4], &r0, &r1);
05155             tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
05156             tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
05157             tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);
05158             tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);
05159             tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);
05160             tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);
05161             tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);
05162             tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);
05163                 /* 128 x 128 Carryless Multiply */
05164                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+4]);
05165                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05166                 gfmul_only(XV, HT[3], &r0, &r1);
05167             tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
05168             tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
05169             tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);
05170             tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);
05171             tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);
05172             tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);
05173             tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);
05174             tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);
05175                 /* 128 x 128 Carryless Multiply */
05176                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+5]);
05177                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05178                 gfmul_only(XV, HT[2], &r0, &r1);
05179             tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
05180             tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
05181             tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);
05182             tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);
05183             tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);
05184             tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);
05185             tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);
05186             tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);
05187                 /* 128 x 128 Carryless Multiply */
05188                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+6]);
05189                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05190                 gfmul_only(XV, HT[1], &r0, &r1);
05191             tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
05192             tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
05193             tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);
05194             tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);
05195             tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);
05196             tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);
05197             tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);
05198             tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);
05199                 /* 128 x 128 Carryless Multiply */
05200                 XV = _mm_loadu_si128(&((__m128i*)in)[i*8+7]);
05201                 XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05202                 gfmul_only(XV, HT[0], &r0, &r1);
05203             tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
05204             tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
05205             tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);
05206             tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);
05207             tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);
05208             tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);
05209             tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);
05210             tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);
05211                 /* Reduction */
05212                 X = ghash_red(r0, r1);
05213             tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
05214             tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
05215             tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);
05216             tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);
05217             tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);
05218             tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);
05219             tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);
05220             tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);
05221             lastKey = KEY[10];
05222             if (nr > 10) {
05223                 tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);
05224                 tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);
05225                 tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);
05226                 tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);
05227                 tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);
05228                 tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);
05229                 tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);
05230                 tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);
05231                 tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
05232                 tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
05233                 tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);
05234                 tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);
05235                 tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);
05236                 tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);
05237                 tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);
05238                 tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);
05239                 lastKey = KEY[12];
05240                 if (nr > 12) {
05241                     tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);
05242                     tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);
05243                     tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);
05244                     tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);
05245                     tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);
05246                     tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);
05247                     tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);
05248                     tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);
05249                     tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
05250                     tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
05251                     tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);
05252                     tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);
05253                     tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);
05254                     tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);
05255                     tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);
05256                     tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
05257                     lastKey = KEY[14];
05258                 }
05259             }
05260             AES_ENC_LAST_8();
05261         }
05262     }
05263 
05264 #endif /* AES_GCM_AESNI_NO_UNROLL */
05265 
05266     for (k = i*8; k < nbytes/16; k++) {
05267         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
05268         ctr1 = _mm_add_epi32(ctr1, ONE);
05269         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
05270         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
05271         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
05272         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
05273         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
05274         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
05275         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
05276         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
05277         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
05278         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
05279         /* 128 x 128 Carryless Multiply */
05280         XV = _mm_loadu_si128(&((__m128i*)in)[k]);
05281         XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05282         XV = _mm_xor_si128(XV, X);
05283         X = gfmul_shifted(XV, H);
05284         lastKey = KEY[10];
05285         if (nr > 10) {
05286             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
05287             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
05288             lastKey = KEY[12];
05289             if (nr > 12) {
05290                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
05291                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
05292                 lastKey = KEY[14];
05293             }
05294         }
05295         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
05296         tmp2 = _mm_loadu_si128(&((__m128i*)in)[k]);
05297         tmp1 = _mm_xor_si128(tmp1, tmp2);
05298         _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
05299     }
05300 
05301     /* If one partial block remains */
05302     if (nbytes % 16) {
05303         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
05304         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
05305         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
05306         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
05307         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
05308         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
05309         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
05310         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
05311         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
05312         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
05313         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
05314         lastKey = KEY[10];
05315         if (nr > 10) {
05316             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
05317             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
05318             lastKey = KEY[12];
05319             if (nr > 12) {
05320                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
05321                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
05322                 lastKey = KEY[14];
05323             }
05324         }
05325         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
05326         last_block = _mm_setzero_si128();
05327         for (j=0; j < nbytes%16; j++)
05328             ((unsigned char*)&last_block)[j] = in[k*16+j];
05329         XV = last_block;
05330         tmp1 = _mm_xor_si128(tmp1, last_block);
05331         last_block = tmp1;
05332         for (j=0; j < nbytes%16; j++)
05333             out[k*16+j] = ((unsigned char*)&last_block)[j];
05334         XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
05335         XV = _mm_xor_si128(XV, X);
05336         X = gfmul_shifted(XV, H);
05337     }
05338 
05339     tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
05340     tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
05341     /* 128 x 128 Carryless Multiply */
05342     X = _mm_xor_si128(X, tmp1);
05343     X = gfmul_shifted(X, H);
05344     X = _mm_shuffle_epi8(X, BSWAP_MASK);
05345     T = _mm_xor_si128(X, T);
05346 
05347 /*    if (0xffff !=
05348            _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag)))) */
05349     if (XMEMCMP(tag, &T, tbytes) != 0)
05350         *res = 0; /* in case the authentication failed */
05351     else
05352         *res = 1; /* when successful returns 1 */
05353 }
05354 
05355 #endif /* HAVE_AES_DECRYPT */
05356 #endif /* _MSC_VER */
05357 #endif /* WOLFSSL_AESNI */
05358 
05359 
05360 #if defined(GCM_SMALL)
05361 static void GMULT(byte* X, byte* Y)
05362 {
05363     byte Z[AES_BLOCK_SIZE];
05364     byte V[AES_BLOCK_SIZE];
05365     int i, j;
05366 
05367     XMEMSET(Z, 0, AES_BLOCK_SIZE);
05368     XMEMCPY(V, X, AES_BLOCK_SIZE);
05369     for (i = 0; i < AES_BLOCK_SIZE; i++)
05370     {
05371         byte y = Y[i];
05372         for (j = 0; j < 8; j++)
05373         {
05374             if (y & 0x80) {
05375                 xorbuf(Z, V, AES_BLOCK_SIZE);
05376             }
05377 
05378             RIGHTSHIFTX(V);
05379             y = y << 1;
05380         }
05381     }
05382     XMEMCPY(X, Z, AES_BLOCK_SIZE);
05383 }
05384 
05385 
05386 void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
05387     word32 cSz, byte* s, word32 sSz)
05388 {
05389     byte x[AES_BLOCK_SIZE];
05390     byte scratch[AES_BLOCK_SIZE];
05391     word32 blocks, partial;
05392     byte* h = aes->H;
05393 
05394     XMEMSET(x, 0, AES_BLOCK_SIZE);
05395 
05396     /* Hash in A, the Additional Authentication Data */
05397     if (aSz != 0 && a != NULL) {
05398         blocks = aSz / AES_BLOCK_SIZE;
05399         partial = aSz % AES_BLOCK_SIZE;
05400         while (blocks--) {
05401             xorbuf(x, a, AES_BLOCK_SIZE);
05402             GMULT(x, h);
05403             a += AES_BLOCK_SIZE;
05404         }
05405         if (partial != 0) {
05406             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
05407             XMEMCPY(scratch, a, partial);
05408             xorbuf(x, scratch, AES_BLOCK_SIZE);
05409             GMULT(x, h);
05410         }
05411     }
05412 
05413     /* Hash in C, the Ciphertext */
05414     if (cSz != 0 && c != NULL) {
05415         blocks = cSz / AES_BLOCK_SIZE;
05416         partial = cSz % AES_BLOCK_SIZE;
05417         while (blocks--) {
05418             xorbuf(x, c, AES_BLOCK_SIZE);
05419             GMULT(x, h);
05420             c += AES_BLOCK_SIZE;
05421         }
05422         if (partial != 0) {
05423             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
05424             XMEMCPY(scratch, c, partial);
05425             xorbuf(x, scratch, AES_BLOCK_SIZE);
05426             GMULT(x, h);
05427         }
05428     }
05429 
05430     /* Hash in the lengths of A and C in bits */
05431     FlattenSzInBits(&scratch[0], aSz);
05432     FlattenSzInBits(&scratch[8], cSz);
05433     xorbuf(x, scratch, AES_BLOCK_SIZE);
05434     GMULT(x, h);
05435 
05436     /* Copy the result into s. */
05437     XMEMCPY(s, x, sSz);
05438 }
05439 
05440 /* end GCM_SMALL */
05441 #elif defined(GCM_TABLE)
05442 
05443 static const byte R[256][2] = {
05444     {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
05445     {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
05446     {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
05447     {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
05448     {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
05449     {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
05450     {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
05451     {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
05452     {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
05453     {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
05454     {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
05455     {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
05456     {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
05457     {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
05458     {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
05459     {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
05460     {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
05461     {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
05462     {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
05463     {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
05464     {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
05465     {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
05466     {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
05467     {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
05468     {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
05469     {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
05470     {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
05471     {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
05472     {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
05473     {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
05474     {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
05475     {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
05476     {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
05477     {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
05478     {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
05479     {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
05480     {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
05481     {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
05482     {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
05483     {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
05484     {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
05485     {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
05486     {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
05487     {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
05488     {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
05489     {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
05490     {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
05491     {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
05492     {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
05493     {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
05494     {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
05495     {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
05496     {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
05497     {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
05498     {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
05499     {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
05500     {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
05501     {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
05502     {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
05503     {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
05504     {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
05505     {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
05506     {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
05507     {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
05508 
05509 
05510 static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
05511 {
05512     int i, j;
05513     byte Z[AES_BLOCK_SIZE];
05514     byte a;
05515 
05516     XMEMSET(Z, 0, sizeof(Z));
05517 
05518     for (i = 15; i > 0; i--) {
05519         xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
05520         a = Z[15];
05521 
05522         for (j = 15; j > 0; j--) {
05523             Z[j] = Z[j-1];
05524         }
05525 
05526         Z[0] = R[a][0];
05527         Z[1] ^= R[a][1];
05528     }
05529     xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
05530 
05531     XMEMCPY(x, Z, AES_BLOCK_SIZE);
05532 }
05533 
05534 
05535 void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
05536     word32 cSz, byte* s, word32 sSz)
05537 {
05538     byte x[AES_BLOCK_SIZE];
05539     byte scratch[AES_BLOCK_SIZE];
05540     word32 blocks, partial;
05541 
05542     XMEMSET(x, 0, AES_BLOCK_SIZE);
05543 
05544     /* Hash in A, the Additional Authentication Data */
05545     if (aSz != 0 && a != NULL) {
05546         blocks = aSz / AES_BLOCK_SIZE;
05547         partial = aSz % AES_BLOCK_SIZE;
05548         while (blocks--) {
05549             xorbuf(x, a, AES_BLOCK_SIZE);
05550             GMULT(x, aes->M0);
05551             a += AES_BLOCK_SIZE;
05552         }
05553         if (partial != 0) {
05554             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
05555             XMEMCPY(scratch, a, partial);
05556             xorbuf(x, scratch, AES_BLOCK_SIZE);
05557             GMULT(x, aes->M0);
05558         }
05559     }
05560 
05561     /* Hash in C, the Ciphertext */
05562     if (cSz != 0 && c != NULL) {
05563         blocks = cSz / AES_BLOCK_SIZE;
05564         partial = cSz % AES_BLOCK_SIZE;
05565         while (blocks--) {
05566             xorbuf(x, c, AES_BLOCK_SIZE);
05567             GMULT(x, aes->M0);
05568             c += AES_BLOCK_SIZE;
05569         }
05570         if (partial != 0) {
05571             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
05572             XMEMCPY(scratch, c, partial);
05573             xorbuf(x, scratch, AES_BLOCK_SIZE);
05574             GMULT(x, aes->M0);
05575         }
05576     }
05577 
05578     /* Hash in the lengths of A and C in bits */
05579     FlattenSzInBits(&scratch[0], aSz);
05580     FlattenSzInBits(&scratch[8], cSz);
05581     xorbuf(x, scratch, AES_BLOCK_SIZE);
05582     GMULT(x, aes->M0);
05583 
05584     /* Copy the result into s. */
05585     XMEMCPY(s, x, sSz);
05586 }
05587 
05588 /* end GCM_TABLE */
05589 #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
05590 
05591 #if !defined(FREESCALE_LTC_AES_GCM)
05592 static void GMULT(word64* X, word64* Y)
05593 {
05594     word64 Z[2] = {0,0};
05595     word64 V[2];
05596     int i, j;
05597     V[0] = X[0];  V[1] = X[1];
05598 
05599     for (i = 0; i < 2; i++)
05600     {
05601         word64 y = Y[i];
05602         for (j = 0; j < 64; j++)
05603         {
05604             if (y & 0x8000000000000000ULL) {
05605                 Z[0] ^= V[0];
05606                 Z[1] ^= V[1];
05607             }
05608 
05609             if (V[1] & 0x0000000000000001) {
05610                 V[1] >>= 1;
05611                 V[1] |= ((V[0] & 0x0000000000000001) ?
05612                     0x8000000000000000ULL : 0);
05613                 V[0] >>= 1;
05614                 V[0] ^= 0xE100000000000000ULL;
05615             }
05616             else {
05617                 V[1] >>= 1;
05618                 V[1] |= ((V[0] & 0x0000000000000001) ?
05619                     0x8000000000000000ULL : 0);
05620                 V[0] >>= 1;
05621             }
05622             y <<= 1;
05623         }
05624     }
05625     X[0] = Z[0];
05626     X[1] = Z[1];
05627 }
05628 
05629 
05630 void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
05631     word32 cSz, byte* s, word32 sSz)
05632 {
05633     word64 x[2] = {0,0};
05634     word32 blocks, partial;
05635     word64 bigH[2];
05636 
05637     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
05638     #ifdef LITTLE_ENDIAN_ORDER
05639         ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);
05640     #endif
05641 
05642     /* Hash in A, the Additional Authentication Data */
05643     if (aSz != 0 && a != NULL) {
05644         word64 bigA[2];
05645         blocks = aSz / AES_BLOCK_SIZE;
05646         partial = aSz % AES_BLOCK_SIZE;
05647         while (blocks--) {
05648             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
05649             #ifdef LITTLE_ENDIAN_ORDER
05650                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
05651             #endif
05652             x[0] ^= bigA[0];
05653             x[1] ^= bigA[1];
05654             GMULT(x, bigH);
05655             a += AES_BLOCK_SIZE;
05656         }
05657         if (partial != 0) {
05658             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
05659             XMEMCPY(bigA, a, partial);
05660             #ifdef LITTLE_ENDIAN_ORDER
05661                 ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
05662             #endif
05663             x[0] ^= bigA[0];
05664             x[1] ^= bigA[1];
05665             GMULT(x, bigH);
05666         }
05667 #ifdef OPENSSL_EXTRA
05668         /* store AAD partial tag for next call */
05669         aes->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000) >> 32);
05670         aes->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
05671         aes->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000) >> 32);
05672         aes->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
05673 #endif
05674     }
05675 
05676     /* Hash in C, the Ciphertext */
05677     if (cSz != 0 && c != NULL) {
05678         word64 bigC[2];
05679         blocks = cSz / AES_BLOCK_SIZE;
05680         partial = cSz % AES_BLOCK_SIZE;
05681 #ifdef OPENSSL_EXTRA
05682         /* Start from last AAD partial tag */
05683         if(aes->aadLen) {
05684             x[0] = ((word64)aes->aadH[0]) << 32 | aes->aadH[1];
05685             x[1] = ((word64)aes->aadH[2]) << 32 | aes->aadH[3];
05686          }
05687 #endif
05688         while (blocks--) {
05689             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
05690             #ifdef LITTLE_ENDIAN_ORDER
05691                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
05692             #endif
05693             x[0] ^= bigC[0];
05694             x[1] ^= bigC[1];
05695             GMULT(x, bigH);
05696             c += AES_BLOCK_SIZE;
05697         }
05698         if (partial != 0) {
05699             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
05700             XMEMCPY(bigC, c, partial);
05701             #ifdef LITTLE_ENDIAN_ORDER
05702                 ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
05703             #endif
05704             x[0] ^= bigC[0];
05705             x[1] ^= bigC[1];
05706             GMULT(x, bigH);
05707         }
05708     }
05709 
05710     /* Hash in the lengths in bits of A and C */
05711     {
05712         word64 len[2];
05713         len[0] = aSz; len[1] = cSz;
05714 #ifdef OPENSSL_EXTRA
05715         if (aes->aadLen)
05716             len[0] = (word64)aes->aadLen;
05717 #endif
05718         /* Lengths are in bytes. Convert to bits. */
05719         len[0] *= 8;
05720         len[1] *= 8;
05721 
05722         x[0] ^= len[0];
05723         x[1] ^= len[1];
05724         GMULT(x, bigH);
05725     }
05726     #ifdef LITTLE_ENDIAN_ORDER
05727         ByteReverseWords64(x, x, AES_BLOCK_SIZE);
05728     #endif
05729     XMEMCPY(s, x, sSz);
05730 }
05731 #endif /* !FREESCALE_LTC_AES_GCM */
05732 
05733 /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
05734 #else /* GCM_WORD32 */
05735 
05736 static void GMULT(word32* X, word32* Y)
05737 {
05738     word32 Z[4] = {0,0,0,0};
05739     word32 V[4];
05740     int i, j;
05741 
05742     V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
05743 
05744     for (i = 0; i < 4; i++)
05745     {
05746         word32 y = Y[i];
05747         for (j = 0; j < 32; j++)
05748         {
05749             if (y & 0x80000000) {
05750                 Z[0] ^= V[0];
05751                 Z[1] ^= V[1];
05752                 Z[2] ^= V[2];
05753                 Z[3] ^= V[3];
05754             }
05755 
05756             if (V[3] & 0x00000001) {
05757                 V[3] >>= 1;
05758                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
05759                 V[2] >>= 1;
05760                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
05761                 V[1] >>= 1;
05762                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
05763                 V[0] >>= 1;
05764                 V[0] ^= 0xE1000000;
05765             } else {
05766                 V[3] >>= 1;
05767                 V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
05768                 V[2] >>= 1;
05769                 V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
05770                 V[1] >>= 1;
05771                 V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
05772                 V[0] >>= 1;
05773             }
05774             y <<= 1;
05775         }
05776     }
05777     X[0] = Z[0];
05778     X[1] = Z[1];
05779     X[2] = Z[2];
05780     X[3] = Z[3];
05781 }
05782 
05783 
05784 void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
05785     word32 cSz, byte* s, word32 sSz)
05786 {
05787     word32 x[4] = {0,0,0,0};
05788     word32 blocks, partial;
05789     word32 bigH[4];
05790 
05791     XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
05792     #ifdef LITTLE_ENDIAN_ORDER
05793         ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
05794     #endif
05795 
05796     /* Hash in A, the Additional Authentication Data */
05797     if (aSz != 0 && a != NULL) {
05798         word32 bigA[4];
05799         blocks = aSz / AES_BLOCK_SIZE;
05800         partial = aSz % AES_BLOCK_SIZE;
05801         while (blocks--) {
05802             XMEMCPY(bigA, a, AES_BLOCK_SIZE);
05803             #ifdef LITTLE_ENDIAN_ORDER
05804                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
05805             #endif
05806             x[0] ^= bigA[0];
05807             x[1] ^= bigA[1];
05808             x[2] ^= bigA[2];
05809             x[3] ^= bigA[3];
05810             GMULT(x, bigH);
05811             a += AES_BLOCK_SIZE;
05812         }
05813         if (partial != 0) {
05814             XMEMSET(bigA, 0, AES_BLOCK_SIZE);
05815             XMEMCPY(bigA, a, partial);
05816             #ifdef LITTLE_ENDIAN_ORDER
05817                 ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
05818             #endif
05819             x[0] ^= bigA[0];
05820             x[1] ^= bigA[1];
05821             x[2] ^= bigA[2];
05822             x[3] ^= bigA[3];
05823             GMULT(x, bigH);
05824         }
05825     }
05826 
05827     /* Hash in C, the Ciphertext */
05828     if (cSz != 0 && c != NULL) {
05829         word32 bigC[4];
05830         blocks = cSz / AES_BLOCK_SIZE;
05831         partial = cSz % AES_BLOCK_SIZE;
05832         while (blocks--) {
05833             XMEMCPY(bigC, c, AES_BLOCK_SIZE);
05834             #ifdef LITTLE_ENDIAN_ORDER
05835                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
05836             #endif
05837             x[0] ^= bigC[0];
05838             x[1] ^= bigC[1];
05839             x[2] ^= bigC[2];
05840             x[3] ^= bigC[3];
05841             GMULT(x, bigH);
05842             c += AES_BLOCK_SIZE;
05843         }
05844         if (partial != 0) {
05845             XMEMSET(bigC, 0, AES_BLOCK_SIZE);
05846             XMEMCPY(bigC, c, partial);
05847             #ifdef LITTLE_ENDIAN_ORDER
05848                 ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
05849             #endif
05850             x[0] ^= bigC[0];
05851             x[1] ^= bigC[1];
05852             x[2] ^= bigC[2];
05853             x[3] ^= bigC[3];
05854             GMULT(x, bigH);
05855         }
05856     }
05857 
05858     /* Hash in the lengths in bits of A and C */
05859     {
05860         word32 len[4];
05861 
05862         /* Lengths are in bytes. Convert to bits. */
05863         len[0] = (aSz >> (8*sizeof(aSz) - 3));
05864         len[1] = aSz << 3;
05865         len[2] = (cSz >> (8*sizeof(cSz) - 3));
05866         len[3] = cSz << 3;
05867 
05868         x[0] ^= len[0];
05869         x[1] ^= len[1];
05870         x[2] ^= len[2];
05871         x[3] ^= len[3];
05872         GMULT(x, bigH);
05873     }
05874     #ifdef LITTLE_ENDIAN_ORDER
05875         ByteReverseWords(x, x, AES_BLOCK_SIZE);
05876     #endif
05877     XMEMCPY(s, x, sSz);
05878 }
05879 
05880 #endif /* end GCM_WORD32 */
05881 
05882 
05883 #if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
05884 #ifdef FREESCALE_LTC_AES_GCM
05885 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
05886                    const byte* iv, word32 ivSz,
05887                    byte* authTag, word32 authTagSz,
05888                    const byte* authIn, word32 authInSz)
05889 {
05890     status_t status;
05891     word32 keySize;
05892 
05893     /* argument checks */
05894     if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
05895         return BAD_FUNC_ARG;
05896     }
05897 
05898     if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
05899         WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
05900         return BAD_FUNC_ARG;
05901     }
05902 
05903     status = wc_AesGetKeySize(aes, &keySize);
05904     if (status)
05905         return status;
05906 
05907     status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
05908         authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
05909 
05910     return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
05911 }
05912 
05913 #else
05914 
05915 #ifdef STM32_CRYPTO_AES_GCM
05916 
05917 /* this function supports inline encrypt */
05918 static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz,
05919                                   const byte* iv, word32 ivSz,
05920                                   byte* authTag, word32 authTagSz,
05921                                   const byte* authIn, word32 authInSz)
05922 {
05923     int ret;
05924 #ifdef WOLFSSL_STM32_CUBEMX
05925     CRYP_HandleTypeDef hcryp;
05926 #else
05927     word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
05928 #endif
05929     word32 keySize;
05930     int status = HAL_OK;
05931     word32 blocks = sz / AES_BLOCK_SIZE;
05932     word32 partial = sz % AES_BLOCK_SIZE;
05933     byte tag[AES_BLOCK_SIZE];
05934     byte partialBlock[AES_BLOCK_SIZE];
05935     byte ctr[AES_BLOCK_SIZE];
05936     byte* authInPadded = NULL;
05937     int authPadSz;
05938 
05939     ret = wc_AesGetKeySize(aes, &keySize);
05940     if (ret != 0)
05941         return ret;
05942 
05943 #ifdef WOLFSSL_STM32_CUBEMX
05944     ret = wc_Stm32_Aes_Init(aes, &hcryp);
05945     if (ret != 0)
05946         return ret;
05947 #endif
05948 
05949     ret = wolfSSL_CryptHwMutexLock();
05950     if (ret != 0) {
05951         return ret;
05952     }
05953 
05954     XMEMSET(ctr, 0, AES_BLOCK_SIZE);
05955     if (ivSz == GCM_NONCE_MID_SZ) {
05956         XMEMCPY(ctr, iv, ivSz);
05957         ctr[AES_BLOCK_SIZE - 1] = 1;
05958     }
05959     else {
05960         GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);
05961     }
05962     /* Hardware requires counter + 1 */
05963     IncrementGcmCounter(ctr);
05964 
05965     if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
05966         /* Need to pad the AAD to a full block with zeros. */
05967         authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
05968         authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
05969             DYNAMIC_TYPE_TMP_BUFFER);
05970         if (authInPadded == NULL) {
05971             wolfSSL_CryptHwMutexUnLock();
05972             return MEMORY_E;
05973         }
05974         XMEMSET(authInPadded, 0, authPadSz);
05975         XMEMCPY(authInPadded, authIn, authInSz);
05976     } else {
05977         authPadSz = authInSz;
05978         authInPadded = (byte*)authIn;
05979     }
05980 
05981 #ifdef WOLFSSL_STM32_CUBEMX
05982     hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
05983     hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
05984     hcryp.Init.HeaderSize = authInSz;
05985 
05986 #ifdef STM32_CRYPTO_AES_ONLY
05987     /* Set the CRYP parameters */
05988     hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
05989     hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
05990     hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
05991     HAL_CRYP_Init(&hcryp);
05992 
05993     /* GCM init phase */
05994     status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
05995     if (status == HAL_OK) {
05996         /* GCM header phase */
05997         hcryp.Init.GCMCMACPhase  = CRYP_HEADER_PHASE;
05998         status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
05999     }
06000     if (status == HAL_OK) {
06001         /* GCM payload phase - blocks */
06002         hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;
06003         if (blocks) {
06004             status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
06005                 (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
06006         }
06007     }
06008     if (status == HAL_OK && (partial != 0 || blocks == 0)) {
06009         /* GCM payload phase - partial remainder */
06010         XMEMSET(partialBlock, 0, sizeof(partialBlock));
06011         XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
06012         status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,
06013             partialBlock, STM32_HAL_TIMEOUT);
06014         XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
06015     }
06016     if (status == HAL_OK) {
06017         /* GCM final phase */
06018         hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
06019         status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);
06020     }
06021 #elif defined(STM32_HAL_V2)
06022     hcryp.Init.Algorithm  = CRYP_AES_GCM;
06023     ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);
06024     hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;
06025     HAL_CRYP_Init(&hcryp);
06026 
06027     /* GCM payload phase - can handle partial blocks */
06028     status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
06029         (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
06030     if (status == HAL_OK) {
06031         /* Compute the authTag */
06032         status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
06033             STM32_HAL_TIMEOUT);
06034     }
06035 #else
06036     HAL_CRYP_Init(&hcryp);
06037     if (blocks) {
06038         /* GCM payload phase - blocks */
06039         status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
06040             (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
06041     }
06042     if (status == HAL_OK && (partial != 0 || blocks == 0)) {
06043         /* GCM payload phase - partial remainder */
06044         XMEMSET(partialBlock, 0, sizeof(partialBlock));
06045         XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
06046         status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, partialBlock, partial,
06047             partialBlock, STM32_HAL_TIMEOUT);
06048         XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
06049     }
06050     if (status == HAL_OK) {
06051         /* Compute the authTag */
06052         status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
06053     }
06054 #endif
06055 
06056     if (status != HAL_OK)
06057         ret = AES_GCM_AUTH_E;
06058     HAL_CRYP_DeInit(&hcryp);
06059 
06060 #else /* STD_PERI_LIB */
06061     ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
06062     status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
06063                          (uint8_t*)keyCopy,      keySize * 8,
06064                          (uint8_t*)in,           sz,
06065                          (uint8_t*)authInPadded, authInSz,
06066                          (uint8_t*)out,          tag);
06067     if (status != SUCCESS)
06068         ret = AES_GCM_AUTH_E;
06069 #endif /* WOLFSSL_STM32_CUBEMX */
06070 
06071     if (ret == 0) {
06072         /* return authTag */
06073         if (authTag) {
06074             /* STM32 GCM won't compute Auth correctly for partial or
06075                 when IV != 12, so use software here */
06076             if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) {
06077                 DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */
06078                 GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
06079                 wc_AesEncrypt(aes, ctr, tag);
06080                 xorbuf(authTag, tag, authTagSz);
06081             }
06082             else {
06083                 XMEMCPY(authTag, tag, authTagSz);
06084             }
06085         }
06086     }
06087 
06088     /* Free memory if not a multiple of AES_BLOCK_SZ */
06089     if (authInPadded != authIn) {
06090         XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
06091     }
06092 
06093     wolfSSL_CryptHwMutexUnLock();
06094 
06095     return ret;
06096 }
06097 
06098 #endif /* STM32_CRYPTO_AES_GCM */
06099 
06100 #ifdef WOLFSSL_AESNI
06101 int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
06102                       const byte* iv, word32 ivSz,
06103                       byte* authTag, word32 authTagSz,
06104                       const byte* authIn, word32 authInSz);
06105 #else
06106 static
06107 #endif
06108 int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
06109                       const byte* iv, word32 ivSz,
06110                       byte* authTag, word32 authTagSz,
06111                       const byte* authIn, word32 authInSz)
06112 {
06113     int ret = 0;
06114     word32 blocks = sz / AES_BLOCK_SIZE;
06115     word32 partial = sz % AES_BLOCK_SIZE;
06116     const byte* p = in;
06117     byte* c = out;
06118     byte counter[AES_BLOCK_SIZE];
06119     byte initialCounter[AES_BLOCK_SIZE];
06120     byte *ctr;
06121     byte scratch[AES_BLOCK_SIZE];
06122 #ifdef OPENSSL_EXTRA
06123     word32 aadTemp;
06124 #endif
06125     ctr = counter;
06126     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
06127     XMEMSET(scratch, 0, AES_BLOCK_SIZE);
06128     if (ivSz == GCM_NONCE_MID_SZ) {
06129         XMEMCPY(initialCounter, iv, ivSz);
06130         initialCounter[AES_BLOCK_SIZE - 1] = 1;
06131     }
06132     else {
06133 #ifdef OPENSSL_EXTRA
06134         aadTemp = aes->aadLen;
06135         aes->aadLen = 0;
06136 #endif
06137         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
06138 #ifdef OPENSSL_EXTRA
06139         aes->aadLen = aadTemp;
06140 #endif
06141     }
06142     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
06143 
06144 #ifdef WOLFSSL_PIC32MZ_CRYPT
06145     if (blocks) {
06146         /* use initial IV for HW, but don't use it below */
06147         XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
06148 
06149         ret = wc_Pic32AesCrypt(
06150             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
06151             out, in, (blocks * AES_BLOCK_SIZE),
06152             PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
06153         if (ret != 0)
06154             return ret;
06155     }
06156     /* process remainder using partial handling */
06157 #endif
06158 
06159 #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
06160     /* some hardware acceleration can gain performance from doing AES encryption
06161      * of the whole buffer at once */
06162     if (c != p && blocks > 0) { /* can not handle inline encryption */
06163         while (blocks--) {
06164             IncrementGcmCounter(ctr);
06165             XMEMCPY(c, ctr, AES_BLOCK_SIZE);
06166             c += AES_BLOCK_SIZE;
06167         }
06168 
06169         /* reset number of blocks and then do encryption */
06170         blocks = sz / AES_BLOCK_SIZE;
06171         wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
06172         xorbuf(out, p, AES_BLOCK_SIZE * blocks);
06173         p += AES_BLOCK_SIZE * blocks;
06174     }
06175     else
06176 #endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
06177 
06178     while (blocks--) {
06179         IncrementGcmCounter(ctr);
06180     #if !defined(WOLFSSL_PIC32MZ_CRYPT)
06181         wc_AesEncrypt(aes, ctr, scratch);
06182         xorbuf(scratch, p, AES_BLOCK_SIZE);
06183         XMEMCPY(c, scratch, AES_BLOCK_SIZE);
06184     #endif
06185         p += AES_BLOCK_SIZE;
06186         c += AES_BLOCK_SIZE;
06187     }
06188 
06189     if (partial != 0) {
06190         IncrementGcmCounter(ctr);
06191         wc_AesEncrypt(aes, ctr, scratch);
06192         xorbuf(scratch, p, partial);
06193         XMEMCPY(c, scratch, partial);
06194     }
06195     if (authTag) {
06196         GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
06197         wc_AesEncrypt(aes, initialCounter, scratch);
06198         xorbuf(authTag, scratch, authTagSz);
06199 #ifdef OPENSSL_EXTRA
06200         if (!in && !sz)
06201             /* store AAD size for next call */
06202             aes->aadLen = authInSz;
06203 #endif
06204     }
06205 
06206     return ret;
06207 }
06208 
06209 /* Software AES - GCM Encrypt */
06210 int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
06211                    const byte* iv, word32 ivSz,
06212                    byte* authTag, word32 authTagSz,
06213                    const byte* authIn, word32 authInSz)
06214 {
06215     /* argument checks */
06216     if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
06217         return BAD_FUNC_ARG;
06218     }
06219 
06220     if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
06221         WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
06222         return BAD_FUNC_ARG;
06223     }
06224 
06225 #ifdef WOLF_CRYPTO_CB
06226     if (aes->devId != INVALID_DEVID) {
06227         int ret = wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz,
06228             authTag, authTagSz, authIn, authInSz);
06229         if (ret != CRYPTOCB_UNAVAILABLE)
06230             return ret;
06231         /* fall-through when unavailable */
06232     }
06233 #endif
06234 
06235 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
06236     /* if async and byte count above threshold */
06237     /* only 12-byte IV is supported in HW */
06238     if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
06239                     sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
06240     #if defined(HAVE_CAVIUM)
06241         #ifdef HAVE_CAVIUM_V
06242         if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
06243             return NitroxAesGcmEncrypt(aes, out, in, sz,
06244                 (const byte*)aes->devKey, aes->keylen, iv, ivSz,
06245                 authTag, authTagSz, authIn, authInSz);
06246         }
06247         #endif
06248     #elif defined(HAVE_INTEL_QA)
06249         return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
06250             (const byte*)aes->devKey, aes->keylen, iv, ivSz,
06251             authTag, authTagSz, authIn, authInSz);
06252     #else /* WOLFSSL_ASYNC_CRYPT_TEST */
06253         if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_ENCRYPT)) {
06254             WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
06255             testDev->aes.aes = aes;
06256             testDev->aes.out = out;
06257             testDev->aes.in = in;
06258             testDev->aes.sz = sz;
06259             testDev->aes.iv = iv;
06260             testDev->aes.ivSz = ivSz;
06261             testDev->aes.authTag = authTag;
06262             testDev->aes.authTagSz = authTagSz;
06263             testDev->aes.authIn = authIn;
06264             testDev->aes.authInSz = authInSz;
06265             return WC_PENDING_E;
06266         }
06267     #endif
06268     }
06269 #endif /* WOLFSSL_ASYNC_CRYPT */
06270 
06271 #ifdef STM32_CRYPTO_AES_GCM
06272     /* The STM standard peripheral library API's doesn't support partial blocks */
06273     #ifdef STD_PERI_LIB
06274     if (partial == 0)
06275     #endif
06276     {
06277         return wc_AesGcmEncrypt_STM32(
06278             aes, out, in, sz, iv, ivSz,
06279             authTag, authTagSz, authIn, authInSz);
06280     }
06281 #endif /* STM32_CRYPTO_AES_GCM */
06282 
06283 #ifdef WOLFSSL_AESNI
06284     #ifdef HAVE_INTEL_AVX2
06285     if (IS_INTEL_AVX2(intel_flags)) {
06286         AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06287                                  authTagSz, (const byte*)aes->key, aes->rounds);
06288         return 0;
06289     }
06290     else
06291     #endif
06292     #ifdef HAVE_INTEL_AVX1
06293     if (IS_INTEL_AVX1(intel_flags)) {
06294         AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06295                                  authTagSz, (const byte*)aes->key, aes->rounds);
06296         return 0;
06297     }
06298     else
06299     #endif
06300     if (haveAESNI) {
06301         AES_GCM_encrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06302                                  authTagSz, (const byte*)aes->key, aes->rounds);
06303         return 0;
06304     }
06305     else
06306 #endif
06307     {
06308         return AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
06309                                                               authIn, authInSz);
06310     }
06311 }
06312 #endif
06313 
06314 
06315 
06316 /* AES GCM Decrypt */
06317 #if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
06318 #ifdef FREESCALE_LTC_AES_GCM
06319 int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
06320                    const byte* iv, word32 ivSz,
06321                    const byte* authTag, word32 authTagSz,
06322                    const byte* authIn, word32 authInSz)
06323 {
06324     int ret;
06325     word32 keySize;
06326     status_t status;
06327 
06328     /* argument checks */
06329     /* If the sz is non-zero, both in and out must be set. If sz is 0,
06330      * in and out are don't cares, as this is is the GMAC case. */
06331     if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
06332         authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
06333         ivSz == 0) {
06334 
06335         return BAD_FUNC_ARG;
06336     }
06337 
06338     ret = wc_AesGetKeySize(aes, &keySize);
06339     if (ret != 0) {
06340         return ret;
06341     }
06342 
06343     status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
06344         authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
06345 
06346     return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
06347 }
06348 
06349 #else
06350 
06351 #ifdef STM32_CRYPTO_AES_GCM
06352 /* this function supports inline decrypt */
06353 static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
06354                                   const byte* in, word32 sz,
06355                                   const byte* iv, word32 ivSz,
06356                                   const byte* authTag, word32 authTagSz,
06357                                   const byte* authIn, word32 authInSz)
06358 {
06359     int ret;
06360 #ifdef WOLFSSL_STM32_CUBEMX
06361     CRYP_HandleTypeDef hcryp;
06362 #else
06363     word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
06364 #endif
06365     word32 keySize;
06366     int status = HAL_OK;
06367     word32 blocks = sz / AES_BLOCK_SIZE;
06368     word32 partial = sz % AES_BLOCK_SIZE;
06369     byte tag[AES_BLOCK_SIZE];
06370     byte partialBlock[AES_BLOCK_SIZE];
06371     byte ctr[AES_BLOCK_SIZE];
06372     byte* authInPadded = NULL;
06373     int authPadSz;
06374 
06375     ret = wc_AesGetKeySize(aes, &keySize);
06376     if (ret != 0)
06377         return ret;
06378 
06379 #ifdef WOLFSSL_STM32_CUBEMX
06380     ret = wc_Stm32_Aes_Init(aes, &hcryp);
06381     if (ret != 0)
06382         return ret;
06383 #endif
06384 
06385     ret = wolfSSL_CryptHwMutexLock();
06386     if (ret != 0) {
06387         return ret;
06388     }
06389 
06390     XMEMSET(ctr, 0, AES_BLOCK_SIZE);
06391     if (ivSz == GCM_NONCE_MID_SZ) {
06392         XMEMCPY(ctr, iv, ivSz);
06393         ctr[AES_BLOCK_SIZE - 1] = 1;
06394     }
06395     else {
06396         GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);
06397     }
06398     /* Hardware requires counter + 1 */
06399     IncrementGcmCounter(ctr);
06400 
06401     if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
06402         /* Need to pad the AAD to a full block with zeros. */
06403         authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
06404         authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
06405             DYNAMIC_TYPE_TMP_BUFFER);
06406         if (authInPadded == NULL) {
06407             wolfSSL_CryptHwMutexUnLock();
06408             return MEMORY_E;
06409         }
06410         XMEMSET(authInPadded, 0, authPadSz);
06411         XMEMCPY(authInPadded, authIn, authInSz);
06412     } else {
06413         authPadSz = authInSz;
06414         authInPadded = (byte*)authIn;
06415     }
06416 
06417 #ifdef WOLFSSL_STM32_CUBEMX
06418     hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
06419     hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
06420     hcryp.Init.HeaderSize = authInSz;
06421 
06422 #ifdef STM32_CRYPTO_AES_ONLY
06423     /* Set the CRYP parameters */
06424     hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
06425     hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
06426     hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
06427     HAL_CRYP_Init(&hcryp);
06428 
06429     /* GCM init phase */
06430     status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
06431     if (status == HAL_OK) {
06432         /* GCM header phase */
06433         hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
06434         status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
06435     }
06436     if (status == HAL_OK) {
06437         /* GCM payload phase - blocks */
06438         hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;
06439         if (blocks) {
06440             status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
06441                 (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
06442         }
06443     }
06444     if (status == HAL_OK && (partial != 0 || blocks == 0)) {
06445         /* GCM payload phase - partial remainder */
06446         XMEMSET(partialBlock, 0, sizeof(partialBlock));
06447         XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
06448         status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,
06449             partialBlock, STM32_HAL_TIMEOUT);
06450         XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
06451     }
06452     if (status == HAL_OK) {
06453         /* GCM final phase */
06454         hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
06455         status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);
06456     }
06457 #elif defined(STM32_HAL_V2)
06458     hcryp.Init.Algorithm = CRYP_AES_GCM;
06459     ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);
06460     hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;
06461     HAL_CRYP_Init(&hcryp);
06462 
06463     /* GCM payload phase - can handle partial blocks */
06464     status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
06465         (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
06466     if (status == HAL_OK) {
06467         /* Compute the authTag */
06468         status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
06469             STM32_HAL_TIMEOUT);
06470     }
06471 #else
06472     HAL_CRYP_Init(&hcryp);
06473     if (blocks) {
06474         /* GCM payload phase - blocks */
06475         status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
06476             (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
06477     }
06478     if (status == HAL_OK && (partial != 0 || blocks == 0)) {
06479         /* GCM payload phase - partial remainder */
06480         XMEMSET(partialBlock, 0, sizeof(partialBlock));
06481         XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
06482         status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, partialBlock, partial,
06483             partialBlock, STM32_HAL_TIMEOUT);
06484         XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
06485     }
06486     if (status == HAL_OK) {
06487         /* Compute the authTag */
06488         status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
06489     }
06490 #endif
06491 
06492     if (status != HAL_OK)
06493         ret = AES_GCM_AUTH_E;
06494 
06495     HAL_CRYP_DeInit(&hcryp);
06496 
06497 #else /* STD_PERI_LIB */
06498     ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
06499 
06500     /* Input size and auth size need to be the actual sizes, even though
06501      * they are not block aligned, because this length (in bits) is used
06502      * in the final GHASH. */
06503     status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
06504                          (uint8_t*)keyCopy,      keySize * 8,
06505                          (uint8_t*)in,           sz,
06506                          (uint8_t*)authInPadded, authInSz,
06507                          (uint8_t*)out,          tag);
06508     if (status != SUCCESS)
06509         ret = AES_GCM_AUTH_E;
06510 #endif /* WOLFSSL_STM32_CUBEMX */
06511 
06512     /* STM32 GCM hardware only supports IV of 12 bytes, so use software for auth */
06513     if (sz == 0 || ivSz != GCM_NONCE_MID_SZ) {
06514         DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */
06515         GHASH(aes, authIn, authInSz, in, sz, tag, sizeof(tag));
06516         wc_AesEncrypt(aes, ctr, partialBlock);
06517         xorbuf(tag, partialBlock, sizeof(tag));
06518     }
06519 
06520     if (ConstantCompare(authTag, tag, authTagSz) != 0) {
06521         ret = AES_GCM_AUTH_E;
06522     }
06523 
06524     /* Free memory if not a multiple of AES_BLOCK_SZ */
06525     if (authInPadded != authIn) {
06526         XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
06527     }
06528 
06529     wolfSSL_CryptHwMutexUnLock();
06530 
06531     return ret;
06532 }
06533 
06534 #endif /* STM32_CRYPTO_AES_GCM */
06535 
06536 #ifdef WOLFSSL_AESNI
06537 int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
06538                       const byte* iv, word32 ivSz,
06539                       const byte* authTag, word32 authTagSz,
06540                       const byte* authIn, word32 authInSz);
06541 #else
06542 static
06543 #endif
06544 int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
06545                       const byte* iv, word32 ivSz,
06546                       const byte* authTag, word32 authTagSz,
06547                       const byte* authIn, word32 authInSz)
06548 {
06549     int ret = 0;
06550     word32 blocks = sz / AES_BLOCK_SIZE;
06551     word32 partial = sz % AES_BLOCK_SIZE;
06552     const byte* c = in;
06553     byte* p = out;
06554     byte counter[AES_BLOCK_SIZE];
06555     byte initialCounter[AES_BLOCK_SIZE];
06556     byte *ctr;
06557     byte scratch[AES_BLOCK_SIZE];
06558     byte Tprime[AES_BLOCK_SIZE];
06559     byte EKY0[AES_BLOCK_SIZE];
06560 #ifdef OPENSSL_EXTRA
06561     word32 aadTemp;
06562 #endif
06563     ctr = counter;
06564     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
06565     if (ivSz == GCM_NONCE_MID_SZ) {
06566         XMEMCPY(initialCounter, iv, ivSz);
06567         initialCounter[AES_BLOCK_SIZE - 1] = 1;
06568     }
06569     else {
06570 #ifdef OPENSSL_EXTRA
06571         aadTemp = aes->aadLen;
06572         aes->aadLen = 0;
06573 #endif
06574         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
06575 #ifdef OPENSSL_EXTRA
06576         aes->aadLen = aadTemp;
06577 #endif
06578     }
06579     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
06580 
06581     /* Calc the authTag again using the received auth data and the cipher text */
06582     GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
06583     wc_AesEncrypt(aes, ctr, EKY0);
06584     xorbuf(Tprime, EKY0, sizeof(Tprime));
06585 
06586 #ifdef OPENSSL_EXTRA
06587     if (!out) {
06588         /* authenticated, non-confidential data */
06589         /* store AAD size for next call */
06590         aes->aadLen = authInSz;
06591     }
06592 #endif
06593     if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
06594         return AES_GCM_AUTH_E;
06595     }
06596 
06597 #if defined(WOLFSSL_PIC32MZ_CRYPT)
06598     if (blocks) {
06599         /* use initial IV for HW, but don't use it below */
06600         XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
06601 
06602         ret = wc_Pic32AesCrypt(
06603             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
06604             out, in, (blocks * AES_BLOCK_SIZE),
06605             PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
06606         if (ret != 0)
06607             return ret;
06608     }
06609     /* process remainder using partial handling */
06610 #endif
06611 
06612 #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
06613     /* some hardware acceleration can gain performance from doing AES encryption
06614      * of the whole buffer at once */
06615     if (c != p && blocks > 0) { /* can not handle inline decryption */
06616         while (blocks--) {
06617             IncrementGcmCounter(ctr);
06618             XMEMCPY(p, ctr, AES_BLOCK_SIZE);
06619             p += AES_BLOCK_SIZE;
06620         }
06621 
06622         /* reset number of blocks and then do encryption */
06623         blocks = sz / AES_BLOCK_SIZE;
06624 
06625         wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
06626         xorbuf(out, c, AES_BLOCK_SIZE * blocks);
06627         c += AES_BLOCK_SIZE * blocks;
06628     }
06629     else
06630 #endif /* HAVE_AES_ECB && !PIC32MZ */
06631     while (blocks--) {
06632         IncrementGcmCounter(ctr);
06633     #if !defined(WOLFSSL_PIC32MZ_CRYPT)
06634         wc_AesEncrypt(aes, ctr, scratch);
06635         xorbuf(scratch, c, AES_BLOCK_SIZE);
06636         XMEMCPY(p, scratch, AES_BLOCK_SIZE);
06637     #endif
06638         p += AES_BLOCK_SIZE;
06639         c += AES_BLOCK_SIZE;
06640     }
06641 
06642     if (partial != 0) {
06643         IncrementGcmCounter(ctr);
06644         wc_AesEncrypt(aes, ctr, scratch);
06645         xorbuf(scratch, c, partial);
06646         XMEMCPY(p, scratch, partial);
06647     }
06648 
06649     return ret;
06650 }
06651 
06652 /* Software AES - GCM Decrypt */
06653 int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
06654                      const byte* iv, word32 ivSz,
06655                      const byte* authTag, word32 authTagSz,
06656                      const byte* authIn, word32 authInSz)
06657 {
06658 #ifdef WOLFSSL_AESNI
06659     int res = AES_GCM_AUTH_E;
06660 #endif
06661 
06662     /* argument checks */
06663     /* If the sz is non-zero, both in and out must be set. If sz is 0,
06664      * in and out are don't cares, as this is is the GMAC case. */
06665     if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
06666         authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
06667         ivSz == 0) {
06668 
06669         return BAD_FUNC_ARG;
06670     }
06671 
06672 #ifdef WOLF_CRYPTO_CB
06673     if (aes->devId != INVALID_DEVID) {
06674         int ret = wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
06675             authTag, authTagSz, authIn, authInSz);
06676         if (ret != CRYPTOCB_UNAVAILABLE)
06677             return ret;
06678         /* fall-through when unavailable */
06679     }
06680 #endif
06681 
06682 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
06683     /* if async and byte count above threshold */
06684     /* only 12-byte IV is supported in HW */
06685     if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
06686                     sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
06687     #if defined(HAVE_CAVIUM)
06688         #ifdef HAVE_CAVIUM_V
06689         if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
06690             return NitroxAesGcmDecrypt(aes, out, in, sz,
06691                 (const byte*)aes->devKey, aes->keylen, iv, ivSz,
06692                 authTag, authTagSz, authIn, authInSz);
06693         }
06694         #endif
06695     #elif defined(HAVE_INTEL_QA)
06696         return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
06697             (const byte*)aes->devKey, aes->keylen, iv, ivSz,
06698             authTag, authTagSz, authIn, authInSz);
06699     #else /* WOLFSSL_ASYNC_CRYPT_TEST */
06700         if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_DECRYPT)) {
06701             WC_ASYNC_TEST* testDev = &aes->asyncDev.test;
06702             testDev->aes.aes = aes;
06703             testDev->aes.out = out;
06704             testDev->aes.in = in;
06705             testDev->aes.sz = sz;
06706             testDev->aes.iv = iv;
06707             testDev->aes.ivSz = ivSz;
06708             testDev->aes.authTag = (byte*)authTag;
06709             testDev->aes.authTagSz = authTagSz;
06710             testDev->aes.authIn = authIn;
06711             testDev->aes.authInSz = authInSz;
06712             return WC_PENDING_E;
06713         }
06714     #endif
06715     }
06716 #endif /* WOLFSSL_ASYNC_CRYPT */
06717 
06718 #ifdef STM32_CRYPTO_AES_GCM
06719     /* The STM standard peripheral library API's doesn't support partial blocks */
06720     #ifdef STD_PERI_LIB
06721     if (partial == 0)
06722     #endif
06723     {
06724         return wc_AesGcmDecrypt_STM32(
06725             aes, out, in, sz, iv, ivSz,
06726             authTag, authTagSz, authIn, authInSz);
06727     }
06728 #endif /* STM32_CRYPTO_AES_GCM */
06729 
06730 #ifdef WOLFSSL_AESNI
06731     #ifdef HAVE_INTEL_AVX2
06732     if (IS_INTEL_AVX2(intel_flags)) {
06733         AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06734                                  authTagSz, (byte*)aes->key, aes->rounds, &res);
06735         if (res == 0)
06736             return AES_GCM_AUTH_E;
06737         return 0;
06738     }
06739     else
06740     #endif
06741     #ifdef HAVE_INTEL_AVX1
06742     if (IS_INTEL_AVX1(intel_flags)) {
06743         AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06744                                  authTagSz, (byte*)aes->key, aes->rounds, &res);
06745         if (res == 0)
06746             return AES_GCM_AUTH_E;
06747         return 0;
06748     }
06749     else
06750     #endif
06751     if (haveAESNI) {
06752         AES_GCM_decrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
06753                                  authTagSz, (byte*)aes->key, aes->rounds, &res);
06754         if (res == 0)
06755             return AES_GCM_AUTH_E;
06756         return 0;
06757     }
06758     else
06759 #endif
06760     {
06761         return AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
06762                                                               authIn, authInSz);
06763     }
06764 }
06765 #endif
06766 #endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
06767 #endif /* WOLFSSL_XILINX_CRYPT */
06768 #endif /* end of block for AESGCM implementation selection */
06769 
06770 
06771 /* Common to all, abstract functions that build off of lower level AESGCM
06772  * functions */
06773 #ifndef WC_NO_RNG
06774 
06775 int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
06776 {
06777     int ret = 0;
06778 
06779     if (aes == NULL || iv == NULL ||
06780         (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
06781          ivSz != GCM_NONCE_MAX_SZ)) {
06782 
06783         ret = BAD_FUNC_ARG;
06784     }
06785 
06786     if (ret == 0) {
06787         XMEMCPY((byte*)aes->reg, iv, ivSz);
06788 
06789         /* If the IV is 96, allow for a 2^64 invocation counter.
06790          * For any other size for the nonce, limit the invocation
06791          * counter to 32-bits. (SP 800-38D 8.3) */
06792         aes->invokeCtr[0] = 0;
06793         aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
06794         aes->nonceSz = ivSz;
06795     }
06796 
06797     return ret;
06798 }
06799 
06800 
06801 int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
06802                    const byte* ivFixed, word32 ivFixedSz,
06803                    WC_RNG* rng)
06804 {
06805     int ret = 0;
06806 
06807     if (aes == NULL || rng == NULL ||
06808         (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
06809          ivSz != GCM_NONCE_MAX_SZ) ||
06810         (ivFixed == NULL && ivFixedSz != 0) ||
06811         (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
06812 
06813         ret = BAD_FUNC_ARG;
06814     }
06815 
06816     if (ret == 0) {
06817         byte* iv = (byte*)aes->reg;
06818 
06819         if (ivFixedSz)
06820             XMEMCPY(iv, ivFixed, ivFixedSz);
06821 
06822         ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
06823     }
06824 
06825     if (ret == 0) {
06826         /* If the IV is 96, allow for a 2^64 invocation counter.
06827          * For any other size for the nonce, limit the invocation
06828          * counter to 32-bits. (SP 800-38D 8.3) */
06829         aes->invokeCtr[0] = 0;
06830         aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
06831         aes->nonceSz = ivSz;
06832     }
06833 
06834     return ret;
06835 }
06836 
06837 
06838 int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
06839                         byte* ivOut, word32 ivOutSz,
06840                         byte* authTag, word32 authTagSz,
06841                         const byte* authIn, word32 authInSz)
06842 {
06843     int ret = 0;
06844 
06845     if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
06846         ivOut == NULL || ivOutSz != aes->nonceSz ||
06847         (authIn == NULL && authInSz != 0)) {
06848 
06849         ret = BAD_FUNC_ARG;
06850     }
06851 
06852     if (ret == 0) {
06853         aes->invokeCtr[0]++;
06854         if (aes->invokeCtr[0] == 0) {
06855             aes->invokeCtr[1]++;
06856             if (aes->invokeCtr[1] == 0)
06857                 ret = AES_GCM_OVERFLOW_E;
06858         }
06859     }
06860 
06861     if (ret == 0) {
06862         XMEMCPY(ivOut, aes->reg, ivOutSz);
06863         ret = wc_AesGcmEncrypt(aes, out, in, sz,
06864                                (byte*)aes->reg, ivOutSz,
06865                                authTag, authTagSz,
06866                                authIn, authInSz);
06867         if (ret == 0)
06868             IncCtr((byte*)aes->reg, ivOutSz);
06869     }
06870 
06871     return ret;
06872 }
06873 
06874 int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
06875             const byte* authIn, word32 authInSz,
06876             byte* authTag, word32 authTagSz, WC_RNG* rng)
06877 {
06878     Aes aes;
06879     int ret;
06880 
06881     if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
06882         authTag == NULL || authTagSz == 0 || rng == NULL) {
06883 
06884         return BAD_FUNC_ARG;
06885     }
06886 
06887     ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
06888     if (ret == 0) {
06889         ret = wc_AesGcmSetKey(&aes, key, keySz);
06890         if (ret == 0)
06891             ret = wc_AesGcmSetIV(&aes, ivSz, NULL, 0, rng);
06892         if (ret == 0)
06893             ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
06894                                   authTag, authTagSz, authIn, authInSz);
06895         wc_AesFree(&aes);
06896     }
06897     ForceZero(&aes, sizeof(aes));
06898 
06899     return ret;
06900 }
06901 
06902 int wc_GmacVerify(const byte* key, word32 keySz,
06903                   const byte* iv, word32 ivSz,
06904                   const byte* authIn, word32 authInSz,
06905                   const byte* authTag, word32 authTagSz)
06906 {
06907     int ret;
06908 #ifndef NO_AES_DECRYPT
06909     Aes aes;
06910 
06911     if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
06912         authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
06913 
06914         return BAD_FUNC_ARG;
06915     }
06916 
06917     ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
06918     if (ret == 0) {
06919         ret = wc_AesGcmSetKey(&aes, key, keySz);
06920         if (ret == 0)
06921             ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,
06922                                   authTag, authTagSz, authIn, authInSz);
06923         wc_AesFree(&aes);
06924     }
06925     ForceZero(&aes, sizeof(aes));
06926 #else
06927     (void)key;
06928     (void)keySz;
06929     (void)iv;
06930     (void)ivSz;
06931     (void)authIn;
06932     (void)authInSz;
06933     (void)authTag;
06934     (void)authTagSz;
06935     ret = NOT_COMPILED_IN;
06936 #endif
06937     return ret;
06938 }
06939 
06940 #endif /* WC_NO_RNG */
06941 
06942 
06943 WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
06944 {
06945     if (gmac == NULL || key == NULL) {
06946         return BAD_FUNC_ARG;
06947     }
06948     return wc_AesGcmSetKey(&gmac->aes, key, len);
06949 }
06950 
06951 
06952 WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
06953                               const byte* authIn, word32 authInSz,
06954                               byte* authTag, word32 authTagSz)
06955 {
06956     return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
06957                                          authTag, authTagSz, authIn, authInSz);
06958 }
06959 
06960 #endif /* HAVE_AESGCM */
06961 
06962 
06963 #ifdef HAVE_AESCCM
06964 
06965 int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
06966 {
06967     if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
06968         return BAD_FUNC_ARG;
06969 
06970     return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
06971 }
06972 
06973 #ifdef WOLFSSL_ARMASM
06974     /* implementation located in wolfcrypt/src/port/arm/armv8-aes.c */
06975 
06976 #elif defined(HAVE_COLDFIRE_SEC)
06977     #error "Coldfire SEC doesn't currently support AES-CCM mode"
06978 
06979 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
06980     /* implemented in wolfcrypt/src/port/caam_aes.c */
06981 
06982 #elif defined(FREESCALE_LTC)
06983 
06984 /* return 0 on success */
06985 int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
06986                    const byte* nonce, word32 nonceSz,
06987                    byte* authTag, word32 authTagSz,
06988                    const byte* authIn, word32 authInSz)
06989 {
06990     byte *key;
06991     uint32_t keySize;
06992     status_t status;
06993 
06994     /* sanity check on arguments */
06995     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
06996             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
06997         return BAD_FUNC_ARG;
06998 
06999     key = (byte*)aes->key;
07000 
07001     status = wc_AesGetKeySize(aes, &keySize);
07002     if (status != 0) {
07003         return status;
07004     }
07005 
07006     status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
07007         nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
07008 
07009     return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
07010 }
07011 
07012 #ifdef HAVE_AES_DECRYPT
07013 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
07014                    const byte* nonce, word32 nonceSz,
07015                    const byte* authTag, word32 authTagSz,
07016                    const byte* authIn, word32 authInSz)
07017 {
07018     byte *key;
07019     uint32_t keySize;
07020     status_t status;
07021 
07022     /* sanity check on arguments */
07023     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
07024             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
07025         return BAD_FUNC_ARG;
07026 
07027     key = (byte*)aes->key;
07028 
07029     status = wc_AesGetKeySize(aes, &keySize);
07030     if (status != 0) {
07031         return status;
07032     }
07033 
07034     status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
07035         nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
07036 
07037     if (status == kStatus_Success) {
07038         return 0;
07039     }
07040     else {
07041         XMEMSET(out, 0, inSz);
07042         return AES_CCM_AUTH_E;
07043     }
07044 }
07045 #endif /* HAVE_AES_DECRYPT */
07046 
07047 #else
07048 
07049 /* Software CCM */
07050 static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
07051 {
07052     /* process the bulk of the data */
07053     while (inSz >= AES_BLOCK_SIZE) {
07054         xorbuf(out, in, AES_BLOCK_SIZE);
07055         in += AES_BLOCK_SIZE;
07056         inSz -= AES_BLOCK_SIZE;
07057 
07058         wc_AesEncrypt(aes, out, out);
07059     }
07060 
07061     /* process remainder of the data */
07062     if (inSz > 0) {
07063         xorbuf(out, in, inSz);
07064         wc_AesEncrypt(aes, out, out);
07065     }
07066 }
07067 
07068 static void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)
07069 {
07070     word32 authLenSz;
07071     word32 remainder;
07072 
07073     /* encode the length in */
07074     if (inSz <= 0xFEFF) {
07075         authLenSz = 2;
07076         out[0] ^= ((inSz & 0xFF00) >> 8);
07077         out[1] ^=  (inSz & 0x00FF);
07078     }
07079     else if (inSz <= 0xFFFFFFFF) {
07080         authLenSz = 6;
07081         out[0] ^= 0xFF; out[1] ^= 0xFE;
07082         out[2] ^= ((inSz & 0xFF000000) >> 24);
07083         out[3] ^= ((inSz & 0x00FF0000) >> 16);
07084         out[4] ^= ((inSz & 0x0000FF00) >>  8);
07085         out[5] ^=  (inSz & 0x000000FF);
07086     }
07087     /* Note, the protocol handles auth data up to 2^64, but we are
07088      * using 32-bit sizes right now, so the bigger data isn't handled
07089      * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
07090     else
07091         return;
07092 
07093     /* start fill out the rest of the first block */
07094     remainder = AES_BLOCK_SIZE - authLenSz;
07095     if (inSz >= remainder) {
07096         /* plenty of bulk data to fill the remainder of this block */
07097         xorbuf(out + authLenSz, in, remainder);
07098         inSz -= remainder;
07099         in += remainder;
07100     }
07101     else {
07102         /* not enough bulk data, copy what is available, and pad zero */
07103         xorbuf(out + authLenSz, in, inSz);
07104         inSz = 0;
07105     }
07106     wc_AesEncrypt(aes, out, out);
07107 
07108     if (inSz > 0)
07109         roll_x(aes, in, inSz, out);
07110 }
07111 
07112 
07113 static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
07114 {
07115     word32 i;
07116 
07117     for (i = 0; i < lenSz; i++) {
07118         if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
07119     }
07120 }
07121 
07122 #ifdef WOLFSSL_AESNI
07123 static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
07124 {
07125     word32 i;
07126 
07127     /* B+1 = B */
07128     XMEMCPY(B + AES_BLOCK_SIZE * 1, B, AES_BLOCK_SIZE);
07129     /* B+2,B+3 = B,B+1 */
07130     XMEMCPY(B + AES_BLOCK_SIZE * 2, B, AES_BLOCK_SIZE * 2);
07131 
07132     for (i = 0; i < lenSz; i++) {
07133         if (++B[AES_BLOCK_SIZE * 1 - 1 - i] != 0) break;
07134     }
07135     B[AES_BLOCK_SIZE * 2 - 1] += 2;
07136     if (B[AES_BLOCK_SIZE * 2 - 1] < 2) {
07137         for (i = 1; i < lenSz; i++) {
07138             if (++B[AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
07139         }
07140     }
07141     B[AES_BLOCK_SIZE * 3 - 1] += 3;
07142     if (B[AES_BLOCK_SIZE * 3 - 1] < 3) {
07143         for (i = 1; i < lenSz; i++) {
07144             if (++B[AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
07145         }
07146     }
07147 }
07148 
07149 static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
07150 {
07151     word32 i;
07152 
07153     B[AES_BLOCK_SIZE - 1] += 4;
07154     if (B[AES_BLOCK_SIZE - 1] < 4) {
07155         for (i = 1; i < lenSz; i++) {
07156             if (++B[AES_BLOCK_SIZE - 1 - i] != 0) break;
07157         }
07158     }
07159 }
07160 #endif
07161 
07162 /* Software AES - CCM Encrypt */
07163 /* return 0 on success */
07164 int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
07165                    const byte* nonce, word32 nonceSz,
07166                    byte* authTag, word32 authTagSz,
07167                    const byte* authIn, word32 authInSz)
07168 {
07169 #ifndef WOLFSSL_AESNI
07170     byte A[AES_BLOCK_SIZE];
07171     byte B[AES_BLOCK_SIZE];
07172 #else
07173     ALIGN128 byte A[AES_BLOCK_SIZE * 4];
07174     ALIGN128 byte B[AES_BLOCK_SIZE * 4];
07175 #endif
07176     byte lenSz;
07177     word32 i;
07178     byte mask = 0xFF;
07179     const word32 wordSz = (word32)sizeof(word32);
07180 
07181     /* sanity check on arguments */
07182     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
07183             || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
07184             authTagSz > AES_BLOCK_SIZE)
07185         return BAD_FUNC_ARG;
07186 
07187     XMEMSET(A, 0, sizeof(A));
07188     XMEMCPY(B+1, nonce, nonceSz);
07189     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
07190     B[0] = (authInSz > 0 ? 64 : 0)
07191          + (8 * (((byte)authTagSz - 2) / 2))
07192          + (lenSz - 1);
07193     for (i = 0; i < lenSz; i++) {
07194         if (mask && i >= wordSz)
07195             mask = 0x00;
07196         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
07197     }
07198 
07199     wc_AesEncrypt(aes, B, A);
07200 
07201     if (authInSz > 0)
07202         roll_auth(aes, authIn, authInSz, A);
07203     if (inSz > 0)
07204         roll_x(aes, in, inSz, A);
07205     XMEMCPY(authTag, A, authTagSz);
07206 
07207     B[0] = lenSz - 1;
07208     for (i = 0; i < lenSz; i++)
07209         B[AES_BLOCK_SIZE - 1 - i] = 0;
07210     wc_AesEncrypt(aes, B, A);
07211     xorbuf(authTag, A, authTagSz);
07212 
07213     B[15] = 1;
07214 #ifdef WOLFSSL_AESNI
07215     if (haveAESNI && aes->use_aesni) {
07216         while (inSz >= AES_BLOCK_SIZE * 4) {
07217             AesCcmCtrIncSet4(B, lenSz);
07218 
07219             AES_ECB_encrypt(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
07220                             aes->rounds);
07221             xorbuf(A, in, AES_BLOCK_SIZE * 4);
07222             XMEMCPY(out, A, AES_BLOCK_SIZE * 4);
07223 
07224             inSz -= AES_BLOCK_SIZE * 4;
07225             in += AES_BLOCK_SIZE * 4;
07226             out += AES_BLOCK_SIZE * 4;
07227 
07228             if (inSz < AES_BLOCK_SIZE * 4) {
07229                 AesCcmCtrInc4(B, lenSz);
07230             }
07231         }
07232     }
07233 #endif
07234     while (inSz >= AES_BLOCK_SIZE) {
07235         wc_AesEncrypt(aes, B, A);
07236         xorbuf(A, in, AES_BLOCK_SIZE);
07237         XMEMCPY(out, A, AES_BLOCK_SIZE);
07238 
07239         AesCcmCtrInc(B, lenSz);
07240         inSz -= AES_BLOCK_SIZE;
07241         in += AES_BLOCK_SIZE;
07242         out += AES_BLOCK_SIZE;
07243     }
07244     if (inSz > 0) {
07245         wc_AesEncrypt(aes, B, A);
07246         xorbuf(A, in, inSz);
07247         XMEMCPY(out, A, inSz);
07248     }
07249 
07250     ForceZero(A, AES_BLOCK_SIZE);
07251     ForceZero(B, AES_BLOCK_SIZE);
07252 
07253     return 0;
07254 }
07255 
07256 #ifdef HAVE_AES_DECRYPT
07257 /* Software AES - CCM Decrypt */
07258 int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
07259                    const byte* nonce, word32 nonceSz,
07260                    const byte* authTag, word32 authTagSz,
07261                    const byte* authIn, word32 authInSz)
07262 {
07263 #ifndef WOLFSSL_AESNI
07264     byte A[AES_BLOCK_SIZE];
07265     byte B[AES_BLOCK_SIZE];
07266 #else
07267     ALIGN128 byte B[AES_BLOCK_SIZE * 4];
07268     ALIGN128 byte A[AES_BLOCK_SIZE * 4];
07269 #endif
07270     byte* o;
07271     byte lenSz;
07272     word32 i, oSz;
07273     int result = 0;
07274     byte mask = 0xFF;
07275     const word32 wordSz = (word32)sizeof(word32);
07276 
07277     /* sanity check on arguments */
07278     if (aes == NULL || out == NULL || in == NULL || nonce == NULL
07279             || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
07280             authTagSz > AES_BLOCK_SIZE)
07281         return BAD_FUNC_ARG;
07282 
07283     o = out;
07284     oSz = inSz;
07285     XMEMCPY(B+1, nonce, nonceSz);
07286     lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
07287 
07288     B[0] = lenSz - 1;
07289     for (i = 0; i < lenSz; i++)
07290         B[AES_BLOCK_SIZE - 1 - i] = 0;
07291     B[15] = 1;
07292 
07293 #ifdef WOLFSSL_AESNI
07294     if (haveAESNI && aes->use_aesni) {
07295         while (oSz >= AES_BLOCK_SIZE * 4) {
07296             AesCcmCtrIncSet4(B, lenSz);
07297 
07298             AES_ECB_encrypt(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
07299                             aes->rounds);
07300             xorbuf(A, in, AES_BLOCK_SIZE * 4);
07301             XMEMCPY(o, A, AES_BLOCK_SIZE * 4);
07302 
07303             oSz -= AES_BLOCK_SIZE * 4;
07304             in += AES_BLOCK_SIZE * 4;
07305             o += AES_BLOCK_SIZE * 4;
07306 
07307             if (oSz < AES_BLOCK_SIZE * 4) {
07308                 AesCcmCtrInc4(B, lenSz);
07309             }
07310         }
07311     }
07312 #endif
07313     while (oSz >= AES_BLOCK_SIZE) {
07314         wc_AesEncrypt(aes, B, A);
07315         xorbuf(A, in, AES_BLOCK_SIZE);
07316         XMEMCPY(o, A, AES_BLOCK_SIZE);
07317 
07318         AesCcmCtrInc(B, lenSz);
07319         oSz -= AES_BLOCK_SIZE;
07320         in += AES_BLOCK_SIZE;
07321         o += AES_BLOCK_SIZE;
07322     }
07323     if (inSz > 0) {
07324         wc_AesEncrypt(aes, B, A);
07325         xorbuf(A, in, oSz);
07326         XMEMCPY(o, A, oSz);
07327     }
07328 
07329     for (i = 0; i < lenSz; i++)
07330         B[AES_BLOCK_SIZE - 1 - i] = 0;
07331     wc_AesEncrypt(aes, B, A);
07332 
07333     o = out;
07334     oSz = inSz;
07335 
07336     B[0] = (authInSz > 0 ? 64 : 0)
07337          + (8 * (((byte)authTagSz - 2) / 2))
07338          + (lenSz - 1);
07339     for (i = 0; i < lenSz; i++) {
07340         if (mask && i >= wordSz)
07341             mask = 0x00;
07342         B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
07343     }
07344 
07345     wc_AesEncrypt(aes, B, A);
07346 
07347     if (authInSz > 0)
07348         roll_auth(aes, authIn, authInSz, A);
07349     if (inSz > 0)
07350         roll_x(aes, o, oSz, A);
07351 
07352     B[0] = lenSz - 1;
07353     for (i = 0; i < lenSz; i++)
07354         B[AES_BLOCK_SIZE - 1 - i] = 0;
07355     wc_AesEncrypt(aes, B, B);
07356     xorbuf(A, B, authTagSz);
07357 
07358     if (ConstantCompare(A, authTag, authTagSz) != 0) {
07359         /* If the authTag check fails, don't keep the decrypted data.
07360          * Unfortunately, you need the decrypted data to calculate the
07361          * check value. */
07362         XMEMSET(out, 0, inSz);
07363         result = AES_CCM_AUTH_E;
07364     }
07365 
07366     ForceZero(A, AES_BLOCK_SIZE);
07367     ForceZero(B, AES_BLOCK_SIZE);
07368     o = NULL;
07369 
07370     return result;
07371 }
07372 
07373 #endif /* HAVE_AES_DECRYPT */
07374 #endif /* software CCM */
07375 
07376 /* abstract functions that call lower level AESCCM functions */
07377 #ifndef WC_NO_RNG
07378 
07379 int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
07380 {
07381     int ret = 0;
07382 
07383     if (aes == NULL || nonce == NULL ||
07384         nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
07385 
07386         ret = BAD_FUNC_ARG;
07387     }
07388 
07389     if (ret == 0) {
07390         XMEMCPY(aes->reg, nonce, nonceSz);
07391         aes->nonceSz = nonceSz;
07392 
07393         /* Invocation counter should be 2^61 */
07394         aes->invokeCtr[0] = 0;
07395         aes->invokeCtr[1] = 0xE0000000;
07396     }
07397 
07398     return ret;
07399 }
07400 
07401 
07402 int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
07403                         byte* ivOut, word32 ivOutSz,
07404                         byte* authTag, word32 authTagSz,
07405                         const byte* authIn, word32 authInSz)
07406 {
07407     int ret = 0;
07408 
07409     if (aes == NULL || out == NULL ||
07410         (in == NULL && sz != 0) ||
07411         ivOut == NULL ||
07412         (authIn == NULL && authInSz != 0) ||
07413         (ivOutSz != aes->nonceSz)) {
07414 
07415         ret = BAD_FUNC_ARG;
07416     }
07417 
07418     if (ret == 0) {
07419         aes->invokeCtr[0]++;
07420         if (aes->invokeCtr[0] == 0) {
07421             aes->invokeCtr[1]++;
07422             if (aes->invokeCtr[1] == 0)
07423                 ret = AES_CCM_OVERFLOW_E;
07424         }
07425     }
07426 
07427     if (ret == 0) {
07428         ret = wc_AesCcmEncrypt(aes, out, in, sz,
07429                                (byte*)aes->reg, aes->nonceSz,
07430                                authTag, authTagSz,
07431                                authIn, authInSz);
07432         if (ret == 0) {
07433             XMEMCPY(ivOut, aes->reg, aes->nonceSz);
07434             IncCtr((byte*)aes->reg, aes->nonceSz);
07435         }
07436     }
07437 
07438     return ret;
07439 }
07440 
07441 #endif /* WC_NO_RNG */
07442 
07443 #endif /* HAVE_AESCCM */
07444 
07445 
07446 /* Initialize Aes for use with async hardware */
07447 int wc_AesInit(Aes* aes, void* heap, int devId)
07448 {
07449     int ret = 0;
07450 
07451     if (aes == NULL)
07452         return BAD_FUNC_ARG;
07453 
07454     aes->heap = heap;
07455 
07456 #ifdef WOLF_CRYPTO_CB
07457     aes->devId = devId;
07458     aes->devCtx = NULL;
07459 #else
07460     (void)devId;
07461 #endif
07462 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
07463     ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
07464                                                         aes->heap, devId);
07465 #endif /* WOLFSSL_ASYNC_CRYPT */
07466 
07467 #ifdef WOLFSSL_AFALG
07468     aes->alFd = -1;
07469     aes->rdFd = -1;
07470 #endif
07471 #if defined(WOLFSSL_DEVCRYPTO) && \
07472    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
07473     aes->ctx.cfd = -1;
07474 #endif
07475 #if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
07476     XMEMSET(&aes->ctx, 0, sizeof(aes->ctx));
07477 #endif
07478 #ifdef HAVE_AESGCM
07479 #ifdef OPENSSL_EXTRA
07480     XMEMSET(aes->aadH, 0, sizeof(aes->aadH));
07481     aes->aadLen = 0;
07482 #endif
07483 #endif
07484     return ret;
07485 }
07486 
07487 #ifdef HAVE_PKCS11
07488 int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
07489 {
07490     int ret = 0;
07491 
07492     if (aes == NULL)
07493         ret = BAD_FUNC_ARG;
07494     if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
07495         ret = BUFFER_E;
07496 
07497     if (ret == 0)
07498         ret  = wc_AesInit(aes, heap, devId);
07499     if (ret == 0) {
07500         XMEMCPY(aes->id, id, len);
07501         aes->idLen = len;
07502     }
07503 
07504     return ret;
07505 }
07506 #endif
07507 
07508 /* Free Aes from use with async hardware */
07509 void wc_AesFree(Aes* aes)
07510 {
07511     if (aes == NULL)
07512         return;
07513 
07514 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
07515     wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
07516 #endif /* WOLFSSL_ASYNC_CRYPT */
07517 #if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
07518     if (aes->rdFd > 0) { /* negative is error case */
07519         close(aes->rdFd);
07520     }
07521     if (aes->alFd > 0) {
07522         close(aes->alFd);
07523     }
07524 #endif /* WOLFSSL_AFALG */
07525 #if defined(WOLFSSL_DEVCRYPTO) && \
07526     (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
07527     wc_DevCryptoFree(&aes->ctx);
07528 #endif
07529 #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
07530     (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
07531     (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
07532     ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
07533 #endif
07534 }
07535 
07536 
07537 int wc_AesGetKeySize(Aes* aes, word32* keySize)
07538 {
07539     int ret = 0;
07540 
07541     if (aes == NULL || keySize == NULL) {
07542         return BAD_FUNC_ARG;
07543     }
07544 #if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
07545     *keySize = aes->ctx.key.keySize;
07546     return ret;
07547 #endif
07548     switch (aes->rounds) {
07549 #ifdef WOLFSSL_AES_128
07550     case 10:
07551         *keySize = 16;
07552         break;
07553 #endif
07554 #ifdef WOLFSSL_AES_192
07555     case 12:
07556         *keySize = 24;
07557         break;
07558 #endif
07559 #ifdef WOLFSSL_AES_256
07560     case 14:
07561         *keySize = 32;
07562         break;
07563 #endif
07564     default:
07565         *keySize = 0;
07566         ret = BAD_FUNC_ARG;
07567     }
07568 
07569     return ret;
07570 }
07571 
07572 #endif /* !WOLFSSL_TI_CRYPT */
07573 
07574 #ifdef HAVE_AES_ECB
07575 #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
07576     /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
07577 
07578 #elif defined(WOLFSSL_AFALG)
07579     /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
07580 
07581 #elif defined(WOLFSSL_DEVCRYPTO_AES)
07582     /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
07583 
07584 #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
07585 
07586 /* Software AES - ECB */
07587 int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07588 {
07589     if ((in == NULL) || (out == NULL) || (aes == NULL))
07590         return BAD_FUNC_ARG;
07591 
07592         return AES_ECB_encrypt(aes, in, out, sz);
07593 }
07594 
07595 
07596 int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07597 {
07598     if ((in == NULL) || (out == NULL) || (aes == NULL))
07599         return BAD_FUNC_ARG;
07600 
07601         return AES_ECB_decrypt(aes, in, out, sz);
07602 }
07603 
07604 #else
07605 
07606 /* Software AES - ECB */
07607 int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07608 {
07609     word32 blocks = sz / AES_BLOCK_SIZE;
07610 
07611     if ((in == NULL) || (out == NULL) || (aes == NULL))
07612       return BAD_FUNC_ARG;
07613     while (blocks>0) {
07614       wc_AesEncryptDirect(aes, out, in);
07615       out += AES_BLOCK_SIZE;
07616       in  += AES_BLOCK_SIZE;
07617       sz  -= AES_BLOCK_SIZE;
07618       blocks--;
07619     }
07620     return 0;
07621 }
07622 
07623 
07624 int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07625 {
07626     word32 blocks = sz / AES_BLOCK_SIZE;
07627 
07628     if ((in == NULL) || (out == NULL) || (aes == NULL))
07629       return BAD_FUNC_ARG;
07630     while (blocks>0) {
07631       wc_AesDecryptDirect(aes, out, in);
07632       out += AES_BLOCK_SIZE;
07633       in  += AES_BLOCK_SIZE;
07634       sz  -= AES_BLOCK_SIZE;
07635       blocks--;
07636     }
07637     return 0;
07638 }
07639 #endif
07640 #endif /* HAVE_AES_ECB */
07641 
07642 #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_OFB)
07643 /* Feedback AES mode
07644  *
07645  * aes structure holding key to use for encryption
07646  * out buffer to hold result of encryption (must be at least as large as input
07647  *     buffer)
07648  * in  buffer to encrypt
07649  * sz  size of input buffer
07650  * mode flag to specify AES mode
07651  *
07652  * returns 0 on success and negative error values on failure
07653  */
07654 /* Software AES - CFB Encrypt */
07655 static int wc_AesFeedbackEncrypt(Aes* aes, byte* out, const byte* in,
07656         word32 sz, byte mode)
07657 {
07658     byte*  tmp = NULL;
07659 #ifdef WOLFSSL_AES_CFB
07660     byte*  reg = NULL;
07661 #endif
07662 
07663     if (aes == NULL || out == NULL || in == NULL) {
07664         return BAD_FUNC_ARG;
07665     }
07666 
07667 #ifdef WOLFSSL_AES_CFB
07668     if (aes->left && sz) {
07669         reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left;
07670     }
07671 #endif
07672 
07673     /* consume any unused bytes left in aes->tmp */
07674     tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
07675     while (aes->left && sz) {
07676         *(out) = *(in++) ^ *(tmp++);
07677     #ifdef WOLFSSL_AES_CFB
07678         if (mode == AES_CFB_MODE) {
07679             *(reg++) = *out;
07680         }
07681     #endif
07682         out++;
07683         aes->left--;
07684         sz--;
07685     }
07686 
07687     while (sz >= AES_BLOCK_SIZE) {
07688         /* Using aes->tmp here for inline case i.e. in=out */
07689         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07690     #ifdef WOLFSSL_AES_OFB
07691         if (mode == AES_OFB_MODE) {
07692             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
07693         }
07694     #endif
07695         xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
07696     #ifdef WOLFSSL_AES_CFB
07697         if (mode == AES_CFB_MODE) {
07698             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
07699         }
07700     #endif
07701         XMEMCPY(out, aes->tmp, AES_BLOCK_SIZE);
07702         out += AES_BLOCK_SIZE;
07703         in  += AES_BLOCK_SIZE;
07704         sz  -= AES_BLOCK_SIZE;
07705         aes->left = 0;
07706     }
07707 
07708     /* encrypt left over data */
07709     if (sz) {
07710         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07711         aes->left = AES_BLOCK_SIZE;
07712         tmp = (byte*)aes->tmp;
07713     #ifdef WOLFSSL_AES_OFB
07714         if (mode == AES_OFB_MODE) {
07715             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
07716         }
07717     #endif
07718     #ifdef WOLFSSL_AES_CFB
07719         reg = (byte*)aes->reg;
07720     #endif
07721 
07722         while (sz--) {
07723             *(out) = *(in++) ^ *(tmp++);
07724         #ifdef WOLFSSL_AES_CFB
07725             if (mode == AES_CFB_MODE) {
07726                 *(reg++) = *out;
07727             }
07728         #endif
07729             out++;
07730             aes->left--;
07731         }
07732     }
07733 
07734     return 0;
07735 }
07736 
07737 
07738 #ifdef HAVE_AES_DECRYPT
07739 /* CFB 128
07740  *
07741  * aes structure holding key to use for decryption
07742  * out buffer to hold result of decryption (must be at least as large as input
07743  *     buffer)
07744  * in  buffer to decrypt
07745  * sz  size of input buffer
07746  *
07747  * returns 0 on success and negative error values on failure
07748  */
07749 /* Software AES - CFB Decrypt */
07750 static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
07751         byte mode)
07752 {
07753     byte*  tmp;
07754 
07755     if (aes == NULL || out == NULL || in == NULL) {
07756         return BAD_FUNC_ARG;
07757     }
07758 
07759     #ifdef WOLFSSL_AES_CFB
07760     /* check if more input needs copied over to aes->reg */
07761     if (aes->left && sz && mode == AES_CFB_MODE) {
07762         int size = min(aes->left, sz);
07763         XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size);
07764     }
07765     #endif
07766 
07767     /* consume any unused bytes left in aes->tmp */
07768     tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
07769     while (aes->left && sz) {
07770         *(out++) = *(in++) ^ *(tmp++);
07771         aes->left--;
07772         sz--;
07773     }
07774 
07775     while (sz > AES_BLOCK_SIZE) {
07776         /* Using aes->tmp here for inline case i.e. in=out */
07777         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07778     #ifdef WOLFSSL_AES_OFB
07779         if (mode == AES_OFB_MODE) {
07780             XMEMCPY((byte*)aes->reg, (byte*)aes->tmp, AES_BLOCK_SIZE);
07781         }
07782     #endif
07783         xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
07784     #ifdef WOLFSSL_AES_CFB
07785         if (mode == AES_CFB_MODE) {
07786             XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
07787         }
07788     #endif
07789         XMEMCPY(out, (byte*)aes->tmp, AES_BLOCK_SIZE);
07790         out += AES_BLOCK_SIZE;
07791         in  += AES_BLOCK_SIZE;
07792         sz  -= AES_BLOCK_SIZE;
07793         aes->left = 0;
07794     }
07795 
07796     /* decrypt left over data */
07797     if (sz) {
07798         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07799     #ifdef WOLFSSL_AES_CFB
07800         if (mode == AES_CFB_MODE) {
07801             XMEMCPY(aes->reg, in, sz);
07802         }
07803     #endif
07804     #ifdef WOLFSSL_AES_OFB
07805         if (mode == AES_OFB_MODE) {
07806             XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
07807         }
07808     #endif
07809 
07810         aes->left = AES_BLOCK_SIZE;
07811         tmp = (byte*)aes->tmp;
07812 
07813         while (sz--) {
07814             *(out++) = *(in++) ^ *(tmp++);
07815             aes->left--;
07816         }
07817     }
07818 
07819     return 0;
07820 }
07821 #endif /* HAVE_AES_DECRYPT */
07822 #endif /* WOLFSSL_AES_CFB */
07823 
07824 #ifdef WOLFSSL_AES_CFB
07825 /* CFB 128
07826  *
07827  * aes structure holding key to use for encryption
07828  * out buffer to hold result of encryption (must be at least as large as input
07829  *     buffer)
07830  * in  buffer to encrypt
07831  * sz  size of input buffer
07832  *
07833  * returns 0 on success and negative error values on failure
07834  */
07835 /* Software AES - CFB Encrypt */
07836 int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07837 {
07838     return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_CFB_MODE);
07839 }
07840 
07841 
07842 #ifdef HAVE_AES_DECRYPT
07843 /* CFB 128
07844  *
07845  * aes structure holding key to use for decryption
07846  * out buffer to hold result of decryption (must be at least as large as input
07847  *     buffer)
07848  * in  buffer to decrypt
07849  * sz  size of input buffer
07850  *
07851  * returns 0 on success and negative error values on failure
07852  */
07853 /* Software AES - CFB Decrypt */
07854 int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
07855 {
07856     return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE);
07857 }
07858 #endif /* HAVE_AES_DECRYPT */
07859 
07860 
07861 /* shift the whole AES_BLOCK_SIZE array left by 8 or 1 bits */
07862 static void shiftLeftArray(byte* ary, byte shift)
07863 {
07864     int i;
07865 
07866     if (shift == WOLFSSL_BIT_SIZE) {
07867         /* shifting over by 8 bits */
07868         for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
07869             ary[i] = ary[i+1];
07870         }
07871         ary[i] = 0;
07872     }
07873     else {
07874         byte carry = 0;
07875 
07876         /* shifting over by 7 or less bits */
07877         for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
07878             carry = ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift));
07879             carry >>= (WOLFSSL_BIT_SIZE - shift);
07880             ary[i] = (ary[i] << shift) + carry;
07881         }
07882         ary[i] = ary[i] << shift;
07883     }
07884 }
07885 
07886 
07887 /* returns 0 on success and negative values on failure */
07888 static int wc_AesFeedbackCFB8(Aes* aes, byte* out, const byte* in,
07889         word32 sz, byte dir)
07890 {
07891     byte *pt;
07892 
07893     if (aes == NULL || out == NULL || in == NULL) {
07894         return BAD_FUNC_ARG;
07895     }
07896 
07897     if (sz == 0) {
07898         return 0;
07899     }
07900 
07901     while (sz > 0) {
07902         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07903         if (dir == AES_DECRYPTION) {
07904             pt = (byte*)aes->reg;
07905 
07906             /* LSB + CAT */
07907             shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
07908             pt[AES_BLOCK_SIZE - 1] = in[0];
07909         }
07910 
07911         /* MSB + XOR */
07912         out[0] = aes->tmp[0] ^ in[0];
07913         if (dir == AES_ENCRYPTION) {
07914             pt = (byte*)aes->reg;
07915 
07916             /* LSB + CAT */
07917             shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
07918             pt[AES_BLOCK_SIZE - 1] = out[0];
07919         }
07920 
07921         out += 1;
07922         in  += 1;
07923         sz  -= 1;
07924     }
07925 
07926     return 0;
07927 }
07928 
07929 
07930 /* returns 0 on success and negative values on failure */
07931 static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in,
07932         word32 sz, byte dir)
07933 {
07934     byte tmp;
07935     byte cur = 0; /* hold current work in order to handle inline in=out */
07936     byte* pt;
07937     int bit = 7;
07938 
07939     if (aes == NULL || out == NULL || in == NULL) {
07940         return BAD_FUNC_ARG;
07941     }
07942 
07943     if (sz == 0) {
07944         return 0;
07945     }
07946 
07947     while (sz > 0) {
07948         wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
07949         if (dir == AES_DECRYPTION) {
07950             pt = (byte*)aes->reg;
07951 
07952             /* LSB + CAT */
07953             tmp = (0X01 << bit) & in[0];
07954             tmp = tmp >> bit;
07955             tmp &= 0x01;
07956             shiftLeftArray((byte*)aes->reg, 1);
07957             pt[AES_BLOCK_SIZE - 1] |= tmp;
07958         }
07959 
07960         /* MSB  + XOR */
07961         tmp = (0X01 << bit) & in[0];
07962         pt = (byte*)aes->tmp;
07963         tmp = (pt[0] >> 7) ^ (tmp >> bit);
07964         tmp &= 0x01;
07965         cur |= (tmp << bit);
07966 
07967 
07968         if (dir == AES_ENCRYPTION) {
07969             pt = (byte*)aes->reg;
07970 
07971             /* LSB + CAT */
07972             shiftLeftArray((byte*)aes->reg, 1);
07973             pt[AES_BLOCK_SIZE - 1] |= tmp;
07974         }
07975 
07976         bit--;
07977         if (bit < 0) {
07978             out[0] = cur;
07979             out += 1;
07980             in  += 1;
07981             sz  -= 1;
07982             bit = 7;
07983             cur = 0;
07984         }
07985         else {
07986             sz -= 1;
07987         }
07988     }
07989 
07990     if (bit > 0 && bit < 7) {
07991         out[0] = cur;
07992     }
07993 
07994     return 0;
07995 }
07996 
07997 
07998 /* CFB 1
07999  *
08000  * aes structure holding key to use for encryption
08001  * out buffer to hold result of encryption (must be at least as large as input
08002  *     buffer)
08003  * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
08004  * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
08005  *
08006  * returns 0 on success and negative values on failure
08007  */
08008 int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08009 {
08010     return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
08011 }
08012 
08013 
08014 /* CFB 8
08015  *
08016  * aes structure holding key to use for encryption
08017  * out buffer to hold result of encryption (must be at least as large as input
08018  *     buffer)
08019  * in  buffer to encrypt
08020  * sz  size of input buffer
08021  *
08022  * returns 0 on success and negative values on failure
08023  */
08024 int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08025 {
08026     return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
08027 }
08028 #ifdef HAVE_AES_DECRYPT
08029 
08030 /* CFB 1
08031  *
08032  * aes structure holding key to use for encryption
08033  * out buffer to hold result of encryption (must be at least as large as input
08034  *     buffer)
08035  * in  buffer to encrypt
08036  * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
08037  *
08038  * returns 0 on success and negative values on failure
08039  */
08040 int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08041 {
08042     return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
08043 }
08044 
08045 
08046 /* CFB 8
08047  *
08048  * aes structure holding key to use for encryption
08049  * out buffer to hold result of encryption (must be at least as large as input
08050  *     buffer)
08051  * in  buffer to encrypt
08052  * sz  size of input buffer
08053  *
08054  * returns 0 on success and negative values on failure
08055  */
08056 int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08057 {
08058     return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
08059 }
08060 #endif /* HAVE_AES_DECRYPT */
08061 #endif /* WOLFSSL_AES_CFB */
08062 
08063 #ifdef WOLFSSL_AES_OFB
08064 /* OFB
08065  *
08066  * aes structure holding key to use for encryption
08067  * out buffer to hold result of encryption (must be at least as large as input
08068  *     buffer)
08069  * in  buffer to encrypt
08070  * sz  size of input buffer
08071  *
08072  * returns 0 on success and negative error values on failure
08073  */
08074 /* Software AES - CFB Encrypt */
08075 int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08076 {
08077     return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_OFB_MODE);
08078 }
08079 
08080 
08081 #ifdef HAVE_AES_DECRYPT
08082 /* OFB
08083  *
08084  * aes structure holding key to use for decryption
08085  * out buffer to hold result of decryption (must be at least as large as input
08086  *     buffer)
08087  * in  buffer to decrypt
08088  * sz  size of input buffer
08089  *
08090  * returns 0 on success and negative error values on failure
08091  */
08092 /* Software AES - OFB Decrypt */
08093 int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
08094 {
08095     return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE);
08096 }
08097 #endif /* HAVE_AES_DECRYPT */
08098 #endif /* WOLFSSL_AES_OFB */
08099 
08100 
08101 #ifdef HAVE_AES_KEYWRAP
08102 
08103 /* Initialize key wrap counter with value */
08104 static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
08105 {
08106     int i;
08107     word32 bytes;
08108 
08109     bytes = sizeof(word32);
08110     for (i = 0; i < (int)sizeof(word32); i++) {
08111         inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;
08112         bytes--;
08113     }
08114 }
08115 
08116 /* Increment key wrap counter */
08117 static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
08118 {
08119     int i;
08120 
08121     /* in network byte order so start at end and work back */
08122     for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
08123         if (++inOutCtr[i])  /* we're done unless we overflow */
08124             return;
08125     }
08126 }
08127 
08128 /* Decrement key wrap counter */
08129 static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
08130 {
08131     int i;
08132 
08133     for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
08134         if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
08135             return;
08136     }
08137 }
08138 
08139 /* perform AES key wrap (RFC3394), return out sz on success, negative on err */
08140 int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
08141                   byte* out, word32 outSz, const byte* iv)
08142 {
08143     Aes aes;
08144     byte* r;
08145     word32 i;
08146     int ret, j;
08147 
08148     byte t[KEYWRAP_BLOCK_SIZE];
08149     byte tmp[AES_BLOCK_SIZE];
08150 
08151     /* n must be at least 2, output size is n + 8 bytes */
08152     if (key == NULL || in  == NULL || inSz < 2 ||
08153         out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
08154         return BAD_FUNC_ARG;
08155 
08156     /* input must be multiple of 64-bits */
08157     if (inSz % KEYWRAP_BLOCK_SIZE != 0)
08158         return BAD_FUNC_ARG;
08159 
08160     /* user IV is optional */
08161     if (iv == NULL) {
08162         XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
08163     } else {
08164         XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
08165     }
08166 
08167     r = out + 8;
08168     XMEMCPY(r, in, inSz);
08169     XMEMSET(t, 0, sizeof(t));
08170 
08171     ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
08172     if (ret != 0)
08173         return ret;
08174 
08175     ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);
08176     if (ret != 0)
08177         return ret;
08178 
08179     for (j = 0; j <= 5; j++) {
08180         for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
08181 
08182             /* load R[i] */
08183             XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
08184 
08185             wc_AesEncryptDirect(&aes, tmp, tmp);
08186 
08187             /* calculate new A */
08188             IncrementKeyWrapCounter(t);
08189             xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
08190 
08191             /* save R[i] */
08192             XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
08193             r += KEYWRAP_BLOCK_SIZE;
08194         }
08195         r = out + KEYWRAP_BLOCK_SIZE;
08196     }
08197 
08198     /* C[0] = A */
08199     XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
08200 
08201     wc_AesFree(&aes);
08202 
08203     return inSz + KEYWRAP_BLOCK_SIZE;
08204 }
08205 
08206 int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
08207                     byte* out, word32 outSz, const byte* iv)
08208 {
08209     Aes aes;
08210     byte* r;
08211     word32 i, n;
08212     int ret, j;
08213 
08214     byte t[KEYWRAP_BLOCK_SIZE];
08215     byte tmp[AES_BLOCK_SIZE];
08216 
08217     const byte* expIv;
08218     const byte defaultIV[] = {
08219         0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
08220     };
08221 
08222     (void)iv;
08223 
08224     if (key == NULL || in == NULL || inSz < 3 ||
08225         out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
08226         return BAD_FUNC_ARG;
08227 
08228     /* input must be multiple of 64-bits */
08229     if (inSz % KEYWRAP_BLOCK_SIZE != 0)
08230         return BAD_FUNC_ARG;
08231 
08232     /* user IV optional */
08233     if (iv != NULL) {
08234         expIv = iv;
08235     } else {
08236         expIv = defaultIV;
08237     }
08238 
08239     /* A = C[0], R[i] = C[i] */
08240     XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
08241     XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
08242     XMEMSET(t, 0, sizeof(t));
08243 
08244     ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
08245     if (ret != 0)
08246         return ret;
08247 
08248     ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);
08249     if (ret != 0)
08250         return ret;
08251 
08252     /* initialize counter to 6n */
08253     n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
08254     InitKeyWrapCounter(t, 6 * n);
08255 
08256     for (j = 5; j >= 0; j--) {
08257         for (i = n; i >= 1; i--) {
08258 
08259             /* calculate A */
08260             xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
08261             DecrementKeyWrapCounter(t);
08262 
08263             /* load R[i], starting at end of R */
08264             r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
08265             XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
08266             wc_AesDecryptDirect(&aes, tmp, tmp);
08267 
08268             /* save R[i] */
08269             XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
08270         }
08271     }
08272 
08273     wc_AesFree(&aes);
08274 
08275     /* verify IV */
08276     if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
08277         return BAD_KEYWRAP_IV_E;
08278 
08279     return inSz - KEYWRAP_BLOCK_SIZE;
08280 }
08281 
08282 #endif /* HAVE_AES_KEYWRAP */
08283 
08284 #ifdef WOLFSSL_AES_XTS
08285 
08286 /* Galios Field to use */
08287 #define GF_XTS 0x87
08288 
08289 /* This is to help with setting keys to correct encrypt or decrypt type.
08290  *
08291  * tweak AES key for tweak in XTS
08292  * aes   AES key for encrypt/decrypt process
08293  * key   buffer holding aes key | tweak key
08294  * len   length of key buffer in bytes. Should be twice that of key size. i.e.
08295  *       32 for a 16 byte key.
08296  * dir   direction, either AES_ENCRYPTION or AES_DECRYPTION
08297  * heap  heap hint to use for memory. Can be NULL
08298  * devId id to use with async crypto. Can be 0
08299  *
08300  * Note: is up to user to call wc_AesFree on tweak and aes key when done.
08301  *
08302  * return 0 on success
08303  */
08304 int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
08305         void* heap, int devId)
08306 {
08307     word32 keySz;
08308     int    ret = 0;
08309 
08310     if (aes == NULL || key == NULL) {
08311         return BAD_FUNC_ARG;
08312     }
08313 
08314     if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
08315         return ret;
08316     }
08317     if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
08318         return ret;
08319     }
08320 
08321     keySz = len/2;
08322     if (keySz != 16 && keySz != 32) {
08323         WOLFSSL_MSG("Unsupported key size");
08324         return WC_KEY_SIZE_E;
08325     }
08326 
08327     if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) {
08328         ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
08329                 AES_ENCRYPTION);
08330         if (ret != 0) {
08331             wc_AesFree(&aes->aes);
08332         }
08333     }
08334 
08335     return ret;
08336 }
08337 
08338 
08339 /* This is used to free up resources used by Aes structs
08340  *
08341  * aes AES keys to free
08342  *
08343  * return 0 on success
08344  */
08345 int wc_AesXtsFree(XtsAes* aes)
08346 {
08347     if (aes != NULL) {
08348         wc_AesFree(&aes->aes);
08349         wc_AesFree(&aes->tweak);
08350     }
08351 
08352     return 0;
08353 }
08354 
08355 
08356 /* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
08357  * instead of a byte array. This just converts the word64 to a byte array and
08358  * calls wc_AesXtsEncrypt.
08359  *
08360  * aes    AES keys to use for block encrypt/decrypt
08361  * out    output buffer to hold cipher text
08362  * in     input plain text buffer to encrypt
08363  * sz     size of both out and in buffers
08364  * sector value to use for tweak
08365  *
08366  * returns 0 on success
08367  */
08368 int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
08369         word32 sz, word64 sector)
08370 {
08371     byte* pt;
08372     byte  i[AES_BLOCK_SIZE];
08373 
08374     XMEMSET(i, 0, AES_BLOCK_SIZE);
08375 #ifdef BIG_ENDIAN_ORDER
08376     sector = ByteReverseWord64(sector);
08377 #endif
08378     pt = (byte*)&sector;
08379     XMEMCPY(i, pt, sizeof(word64));
08380 
08381     return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
08382 }
08383 
08384 
08385 /* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
08386  * instead of a byte array. This just converts the word64 to a byte array.
08387  *
08388  * aes    AES keys to use for block encrypt/decrypt
08389  * out    output buffer to hold plain text
08390  * in     input cipher text buffer to encrypt
08391  * sz     size of both out and in buffers
08392  * sector value to use for tweak
08393  *
08394  * returns 0 on success
08395  */
08396 int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
08397         word64 sector)
08398 {
08399     byte* pt;
08400     byte  i[AES_BLOCK_SIZE];
08401 
08402     XMEMSET(i, 0, AES_BLOCK_SIZE);
08403 #ifdef BIG_ENDIAN_ORDER
08404     sector = ByteReverseWord64(sector);
08405 #endif
08406     pt = (byte*)&sector;
08407     XMEMCPY(i, pt, sizeof(word64));
08408 
08409     return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
08410 }
08411 
08412 #ifdef HAVE_AES_ECB
08413 /* helper function for encrypting / decrypting full buffer at once */
08414 static int _AesXtsHelper(Aes* aes, byte* out, const byte* in, word32 sz, int dir)
08415 {
08416     word32 outSz   = sz;
08417     word32 totalSz = (sz / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; /* total bytes */
08418     byte*  pt      = out;
08419 
08420     outSz -= AES_BLOCK_SIZE;
08421 
08422     while (outSz > 0) {
08423         word32 j;
08424         byte carry = 0;
08425 
08426         /* multiply by shift left and propagate carry */
08427         for (j = 0; j < AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
08428             byte tmpC;
08429 
08430             tmpC   = (pt[j] >> 7) & 0x01;
08431             pt[j+AES_BLOCK_SIZE] = ((pt[j] << 1) + carry) & 0xFF;
08432             carry  = tmpC;
08433         }
08434         if (carry) {
08435             pt[AES_BLOCK_SIZE] ^= GF_XTS;
08436         }
08437 
08438         pt += AES_BLOCK_SIZE;
08439     }
08440 
08441     xorbuf(out, in, totalSz);
08442     if (dir == AES_ENCRYPTION) {
08443         return wc_AesEcbEncrypt(aes, out, out, totalSz);
08444     }
08445     else {
08446         return wc_AesEcbDecrypt(aes, out, out, totalSz);
08447     }
08448 }
08449 #endif /* HAVE_AES_ECB */
08450 
08451 
08452 /* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
08453  *
08454  * xaes  AES keys to use for block encrypt/decrypt
08455  * out   output buffer to hold cipher text
08456  * in    input plain text buffer to encrypt
08457  * sz    size of both out and in buffers
08458  * i     value to use for tweak
08459  * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
08460  *       adds a sanity check on how the user calls the function.
08461  *
08462  * returns 0 on success
08463  */
08464 /* Software AES - XTS Encrypt  */
08465 int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
08466         const byte* i, word32 iSz)
08467 {
08468     int ret = 0;
08469     word32 blocks = (sz / AES_BLOCK_SIZE);
08470     Aes *aes, *tweak;
08471 
08472     if (xaes == NULL || out == NULL || in == NULL) {
08473         return BAD_FUNC_ARG;
08474     }
08475 
08476     aes   = &xaes->aes;
08477     tweak = &xaes->tweak;
08478 
08479     if (iSz < AES_BLOCK_SIZE) {
08480         return BAD_FUNC_ARG;
08481     }
08482 
08483     if (blocks > 0) {
08484         byte tmp[AES_BLOCK_SIZE];
08485 
08486         XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
08487                                           * key setup passed to encrypt direct*/
08488 
08489         wc_AesEncryptDirect(tweak, tmp, i);
08490 
08491     #ifdef HAVE_AES_ECB
08492         /* encrypt all of buffer at once when possible */
08493         if (in != out) { /* can not handle inline */
08494             XMEMCPY(out, tmp, AES_BLOCK_SIZE);
08495             if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0) {
08496                 return ret;
08497             }
08498         }
08499     #endif
08500 
08501         while (blocks > 0) {
08502             word32 j;
08503             byte carry = 0;
08504             byte buf[AES_BLOCK_SIZE];
08505 
08506     #ifdef HAVE_AES_ECB
08507             if (in == out) { /* check for if inline */
08508     #endif
08509             XMEMCPY(buf, in, AES_BLOCK_SIZE);
08510             xorbuf(buf, tmp, AES_BLOCK_SIZE);
08511             wc_AesEncryptDirect(aes, out, buf);
08512     #ifdef HAVE_AES_ECB
08513             }
08514     #endif
08515             xorbuf(out, tmp, AES_BLOCK_SIZE);
08516 
08517             /* multiply by shift left and propagate carry */
08518             for (j = 0; j < AES_BLOCK_SIZE; j++) {
08519                 byte tmpC;
08520 
08521                 tmpC   = (tmp[j] >> 7) & 0x01;
08522                 tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
08523                 carry  = tmpC;
08524             }
08525             if (carry) {
08526                 tmp[0] ^= GF_XTS;
08527             }
08528 
08529             in  += AES_BLOCK_SIZE;
08530             out += AES_BLOCK_SIZE;
08531             sz  -= AES_BLOCK_SIZE;
08532             blocks--;
08533         }
08534 
08535         /* stealing operation of XTS to handle left overs */
08536         if (sz > 0) {
08537             byte buf[AES_BLOCK_SIZE];
08538 
08539             XMEMCPY(buf, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
08540             if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
08541                 return BUFFER_E;
08542             }
08543             XMEMCPY(out, buf, sz);
08544             XMEMCPY(buf, in, sz);
08545 
08546             xorbuf(buf, tmp, AES_BLOCK_SIZE);
08547             wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);
08548             xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);
08549         }
08550     }
08551     else {
08552         WOLFSSL_MSG("Plain text input too small for encryption");
08553         return BAD_FUNC_ARG;
08554     }
08555 
08556     return ret;
08557 }
08558 
08559 
08560 /* Same process as encryption but Aes key is AES_DECRYPTION type.
08561  *
08562  * xaes  AES keys to use for block encrypt/decrypt
08563  * out   output buffer to hold plain text
08564  * in    input cipher text buffer to decrypt
08565  * sz    size of both out and in buffers
08566  * i     value to use for tweak
08567  * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
08568  *       adds a sanity check on how the user calls the function.
08569  *
08570  * returns 0 on success
08571  */
08572 /* Software AES - XTS Decrypt */
08573 int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
08574         const byte* i, word32 iSz)
08575 {
08576     int ret = 0;
08577     word32 blocks = (sz / AES_BLOCK_SIZE);
08578     Aes *aes, *tweak;
08579 
08580     if (xaes == NULL || out == NULL || in == NULL) {
08581         return BAD_FUNC_ARG;
08582     }
08583 
08584     aes   = &xaes->aes;
08585     tweak = &xaes->tweak;
08586 
08587     if (iSz < AES_BLOCK_SIZE) {
08588         return BAD_FUNC_ARG;
08589     }
08590 
08591     if (blocks > 0) {
08592         word32 j;
08593         byte carry = 0;
08594         byte tmp[AES_BLOCK_SIZE];
08595         byte stl = (sz % AES_BLOCK_SIZE);
08596 
08597         XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
08598                                           * key setup passed to decrypt direct*/
08599 
08600         wc_AesEncryptDirect(tweak, tmp, i);
08601 
08602         /* if Stealing then break out of loop one block early to handle special
08603          * case */
08604         if (stl > 0) {
08605             blocks--;
08606         }
08607 
08608     #ifdef HAVE_AES_ECB
08609         /* decrypt all of buffer at once when possible */
08610         if (in != out) { /* can not handle inline */
08611             XMEMCPY(out, tmp, AES_BLOCK_SIZE);
08612             if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0) {
08613                 return ret;
08614             }
08615         }
08616     #endif
08617 
08618         while (blocks > 0) {
08619             byte buf[AES_BLOCK_SIZE];
08620 
08621     #ifdef HAVE_AES_ECB
08622             if (in == out) { /* check for if inline */
08623     #endif
08624             XMEMCPY(buf, in, AES_BLOCK_SIZE);
08625             xorbuf(buf, tmp, AES_BLOCK_SIZE);
08626             wc_AesDecryptDirect(aes, out, buf);
08627     #ifdef HAVE_AES_ECB
08628             }
08629     #endif
08630             xorbuf(out, tmp, AES_BLOCK_SIZE);
08631 
08632             /* multiply by shift left and propagate carry */
08633             for (j = 0; j < AES_BLOCK_SIZE; j++) {
08634                 byte tmpC;
08635 
08636                 tmpC   = (tmp[j] >> 7) & 0x01;
08637                 tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
08638                 carry  = tmpC;
08639             }
08640             if (carry) {
08641                 tmp[0] ^= GF_XTS;
08642             }
08643             carry = 0;
08644 
08645             in  += AES_BLOCK_SIZE;
08646             out += AES_BLOCK_SIZE;
08647             sz  -= AES_BLOCK_SIZE;
08648             blocks--;
08649         }
08650 
08651         /* stealing operation of XTS to handle left overs */
08652         if (sz > 0) {
08653             byte buf[AES_BLOCK_SIZE];
08654             byte tmp2[AES_BLOCK_SIZE];
08655 
08656             /* multiply by shift left and propagate carry */
08657             for (j = 0; j < AES_BLOCK_SIZE; j++) {
08658                 byte tmpC;
08659 
08660                 tmpC   = (tmp[j] >> 7) & 0x01;
08661                 tmp2[j] = ((tmp[j] << 1) + carry) & 0xFF;
08662                 carry  = tmpC;
08663             }
08664             if (carry) {
08665                 tmp2[0] ^= GF_XTS;
08666             }
08667 
08668             XMEMCPY(buf, in, AES_BLOCK_SIZE);
08669             xorbuf(buf, tmp2, AES_BLOCK_SIZE);
08670             wc_AesDecryptDirect(aes, out, buf);
08671             xorbuf(out, tmp2, AES_BLOCK_SIZE);
08672 
08673             /* tmp2 holds partial | last */
08674             XMEMCPY(tmp2, out, AES_BLOCK_SIZE);
08675             in  += AES_BLOCK_SIZE;
08676             out += AES_BLOCK_SIZE;
08677             sz  -= AES_BLOCK_SIZE;
08678 
08679             /* Make buffer with end of cipher text | last */
08680             XMEMCPY(buf, tmp2, AES_BLOCK_SIZE);
08681             if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
08682                 return BUFFER_E;
08683             }
08684             XMEMCPY(buf, in,   sz);
08685             XMEMCPY(out, tmp2, sz);
08686 
08687             xorbuf(buf, tmp, AES_BLOCK_SIZE);
08688             wc_AesDecryptDirect(aes, tmp2, buf);
08689             xorbuf(tmp2, tmp, AES_BLOCK_SIZE);
08690             XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);
08691         }
08692     }
08693     else {
08694         WOLFSSL_MSG("Plain text input too small for encryption");
08695         return BAD_FUNC_ARG;
08696     }
08697 
08698     return ret;
08699 }
08700 
08701 #endif /* WOLFSSL_AES_XTS */
08702 
08703 #endif /* HAVE_FIPS */
08704 #endif /* !NO_AES */
08705