wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aes.c Source File

aes.c

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