Ignore:
Timestamp:
Feb 7, 2019, 8:36:33 AM (5 years ago)
Author:
coas-nagasima
Message:

wolfsslを3.15.7にバージョンアップ

Location:
asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src
Files:
31 edited

Legend:

Unmodified
Added
Removed
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/aes.c

    r352 r372  
    2828#include <wolfssl/wolfcrypt/error-crypt.h>
    2929
    30 #ifndef NO_AES
     30#if !defined(NO_AES)
     31
     32/* Tip: Locate the software cipher modes by searching for "Software AES" */
     33
     34#if defined(HAVE_FIPS) && \
     35    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     36
     37    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     38    #define FIPS_NO_WRAPPERS
     39
     40    #ifdef USE_WINDOWS_API
     41        #pragma code_seg(".fipsA$g")
     42        #pragma const_seg(".fipsB$g")
     43    #endif
     44#endif
     45
    3146#include <wolfssl/wolfcrypt/aes.h>
    3247#include <wolfssl/wolfcrypt/cpuid.h>
    3348
     49#ifdef WOLF_CRYPTO_DEV
     50    #include <wolfssl/wolfcrypt/cryptodev.h>
     51#endif
     52
    3453
    3554/* fips wrapper calls, user can call direct */
    36 #ifdef HAVE_FIPS
     55#if defined(HAVE_FIPS) && \
     56    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     57
    3758    int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
    3859                              int dir)
     
    173194
    174195    /* AES-CCM */
    175     #ifdef HAVE_AESCCM
    176         void wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
     196    #if defined(HAVE_AESCCM) && \
     197        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     198        int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
    177199        {
    178             AesCcmSetKey(aes, key, keySz);
     200            return AesCcmSetKey(aes, key, keySz);
    179201        }
    180202        int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
     
    210232            }
    211233        #endif /* HAVE_AES_DECRYPT */
    212     #endif /* HAVE_AESCCM */
     234    #endif /* HAVE_AESCCM && HAVE_FIPS_VERSION 2 */
    213235
    214236    int  wc_AesInit(Aes* aes, void* h, int i)
    215237    {
    216         (void)aes;
     238        if (aes == NULL)
     239            return BAD_FUNC_ARG;
     240
    217241        (void)h;
    218242        (void)i;
     243
    219244        /* FIPS doesn't support:
    220245            return AesInit(aes, h, i); */
     
    228253    }
    229254
    230 #else /* HAVE_FIPS */
     255#else /* else build without fips, or for FIPS v2 */
    231256
    232257
     
    244269#endif
    245270
    246 #ifndef WOLFSSL_ARMASM
     271#if !defined(WOLFSSL_ARMASM)
     272
     273#ifdef WOLFSSL_IMX6_CAAM_BLOB
     274    /* case of possibly not using hardware acceleration for AES but using key
     275       blobs */
     276    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
     277#endif
    247278
    248279#ifdef DEBUG_AESNI
     
    258289/* Define AES implementation includes and functions */
    259290#if defined(STM32_CRYPTO)
    260      /* STM32F2/F4 hardware AES support for CBC, CTR modes */
    261 
    262     /* CRYPT_AES_GCM starts the IV with 2 */
    263     #define STM32_GCM_IV_START 2
     291     /* STM32F2/F4/F7/L4 hardware AES support for ECB, CBC, CTR and GCM modes */
    264292
    265293#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
     294
    266295    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
    267296    {
     
    269298    #ifdef WOLFSSL_STM32_CUBEMX
    270299        CRYP_HandleTypeDef hcryp;
    271 
    272         XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    273         switch(aes->rounds) {
    274             case 10: /* 128-bit key */
    275                 hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    276                 break;
    277             case 12: /* 192-bit key */
    278                 hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    279                 break;
    280             case 14: /* 256-bit key */
    281                 hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    282                 break;
    283             default:
    284                 break;
    285         }
    286         hcryp.Instance = CRYP;
    287         hcryp.Init.DataType = CRYP_DATATYPE_8B;
    288         hcryp.Init.pKey = (uint8_t*)aes->key;
    289 
     300    #else
     301        CRYP_InitTypeDef cryptInit;
     302        CRYP_KeyInitTypeDef keyInit;
     303    #endif
     304
     305    #ifdef WOLFSSL_STM32_CUBEMX
     306        ret = wc_Stm32_Aes_Init(aes, &hcryp);
     307        if (ret != 0)
     308            return ret;
     309
     310    #ifdef STM32_CRYPTO_AES_ONLY
     311        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
     312        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
     313        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
     314    #endif
    290315        HAL_CRYP_Init(&hcryp);
    291316
    292         if (HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
    293                                     outBlock, STM32_HAL_TIMEOUT) != HAL_OK) {
     317    #ifdef STM32_CRYPTO_AES_ONLY
     318        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
     319            outBlock, STM32_HAL_TIMEOUT);
     320    #else
     321        ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
     322            outBlock, STM32_HAL_TIMEOUT);
     323    #endif
     324        if (ret != HAL_OK) {
    294325            ret = WC_TIMEOUT_E;
    295326        }
    296 
    297327        HAL_CRYP_DeInit(&hcryp);
    298     #else
    299         word32 *enc_key;
    300         CRYP_InitTypeDef AES_CRYP_InitStructure;
    301         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
    302 
    303         enc_key = aes->key;
    304 
    305         /* crypto structure initialization */
    306         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
    307         CRYP_StructInit(&AES_CRYP_InitStructure);
     328
     329    #else /* STD_PERI_LIB */
     330        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
     331        if (ret != 0)
     332            return ret;
    308333
    309334        /* reset registers to their default values */
    310335        CRYP_DeInit();
    311336
    312         /* load key into correct registers */
    313         switch (aes->rounds) {
    314             case 10: /* 128-bit key */
    315                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
    316                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
    317                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
    318                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
    319                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
    320                 break;
    321 
    322             case 12: /* 192-bit key */
    323                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
    324                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
    325                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
    326                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
    327                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
    328                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
    329                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
    330                 break;
    331 
    332             case 14: /* 256-bit key */
    333                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
    334                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
    335                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
    336                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
    337                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
    338                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
    339                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
    340                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
    341                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
    342                 break;
    343 
    344             default:
    345                 break;
    346         }
    347         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
    348 
    349         /* set direction, mode, and datatype */
    350         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
    351         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
    352         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    353         CRYP_Init(&AES_CRYP_InitStructure);
     337        /* setup key */
     338        CRYP_KeyInit(&keyInit);
     339
     340        /* set direction and mode */
     341        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
     342        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
     343        CRYP_Init(&cryptInit);
    354344
    355345        /* enable crypto processor */
     
    386376    #ifdef WOLFSSL_STM32_CUBEMX
    387377        CRYP_HandleTypeDef hcryp;
    388 
    389         XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    390         switch(aes->rounds) {
    391             case 10: /* 128-bit key */
    392                 hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    393                 break;
    394             case 12: /* 192-bit key */
    395                 hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    396                 break;
    397             case 14: /* 256-bit key */
    398                 hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    399                 break;
    400             default:
    401                 break;
    402         }
    403         hcryp.Instance = CRYP;
    404         hcryp.Init.DataType = CRYP_DATATYPE_8B;
    405         hcryp.Init.pKey = (uint8_t*)aes->key;
    406 
     378    #else
     379        CRYP_InitTypeDef cryptInit;
     380        CRYP_KeyInitTypeDef keyInit;
     381    #endif
     382
     383    #ifdef WOLFSSL_STM32_CUBEMX
     384        ret = wc_Stm32_Aes_Init(aes, &hcryp);
     385        if (ret != 0)
     386            return ret;
     387
     388    #ifdef STM32_CRYPTO_AES_ONLY
     389        hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
     390        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
     391        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
     392    #endif
    407393        HAL_CRYP_Init(&hcryp);
    408394
    409         if (HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
    410                                        outBlock, STM32_HAL_TIMEOUT) != HAL_OK) {
     395    #ifdef STM32_CRYPTO_AES_ONLY
     396        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
     397            outBlock, STM32_HAL_TIMEOUT);
     398    #else
     399        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
     400            outBlock, STM32_HAL_TIMEOUT)
     401    #endif
     402        if (ret != HAL_OK) {
    411403            ret = WC_TIMEOUT_E;
    412404        }
    413 
    414405        HAL_CRYP_DeInit(&hcryp);
    415     #else
    416         word32 *enc_key;
    417         CRYP_InitTypeDef AES_CRYP_InitStructure;
    418         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
    419 
    420         enc_key = aes->key;
    421 
    422         /* crypto structure initialization */
    423         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
    424         CRYP_StructInit(&AES_CRYP_InitStructure);
     406
     407    #else /* STD_PERI_LIB */
     408        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
     409        if (ret != 0)
     410            return ret;
    425411
    426412        /* reset registers to their default values */
    427413        CRYP_DeInit();
    428414
    429         /* load key into correct registers */
    430         switch (aes->rounds) {
    431             case 10: /* 128-bit key */
    432                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
    433                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
    434                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
    435                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
    436                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
    437                 break;
    438 
    439             case 12: /* 192-bit key */
    440                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
    441                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
    442                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
    443                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
    444                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
    445                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
    446                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
    447                 break;
    448 
    449             case 14: /* 256-bit key */
    450                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
    451                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
    452                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
    453                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
    454                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
    455                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
    456                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
    457                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
    458                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
    459                 break;
    460 
    461             default:
    462                 break;
    463         }
    464         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
    465 
    466         /* set direction, key, and datatype */
    467         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
    468         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
    469         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    470         CRYP_Init(&AES_CRYP_InitStructure);
     415        /* set direction and key */
     416        CRYP_KeyInit(&keyInit);
     417        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
     418        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
     419        CRYP_Init(&cryptInit);
    471420
    472421        /* enable crypto processor */
    473422        CRYP_Cmd(ENABLE);
    474423
    475         /* wait until decrypt key has been intialized */
     424        /* wait until decrypt key has been initialized */
    476425        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
    477426
    478         /* set direction, mode, and datatype */
    479         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
    480         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
    481         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    482         CRYP_Init(&AES_CRYP_InitStructure);
     427        /* set direction and mode */
     428        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
     429        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
     430        CRYP_Init(&cryptInit);
    483431
    484432        /* enable crypto processor */
     
    782730    #endif /* HAVE_AES_DECRYPT */
    783731
     732#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     733        static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
     734        {
     735            wc_AesEncryptDirect(aes, outBlock, inBlock);
     736            return 0;
     737        }
     738
     739#elif defined(WOLFSSL_AFALG)
     740#elif defined(WOLFSSL_DEVCRYPTO_AES)
     741    /* if all AES is enabled with devcrypto then tables are not needed */
     742
    784743#else
    785744
    786     /* using wolfCrypt software AES implementation */
     745    /* using wolfCrypt software implementation */
    787746    #define NEED_AES_TABLES
    788747#endif
     
    13361295
    13371296
     1297#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
    13381298static const byte Td4[256] =
    13391299{
     
    13711331    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
    13721332};
     1333#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
    13731334#endif /* HAVE_AES_DECRYPT */
    13741335
     
    13911352
    13921353/* load 4 Te Tables into cache by cache line stride */
    1393 static INLINE word32 PreFetchTe(void)
     1354static WC_INLINE word32 PreFetchTe(void)
    13941355{
    13951356    word32 x = 0;
     
    14051366}
    14061367
    1407 
     1368/* Software AES - ECB Encrypt */
    14081369static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
    14091370{
     
    14151376    if (r > 7 || r == 0) {
    14161377        WOLFSSL_MSG("AesEncrypt encountered improper key, set it up");
    1417         return;  /* stop instead of segfaulting, set up your keys! */
     1378        return;  /* stop instead of seg-faulting, set up your keys! */
    14181379    }
    14191380
     
    15941555
    15951556#if defined(HAVE_AES_DECRYPT)
    1596 #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
     1557#if (defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)) && \
     1558    !defined(WOLFSSL_DEVCRYPTO_CBC)
    15971559
    15981560/* load 4 Td Tables into cache by cache line stride */
    1599 static INLINE word32 PreFetchTd(void)
     1561static WC_INLINE word32 PreFetchTd(void)
    16001562{
    16011563    word32 x = 0;
     
    16121574
    16131575/* load Td Table4 into cache by cache line stride */
    1614 static INLINE word32 PreFetchTd4(void)
     1576static WC_INLINE word32 PreFetchTd4(void)
    16151577{
    16161578    word32 x = 0;
     
    16231585}
    16241586
     1587/* Software AES - ECB Decrypt */
    16251588static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
    16261589{
     
    16321595    if (r > 7 || r == 0) {
    16331596        WOLFSSL_MSG("AesDecrypt encountered improper key, set it up");
    1634         return;  /* stop instead of segfaulting, set up your keys! */
     1597        return;  /* stop instead of seg-faulting, set up your keys! */
    16351598    }
    16361599#ifdef WOLFSSL_AESNI
     
    18031766        (void)dir;
    18041767
    1805         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
     1768        if (keylen != 16 &&
     1769        #ifdef WOLFSSL_AES_192
     1770            keylen != 24 &&
     1771        #endif
     1772            keylen != 32) {
    18061773            return BAD_FUNC_ARG;
     1774        }
    18071775
    18081776        aes->keylen = keylen;
     
    18121780        ByteReverseWords(rk, rk, keylen);
    18131781    #endif
    1814     #ifdef WOLFSSL_AES_COUNTER
     1782    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
    18151783        aes->left = 0;
    18161784    #endif
     
    18851853            XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
    18861854
     1855    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
     1856        aes->left = 0;
     1857    #endif
     1858
    18871859        return 0;
    18881860    }
     
    18911863                  int dir)
    18921864    {
    1893         if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
     1865        if (aes == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32)))
    18941866            return BAD_FUNC_ARG;
    18951867
    18961868        aes->rounds = keylen/4 + 6;
    18971869        XMEMCPY(aes->key, userKey, keylen);
    1898     #ifdef WOLFSSL_AES_COUNTER
     1870
     1871    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
    18991872        aes->left = 0;
    19001873    #endif
     
    19231896            return BAD_FUNC_ARG;
    19241897
    1925     #ifdef WOLFSSL_AES_COUNTER
     1898    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
    19261899        aes->left = 0;
    19271900    #endif
    1928         aes->keylen = keylen;
     1901
    19291902        aes->rounds = keylen/4 + 6;
    19301903
     
    19661939        ret = nrf51_aes_set_key(userKey);
    19671940
     1941    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
     1942        aes->left = 0;
     1943    #endif
     1944
    19681945        return ret;
    19691946    }
     
    19751952    }
    19761953
     1954#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     1955      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
     1956
     1957#elif defined(WOLFSSL_AFALG)
     1958    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
     1959
     1960#elif defined(WOLFSSL_DEVCRYPTO_AES)
     1961    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
     1962
    19771963#else
     1964
     1965    /* Software AES - SetKey */
    19781966    static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
    19791967                const byte* iv, int dir)
     
    19881976        aes->use_aesni = 0;
    19891977    #endif /* WOLFSSL_AESNI */
    1990     #ifdef WOLFSSL_AES_COUNTER
     1978        #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
    19911979        aes->left = 0;
    1992     #endif /* WOLFSSL_AES_COUNTER */
     1980        #endif
    19931981
    19941982        aes->keylen = keylen;
     
    20031991
    20041992        switch (keylen) {
    2005     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128
     1993    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
     1994            defined(WOLFSSL_AES_128)
    20061995        case 16:
    20071996            while (1)
     
    20242013    #endif /* 128 */
    20252014
    2026     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192
     2015    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
     2016            defined(WOLFSSL_AES_192)
    20272017        case 24:
    20282018            /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
     
    20482038    #endif /* 192 */
    20492039
    2050     #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256
     2040    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
     2041            defined(WOLFSSL_AES_256)
    20512042        case 32:
    20522043            while (1)
     
    21322123        const byte* iv, int dir)
    21332124    {
     2125        int ret;
    21342126    #if defined(AES_MAX_KEY_SIZE)
    21352127        const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
    21362128    #endif
    21372129
     2130    #ifdef WOLFSSL_IMX6_CAAM_BLOB
     2131        byte   local[32];
     2132        word32 localSz = 32;
     2133
     2134        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
     2135                keylen == (24 + WC_CAAM_BLOB_SZ) ||
     2136                keylen == (32 + WC_CAAM_BLOB_SZ)) {
     2137            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
     2138                return BAD_FUNC_ARG;
     2139            }
     2140
     2141            /* set local values */
     2142            userKey = local;
     2143            keylen = localSz;
     2144        }
     2145    #endif
    21382146        if (aes == NULL ||
    21392147                !((keylen == 16) || (keylen == 24) || (keylen == 32))) {
     
    21642172        }
    21652173        if (haveAESNI) {
    2166             #ifdef WOLFSSL_AES_COUNTER
     2174            #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)
    21672175                aes->left = 0;
    21682176            #endif /* WOLFSSL_AES_COUNTER */
     
    21792187    #endif /* WOLFSSL_AESNI */
    21802188
    2181         return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
     2189        ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
     2190
     2191    #if defined(WOLFSSL_DEVCRYPTO) && \
     2192        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
     2193        aes->ctx.cfd = -1;
     2194        XMEMCPY(aes->devKey, userKey, keylen);
     2195    #endif
     2196    #ifdef WOLFSSL_IMX6_CAAM_BLOB
     2197        ForceZero(local, sizeof(local));
     2198    #endif
     2199        return ret;
    21822200    }
    21832201
     
    21872205                            const byte* iv, int dir)
    21882206        {
    2189             return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
     2207            int ret;
     2208
     2209        #ifdef WOLFSSL_IMX6_CAAM_BLOB
     2210            byte   local[32];
     2211            word32 localSz = 32;
     2212
     2213            if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
     2214             keylen == (24 + WC_CAAM_BLOB_SZ) ||
     2215             keylen == (32 + WC_CAAM_BLOB_SZ)) {
     2216                if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz)
     2217                        != 0) {
     2218                    return BAD_FUNC_ARG;
     2219                }
     2220
     2221                /* set local values */
     2222                userKey = local;
     2223                keylen = localSz;
     2224            }
     2225        #endif
     2226            ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);
     2227
     2228        #ifdef WOLFSSL_IMX6_CAAM_BLOB
     2229            ForceZero(local, sizeof(local));
     2230        #endif
     2231
     2232            return ret;
    21902233        }
    21912234    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
     
    22392282        }
    22402283
     2284    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     2285        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
     2286
     2287    #elif defined(WOLFSSL_AFALG)
     2288        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
     2289
     2290    #elif defined(WOLFSSL_DEVCRYPTO_AES)
     2291        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
     2292
    22412293    #else
    22422294        /* Allow direct access to one block encrypt */
     
    22672319        CRYP_HandleTypeDef hcryp;
    22682320
    2269         XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    2270         switch (aes->rounds) {
    2271             case 10: /* 128-bit key */
    2272                 hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    2273                 break;
    2274             case 12: /* 192-bit key */
    2275                 hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    2276                 break;
    2277             case 14: /* 256-bit key */
    2278                 hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    2279                 break;
    2280             default:
    2281                 break;
    2282         }
    2283         hcryp.Instance = CRYP;
    2284         hcryp.Init.DataType = CRYP_DATATYPE_8B;
    2285         hcryp.Init.pKey = (uint8_t*)aes->key;
     2321        ret = wc_Stm32_Aes_Init(aes, &hcryp);
     2322        if (ret != 0)
     2323            return ret;
     2324
     2325    #ifdef STM32_CRYPTO_AES_ONLY
     2326        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
     2327        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
     2328        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
     2329    #endif
    22862330        hcryp.Init.pInitVect = (uint8_t*)aes->reg;
    2287 
    22882331        HAL_CRYP_Init(&hcryp);
    22892332
    22902333        while (blocks--) {
    2291             if (HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
    2292                                            out, STM32_HAL_TIMEOUT) != HAL_OK) {
     2334        #ifdef STM32_CRYPTO_AES_ONLY
     2335            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
     2336                out, STM32_HAL_TIMEOUT);
     2337        #else
     2338            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
     2339                out, STM32_HAL_TIMEOUT);
     2340        #endif
     2341            if (ret != HAL_OK) {
    22932342                ret = WC_TIMEOUT_E;
    22942343                break;
     
    23142363        CRYP_HandleTypeDef hcryp;
    23152364
    2316         XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    2317         switch (aes->rounds) {
    2318             case 10: /* 128-bit key */
    2319                 hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
     2365        ret = wc_Stm32_Aes_Init(aes, &hcryp);
     2366        if (ret != 0)
     2367            return ret;
     2368
     2369        /* if input and output same will overwrite input iv */
     2370        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
     2371
     2372    #ifdef STM32_CRYPTO_AES_ONLY
     2373        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
     2374        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
     2375        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
     2376    #endif
     2377
     2378        hcryp.Init.pInitVect = (uint8_t*)aes->reg;
     2379        HAL_CRYP_Init(&hcryp);
     2380
     2381        while (blocks--) {
     2382        #ifdef STM32_CRYPTO_AES_ONLY
     2383            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
     2384                out, STM32_HAL_TIMEOUT);
     2385        #else
     2386            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
     2387                out, STM32_HAL_TIMEOUT);
     2388        #endif
     2389            if (ret != HAL_OK) {
     2390                ret = WC_TIMEOUT_E;
    23202391                break;
    2321             case 12: /* 192-bit key */
    2322                 hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    2323                 break;
    2324             case 14: /* 256-bit key */
    2325                 hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    2326                 break;
    2327             default:
    2328                 break;
    2329         }
    2330         hcryp.Instance = CRYP;
    2331         hcryp.Init.DataType = CRYP_DATATYPE_8B;
    2332         hcryp.Init.pKey = (uint8_t*)aes->key;
    2333         hcryp.Init.pInitVect = (uint8_t*)aes->reg;
    2334 
    2335         HAL_CRYP_Init(&hcryp);
    2336 
    2337         while (blocks--) {
    2338             if (HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,
    2339                                            out, STM32_HAL_TIMEOUT) != HAL_OK) {
    2340                 ret = WC_TIMEOUT_E;
    23412392            }
    23422393
     
    23532404    }
    23542405    #endif /* HAVE_AES_DECRYPT */
    2355 #else
     2406
     2407#else /* STD_PERI_LIB */
    23562408    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    23572409    {
    2358         word32 *enc_key, *iv;
     2410        int ret;
     2411        word32 *iv;
    23592412        word32 blocks = (sz / AES_BLOCK_SIZE);
    2360         CRYP_InitTypeDef AES_CRYP_InitStructure;
    2361         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
    2362         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
    2363 
    2364         enc_key = aes->key;
    2365         iv = aes->reg;
    2366 
    2367         /* crypto structure initialization */
    2368         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
    2369         CRYP_StructInit(&AES_CRYP_InitStructure);
    2370         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
     2413        CRYP_InitTypeDef cryptInit;
     2414        CRYP_KeyInitTypeDef keyInit;
     2415        CRYP_IVInitTypeDef ivInit;
     2416
     2417        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
     2418        if (ret != 0)
     2419            return ret;
    23712420
    23722421        /* reset registers to their default values */
    23732422        CRYP_DeInit();
    23742423
    2375         /* load key into correct registers */
    2376         switch (aes->rounds) {
    2377             case 10: /* 128-bit key */
    2378                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
    2379                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
    2380                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
    2381                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
    2382                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
    2383                 break;
    2384 
    2385             case 12: /* 192-bit key */
    2386                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
    2387                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
    2388                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
    2389                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
    2390                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
    2391                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
    2392                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
    2393                 break;
    2394 
    2395             case 14: /* 256-bit key */
    2396                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
    2397                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
    2398                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
    2399                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
    2400                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
    2401                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
    2402                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
    2403                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
    2404                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
    2405                 break;
    2406 
    2407             default:
    2408                 break;
    2409         }
    2410         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
     2424        /* set key */
     2425        CRYP_KeyInit(&keyInit);
    24112426
    24122427        /* set iv */
     2428        iv = aes->reg;
     2429        CRYP_IVStructInit(&ivInit);
    24132430        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
    2414         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
    2415         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
    2416         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
    2417         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
    2418         CRYP_IVInit(&AES_CRYP_IVInitStructure);
    2419 
    2420         /* set direction, mode, and datatype */
    2421         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
    2422         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
    2423         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    2424         CRYP_Init(&AES_CRYP_InitStructure);
     2431        ivInit.CRYP_IV0Left  = iv[0];
     2432        ivInit.CRYP_IV0Right = iv[1];
     2433        ivInit.CRYP_IV1Left  = iv[2];
     2434        ivInit.CRYP_IV1Right = iv[3];
     2435        CRYP_IVInit(&ivInit);
     2436
     2437        /* set direction and mode */
     2438        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
     2439        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
     2440        CRYP_Init(&cryptInit);
    24252441
    24262442        /* enable crypto processor */
     
    24552471        CRYP_Cmd(DISABLE);
    24562472
    2457         return 0;
     2473        return ret;
    24582474    }
    24592475
     
    24612477    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    24622478    {
    2463         word32 *dec_key, *iv;
     2479        int ret;
     2480        word32 *iv;
    24642481        word32 blocks = (sz / AES_BLOCK_SIZE);
    2465         CRYP_InitTypeDef AES_CRYP_InitStructure;
    2466         CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
    2467         CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
    2468 
    2469         dec_key = aes->key;
    2470         iv = aes->reg;
    2471 
    2472         /* crypto structure initialization */
    2473         CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
    2474         CRYP_StructInit(&AES_CRYP_InitStructure);
    2475         CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
     2482        CRYP_InitTypeDef cryptInit;
     2483        CRYP_KeyInitTypeDef keyInit;
     2484        CRYP_IVInitTypeDef ivInit;
     2485
     2486        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
     2487        if (ret != 0)
     2488            return ret;
    24762489
    24772490        /* if input and output same will overwrite input iv */
     
    24812494        CRYP_DeInit();
    24822495
    2483         /* load key into correct registers */
    2484         switch (aes->rounds) {
    2485             case 10: /* 128-bit key */
    2486                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
    2487                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[0];
    2488                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[1];
    2489                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[2];
    2490                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[3];
    2491                 break;
    2492 
    2493             case 12: /* 192-bit key */
    2494                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
    2495                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[0];
    2496                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[1];
    2497                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[2];
    2498                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[3];
    2499                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[4];
    2500                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[5];
    2501                 break;
    2502 
    2503             case 14: /* 256-bit key */
    2504                 AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
    2505                 AES_CRYP_KeyInitStructure.CRYP_Key0Left  = dec_key[0];
    2506                 AES_CRYP_KeyInitStructure.CRYP_Key0Right = dec_key[1];
    2507                 AES_CRYP_KeyInitStructure.CRYP_Key1Left  = dec_key[2];
    2508                 AES_CRYP_KeyInitStructure.CRYP_Key1Right = dec_key[3];
    2509                 AES_CRYP_KeyInitStructure.CRYP_Key2Left  = dec_key[4];
    2510                 AES_CRYP_KeyInitStructure.CRYP_Key2Right = dec_key[5];
    2511                 AES_CRYP_KeyInitStructure.CRYP_Key3Left  = dec_key[6];
    2512                 AES_CRYP_KeyInitStructure.CRYP_Key3Right = dec_key[7];
    2513                 break;
    2514 
    2515             default:
    2516                 break;
    2517         }
    2518 
    2519         /* set direction, mode, and datatype for key preparation */
    2520         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
    2521         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
    2522         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
    2523         CRYP_Init(&AES_CRYP_InitStructure);
    2524         CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
     2496        /* set direction and key */
     2497        CRYP_KeyInit(&keyInit);
     2498        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
     2499        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
     2500        CRYP_Init(&cryptInit);
    25252501
    25262502        /* enable crypto processor */
     
    25302506        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
    25312507
    2532         /* set direction, mode, and datatype for decryption */
    2533         AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
    2534         AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
    2535         AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    2536         CRYP_Init(&AES_CRYP_InitStructure);
     2508        /* set direction and mode */
     2509        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
     2510        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
     2511        CRYP_Init(&cryptInit);
    25372512
    25382513        /* set iv */
     2514        iv = aes->reg;
     2515        CRYP_IVStructInit(&ivInit);
    25392516        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
    2540 
    2541         AES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
    2542         AES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
    2543         AES_CRYP_IVInitStructure.CRYP_IV1Left  = iv[2];
    2544         AES_CRYP_IVInitStructure.CRYP_IV1Right = iv[3];
    2545         CRYP_IVInit(&AES_CRYP_IVInitStructure);
     2517        ivInit.CRYP_IV0Left  = iv[0];
     2518        ivInit.CRYP_IV0Right = iv[1];
     2519        ivInit.CRYP_IV1Left  = iv[2];
     2520        ivInit.CRYP_IV1Right = iv[3];
     2521        CRYP_IVInit(&ivInit);
    25462522
    25472523        /* enable crypto processor */
     
    25752551        CRYP_Cmd(DISABLE);
    25762552
    2577         return 0;
     2553        return ret;
    25782554    }
    25792555    #endif /* HAVE_AES_DECRYPT */
     
    27042680        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
    27052681            iv, enc_key, keySize);
     2682
     2683        /* store iv for next call */
     2684        if (status == kStatus_Success) {
     2685            XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
     2686        }
     2687
    27062688        return (status == kStatus_Success) ? 0 : -1;
    27072689    }
     
    27142696        byte* iv, *dec_key;
    27152697        word32 blocks = (sz / AES_BLOCK_SIZE);
     2698        byte temp_block[AES_BLOCK_SIZE];
    27162699
    27172700        iv      = (byte*)aes->reg;
     
    27232706        }
    27242707
     2708        /* get IV for next call */
     2709        XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
     2710
    27252711        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
    27262712            iv, dec_key, keySize, kLTC_EncryptKey);
     2713
     2714        /* store IV for next call */
     2715        if (status == kStatus_Success) {
     2716            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
     2717        }
     2718
    27272719        return (status == kStatus_Success) ? 0 : -1;
    27282720    }
     
    27912783    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    27922784    {
    2793         return wc_Pic32AesCrypt(
     2785        int ret;
     2786
     2787        /* hardware fails on input that is not a multiple of AES block size */
     2788        if (sz % AES_BLOCK_SIZE != 0) {
     2789            return BAD_FUNC_ARG;
     2790        }
     2791
     2792        ret = wc_Pic32AesCrypt(
    27942793            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
    27952794            out, in, sz, PIC32_ENCRYPTION,
    27962795            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
     2796
     2797        /* store iv for next call */
     2798        if (ret == 0) {
     2799            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
     2800        }
     2801
     2802        return ret;
    27972803    }
    27982804    #ifdef HAVE_AES_DECRYPT
    27992805    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    28002806    {
    2801         return wc_Pic32AesCrypt(
     2807        int ret;
     2808        byte scratch[AES_BLOCK_SIZE];
     2809
     2810        /* hardware fails on input that is not a multiple of AES block size */
     2811        if (sz % AES_BLOCK_SIZE != 0) {
     2812            return BAD_FUNC_ARG;
     2813        }
     2814        XMEMCPY(scratch, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
     2815
     2816        ret = wc_Pic32AesCrypt(
    28022817            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
    28032818            out, in, sz, PIC32_DECRYPTION,
    28042819            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
     2820
     2821        /* store iv for next call */
     2822        if (ret == 0) {
     2823            XMEMCPY((byte*)aes->reg, scratch, AES_BLOCK_SIZE);
     2824        }
     2825
     2826        return ret;
    28052827    }
    28062828    #endif /* HAVE_AES_DECRYPT */
    28072829
     2830#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     2831      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
     2832
     2833#elif defined(WOLFSSL_AFALG)
     2834    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
     2835
     2836#elif defined(WOLFSSL_DEVCRYPTO_CBC)
     2837    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
     2838
    28082839#else
    28092840
     2841    /* Software AES - CBC Encrypt */
    28102842    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    28112843    {
     
    28972929
    28982930    #ifdef HAVE_AES_DECRYPT
     2931    /* Software AES - CBC Decrypt */
    28992932    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    29002933    {
     
    29773010#endif /* HAVE_AES_CBC */
    29783011
    2979 #ifdef HAVE_AES_ECB
    2980 int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    2981 {
    2982     if ((in == NULL) || (out == NULL) || (aes == NULL))
    2983       return BAD_FUNC_ARG;
    2984     while (sz>0) {
    2985       wc_AesEncryptDirect(aes, out, in);
    2986       out += AES_BLOCK_SIZE;
    2987       in  += AES_BLOCK_SIZE;
    2988       sz  -= AES_BLOCK_SIZE;
    2989     }
    2990     return 0;
    2991 }
    2992 int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    2993 {
    2994     if ((in == NULL) || (out == NULL) || (aes == NULL))
    2995       return BAD_FUNC_ARG;
    2996     while (sz>0) {
    2997       wc_AesDecryptDirect(aes, out, in);
    2998       out += AES_BLOCK_SIZE;
    2999       in  += AES_BLOCK_SIZE;
    3000       sz  -= AES_BLOCK_SIZE;
    3001     }
    3002     return 0;
    3003 }
    3004 #endif
    3005 
    30063012/* AES-CTR */
    30073013#if defined(WOLFSSL_AES_COUNTER)
     
    30163022        #ifdef WOLFSSL_STM32_CUBEMX
    30173023            CRYP_HandleTypeDef hcryp;
    3018 
    3019             XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    3020             switch (aes->rounds) {
    3021                 case 10: /* 128-bit key */
    3022                     hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    3023                     break;
    3024                 case 12: /* 192-bit key */
    3025                     hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    3026                     break;
    3027                 case 14: /* 256-bit key */
    3028                     hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    3029                     break;
    3030                 default:
    3031                     break;
    3032             }
    3033             hcryp.Instance = CRYP;
    3034             hcryp.Init.DataType = CRYP_DATATYPE_8B;
    3035             hcryp.Init.pKey = (byte*)aes->key;
    3036             hcryp.Init.pInitVect = (byte*)aes->reg;
    3037 
     3024        #else
     3025            word32 *iv;
     3026            CRYP_InitTypeDef cryptInit;
     3027            CRYP_KeyInitTypeDef keyInit;
     3028            CRYP_IVInitTypeDef ivInit;
     3029        #endif
     3030
     3031        #ifdef WOLFSSL_STM32_CUBEMX
     3032            ret = wc_Stm32_Aes_Init(aes, &hcryp);
     3033            if (ret != 0)
     3034                return ret;
     3035
     3036        #ifdef STM32_CRYPTO_AES_ONLY
     3037            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
     3038            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
     3039            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
     3040        #endif
     3041            hcryp.Init.pInitVect = (uint8_t*)aes->reg;
    30383042            HAL_CRYP_Init(&hcryp);
    30393043
    3040             if (HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE, out,
    3041                                                 STM32_HAL_TIMEOUT) != HAL_OK) {
    3042                 /* failed */
     3044        #ifdef STM32_CRYPTO_AES_ONLY
     3045            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE,
     3046                out, STM32_HAL_TIMEOUT);
     3047        #else
     3048            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE,
     3049                out, STM32_HAL_TIMEOUT);
     3050        #endif
     3051            if (ret != HAL_OK) {
    30433052                ret = WC_TIMEOUT_E;
    30443053            }
    3045 
    30463054            HAL_CRYP_DeInit(&hcryp);
    30473055
    30483056        #else /* STD_PERI_LIB */
    3049             word32 *enc_key, *iv;
    3050             CRYP_InitTypeDef AES_CRYP_InitStructure;
    3051             CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
    3052             CRYP_IVInitTypeDef AES_CRYP_IVInitStructure;
    3053 
    3054             enc_key = aes->key;
    3055             iv = aes->reg;
    3056 
    3057             /* crypto structure initialization */
    3058             CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
    3059             CRYP_StructInit(&AES_CRYP_InitStructure);
    3060             CRYP_IVStructInit(&AES_CRYP_IVInitStructure);
     3057            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
     3058            if (ret != 0)
     3059                return ret;
    30613060
    30623061            /* reset registers to their default values */
    30633062            CRYP_DeInit();
    30643063
    3065             /* load key into correct registers */
    3066             switch (aes->rounds) {
    3067                 case 10: /* 128-bit key */
    3068                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
    3069                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[0];
    3070                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1];
    3071                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[2];
    3072                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3];
    3073                     break;
    3074                 case 12: /* 192-bit key */
    3075                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
    3076                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[0];
    3077                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1];
    3078                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[2];
    3079                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3];
    3080                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[4];
    3081                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5];
    3082                     break;
    3083                 case 14: /* 256-bit key */
    3084                     AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
    3085                     AES_CRYP_KeyInitStructure.CRYP_Key0Left  = enc_key[0];
    3086                     AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1];
    3087                     AES_CRYP_KeyInitStructure.CRYP_Key1Left  = enc_key[2];
    3088                     AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3];
    3089                     AES_CRYP_KeyInitStructure.CRYP_Key2Left  = enc_key[4];
    3090                     AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5];
    3091                     AES_CRYP_KeyInitStructure.CRYP_Key3Left  = enc_key[6];
    3092                     AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7];
    3093                     break;
    3094                 default:
    3095                     break;
    3096             }
    3097             CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
     3064            /* set key */
     3065            CRYP_KeyInit(&keyInit);
    30983066
    30993067            /* set iv */
    3100             AES_CRYP_IVInitStructure.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
    3101             AES_CRYP_IVInitStructure.CRYP_IV0Right = ByteReverseWord32(iv[1]);
    3102             AES_CRYP_IVInitStructure.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
    3103             AES_CRYP_IVInitStructure.CRYP_IV1Right = ByteReverseWord32(iv[3]);
    3104             CRYP_IVInit(&AES_CRYP_IVInitStructure);
    3105 
    3106             /* set direction, mode, and datatype */
    3107             AES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
    3108             AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
    3109             AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
    3110             CRYP_Init(&AES_CRYP_InitStructure);
     3068            iv = aes->reg;
     3069            CRYP_IVStructInit(&ivInit);
     3070            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
     3071            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
     3072            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
     3073            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
     3074            CRYP_IVInit(&ivInit);
     3075
     3076            /* set direction and mode */
     3077            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
     3078            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
     3079            CRYP_Init(&cryptInit);
    31113080
    31123081            /* enable crypto processor */
     
    31883157        }
    31893158
     3159    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     3160        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
     3161
     3162    #elif defined(WOLFSSL_AFALG)
     3163        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
     3164
     3165    #elif defined(WOLFSSL_DEVCRYPTO_AES)
     3166        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
     3167
    31903168    #else
    31913169
     
    31963174    #ifdef NEED_AES_CTR_SOFT
    31973175        /* Increment AES counter */
    3198         static INLINE void IncrementAesCounter(byte* inOutCtr)
     3176        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
    31993177        {
    32003178            /* in network byte order so start at end and work back */
     
    32063184        }
    32073185
     3186        /* Software AES - CTR Encrypt */
    32083187        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
    32093188        {
     
    32583237
    32593238#endif /* WOLFSSL_AES_COUNTER */
     3239#endif /* !WOLFSSL_ARMASM */
     3240
     3241
     3242/*
     3243 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
     3244 * of two parts in order:
     3245 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
     3246 *      to the implicit IV.
     3247 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
     3248 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
     3249 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
     3250 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
     3251 * block counter during the encryption.
     3252 */
     3253
     3254#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
     3255static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
     3256{
     3257    int i;
     3258    for (i = ctrSz-1; i >= 0; i--) {
     3259        if (++ctr[i])
     3260            break;
     3261    }
     3262}
     3263#endif /* HAVE_AESGCM || HAVE_AESCCM */
    32603264
    32613265
    32623266#ifdef HAVE_AESGCM
    3263 
    3264 /*
    3265  * The IV for AES GCM, stored in struct Aes's member reg, is comprised of
    3266  * three parts in order:
    3267  *   1. The implicit IV. This is generated from the PRF using the shared
    3268  *      secrets between endpoints. It is 4 bytes long.
    3269  *   2. The explicit IV. This is set by the user of the AES. It needs to be
    3270  *      unique for each call to encrypt. The explicit IV is shared with the
    3271  *      other end of the transaction in the clear.
    3272  *   3. The counter. Each block of data is encrypted with its own sequence
    3273  *      number counter.
    3274  */
    32753267
    32763268#if defined(HAVE_COLDFIRE_SEC)
     
    32823274#endif
    32833275
    3284 enum {
    3285     NONCE_SZ = 12,
    3286     CTR_SZ   = 4
    3287 };
     3276#ifdef WOLFSSL_ARMASM
     3277    /* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */
     3278
     3279#elif defined(WOLFSSL_AFALG)
     3280    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
     3281
     3282#elif defined(WOLFSSL_DEVCRYPTO_AES)
     3283    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
     3284
     3285#else /* software + AESNI implementation */
    32883286
    32893287#if !defined(FREESCALE_LTC_AES_GCM)
    3290 static INLINE void IncrementGcmCounter(byte* inOutCtr)
     3288static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
    32913289{
    32923290    int i;
     
    33023300#if defined(GCM_SMALL) || defined(GCM_TABLE)
    33033301
    3304 static INLINE void FlattenSzInBits(byte* buf, word32 sz)
     3302static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
    33053303{
    33063304    /* Multiply the sz by 8 */
     
    33203318
    33213319
    3322 static INLINE void RIGHTSHIFTX(byte* x)
     3320static WC_INLINE void RIGHTSHIFTX(byte* x)
    33233321{
    33243322    int i;
     
    33643362#endif /* GCM_TABLE */
    33653363
    3366 
     3364/* Software AES - GCM SetKey */
    33673365int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
    33683366{
    33693367    int  ret;
    33703368    byte iv[AES_BLOCK_SIZE];
     3369
     3370    #ifdef WOLFSSL_IMX6_CAAM_BLOB
     3371        byte   local[32];
     3372        word32 localSz = 32;
     3373
     3374        if (len == (16 + WC_CAAM_BLOB_SZ) ||
     3375          len == (24 + WC_CAAM_BLOB_SZ) ||
     3376          len == (32 + WC_CAAM_BLOB_SZ)) {
     3377            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
     3378                 return BAD_FUNC_ARG;
     3379            }
     3380
     3381            /* set local values */
     3382            key = local;
     3383            len = localSz;
     3384        }
     3385    #endif
    33713386
    33723387    if (!((len == 16) || (len == 24) || (len == 32)))
     
    33933408#if defined(WOLFSSL_XILINX_CRYPT)
    33943409    wc_AesGcmSetKey_ex(aes, key, len, XSECURE_CSU_AES_KEY_SRC_KUP);
     3410#endif
     3411
     3412#ifdef WOLFSSL_IMX6_CAAM_BLOB
     3413    ForceZero(local, sizeof(local));
    33953414#endif
    33963415
     
    34163435#endif
    34173436
    3418 static const __m128i MOD2_128 = M128_INIT(0x1, 0xc200000000000000UL);
     3437static const __m128i MOD2_128 = M128_INIT(0x1,
     3438                                           (long long int)0xc200000000000000UL);
     3439
     3440
     3441/* See Intel® Carry-Less Multiplication Instruction
     3442 * and its Usage for Computing the GCM Mode White Paper
     3443 * by Shay Gueron, Intel Mobility Group, Israel Development Center;
     3444 * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */
     3445
     3446
     3447/* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */
     3448
     3449static const __m128i ONE   = M128_INIT(0x0, 0x1);
     3450#ifndef AES_GCM_AESNI_NO_UNROLL
     3451static const __m128i TWO   = M128_INIT(0x0, 0x2);
     3452static const __m128i THREE = M128_INIT(0x0, 0x3);
     3453static const __m128i FOUR  = M128_INIT(0x0, 0x4);
     3454static const __m128i FIVE  = M128_INIT(0x0, 0x5);
     3455static const __m128i SIX   = M128_INIT(0x0, 0x6);
     3456static const __m128i SEVEN = M128_INIT(0x0, 0x7);
     3457static const __m128i EIGHT = M128_INIT(0x0, 0x8);
     3458#endif
     3459static const __m128i BSWAP_EPI64 = M128_INIT(0x0001020304050607, 0x08090a0b0c0d0e0f);
     3460static const __m128i BSWAP_MASK  = M128_INIT(0x08090a0b0c0d0e0f, 0x0001020304050607);
     3461
     3462
     3463#ifndef _MSC_VER
     3464
     3465#define _VAR(a) "" #a ""
     3466#define VAR(a) _VAR(a)
     3467
     3468#define HR     %%xmm14
     3469#define XR     %%xmm15
     3470#define KR     %%ebx
     3471#define KR64   %%rbx
     3472#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     3473#define CTR1   128(%%rsp)
     3474#define TR     144(%%rsp)
     3475#define HTR    %%rsp
     3476#define STACK_OFFSET    160
     3477#else
     3478#define CTR1   (%%rsp)
     3479#define TR     16(%%rsp)
     3480#define STACK_OFFSET    32
     3481#endif
     3482
     3483#define AESENC()                      \
     3484    "aesenc     %%xmm12, %%xmm4\n\t"  \
     3485    "aesenc     %%xmm12, %%xmm5\n\t"  \
     3486    "aesenc     %%xmm12, %%xmm6\n\t"  \
     3487    "aesenc     %%xmm12, %%xmm7\n\t"  \
     3488    "aesenc     %%xmm12, %%xmm8\n\t"  \
     3489    "aesenc     %%xmm12, %%xmm9\n\t"  \
     3490    "aesenc     %%xmm12, %%xmm10\n\t" \
     3491    "aesenc     %%xmm12, %%xmm11\n\t"
     3492
     3493#define AESENC_SET(o)                        \
     3494    "movdqa     " #o "(%[KEY]), %%xmm12\n\t" \
     3495    AESENC()
     3496
     3497#define AESENC_CTR()                        \
     3498    "movdqu     " VAR(CTR1) ", %%xmm4\n\t"  \
     3499    "movdqa     %[BSWAP_EPI64], %%xmm1\n\t" \
     3500    "movdqu     %%xmm4, %%xmm0\n\t"         \
     3501    "pshufb     %%xmm1, %%xmm4\n\t"         \
     3502    "movdqa     %%xmm0, %%xmm5\n\t"         \
     3503    "paddd      %[ONE], %%xmm5\n\t"         \
     3504    "pshufb     %%xmm1, %%xmm5\n\t"         \
     3505    "movdqa     %%xmm0, %%xmm6\n\t"         \
     3506    "paddd      %[TWO], %%xmm6\n\t"         \
     3507    "pshufb     %%xmm1, %%xmm6\n\t"         \
     3508    "movdqa     %%xmm0, %%xmm7\n\t"         \
     3509    "paddd      %[THREE], %%xmm7\n\t"       \
     3510    "pshufb     %%xmm1, %%xmm7\n\t"         \
     3511    "movdqa     %%xmm0, %%xmm8\n\t"         \
     3512    "paddd      %[FOUR], %%xmm8\n\t"        \
     3513    "pshufb     %%xmm1, %%xmm8\n\t"         \
     3514    "movdqa     %%xmm0, %%xmm9\n\t"         \
     3515    "paddd      %[FIVE], %%xmm9\n\t"        \
     3516    "pshufb     %%xmm1, %%xmm9\n\t"         \
     3517    "movdqa     %%xmm0, %%xmm10\n\t"        \
     3518    "paddd      %[SIX], %%xmm10\n\t"        \
     3519    "pshufb     %%xmm1, %%xmm10\n\t"        \
     3520    "movdqa     %%xmm0, %%xmm11\n\t"        \
     3521    "paddd      %[SEVEN], %%xmm11\n\t"      \
     3522    "pshufb     %%xmm1, %%xmm11\n\t"        \
     3523    "paddd      %[EIGHT], %%xmm0\n\t"
     3524
     3525#define AESENC_XOR()                       \
     3526    "movdqa     (%[KEY]), %%xmm12\n\t"     \
     3527    "movdqu     %%xmm0, " VAR(CTR1) "\n\t" \
     3528    "pxor       %%xmm12, %%xmm4\n\t"       \
     3529    "pxor       %%xmm12, %%xmm5\n\t"       \
     3530    "pxor       %%xmm12, %%xmm6\n\t"       \
     3531    "pxor       %%xmm12, %%xmm7\n\t"       \
     3532    "pxor       %%xmm12, %%xmm8\n\t"       \
     3533    "pxor       %%xmm12, %%xmm9\n\t"       \
     3534    "pxor       %%xmm12, %%xmm10\n\t"      \
     3535    "pxor       %%xmm12, %%xmm11\n\t"
     3536
     3537/* Encrypt and carry-less multiply for AVX1. */
     3538#define AESENC_PCLMUL_1(src, o1, o2, o3)            \
     3539    "movdqu     " #o3 "(" VAR(HTR) "), %%xmm12\n\t" \
     3540    "movdqu     " #o2 "(" #src "), %%xmm0\n\t"      \
     3541    "aesenc     " #o1 "(%[KEY]), %%xmm4\n\t"        \
     3542    "pshufb     %[BSWAP_MASK], %%xmm0\n\t"          \
     3543    "pxor       %%xmm2, %%xmm0\n\t"                 \
     3544    "pshufd     $0x4e, %%xmm12, %%xmm1\n\t"         \
     3545    "pshufd     $0x4e, %%xmm0, %%xmm14\n\t"         \
     3546    "pxor       %%xmm12, %%xmm1\n\t"                \
     3547    "pxor       %%xmm0, %%xmm14\n\t"                \
     3548    "movdqa     %%xmm0, %%xmm3\n\t"                 \
     3549    "pclmulqdq  $0x11, %%xmm12, %%xmm3\n\t"         \
     3550    "aesenc     " #o1 "(%[KEY]), %%xmm5\n\t"        \
     3551    "aesenc     " #o1 "(%[KEY]), %%xmm6\n\t"        \
     3552    "movdqa     %%xmm0, %%xmm2\n\t"                 \
     3553    "pclmulqdq  $0x00, %%xmm12, %%xmm2\n\t"         \
     3554    "aesenc     " #o1 "(%[KEY]), %%xmm7\n\t"        \
     3555    "aesenc     " #o1 "(%[KEY]), %%xmm8\n\t"        \
     3556    "pclmulqdq  $0x00, %%xmm14, %%xmm1\n\t"         \
     3557    "aesenc     " #o1 "(%[KEY]), %%xmm9\n\t"        \
     3558    "aesenc     " #o1 "(%[KEY]), %%xmm10\n\t"       \
     3559    "aesenc     " #o1 "(%[KEY]), %%xmm11\n\t"       \
     3560    "pxor      %%xmm2, %%xmm1\n\t"                  \
     3561    "pxor      %%xmm3, %%xmm1\n\t"                  \
     3562
     3563#define AESENC_PCLMUL_N(src, o1, o2, o3)            \
     3564    "movdqu     " #o3 "(" VAR(HTR) "), %%xmm12\n\t" \
     3565    "movdqu     " #o2 "(" #src" ), %%xmm0\n\t"      \
     3566    "pshufd     $0x4e, %%xmm12, %%xmm13\n\t"        \
     3567    "pshufb     %[BSWAP_MASK], %%xmm0\n\t"          \
     3568    "aesenc     " #o1 "(%[KEY]), %%xmm4\n\t"        \
     3569    "pxor       %%xmm12, %%xmm13\n\t"               \
     3570    "pshufd     $0x4e, %%xmm0, %%xmm14\n\t"         \
     3571    "pxor       %%xmm0, %%xmm14\n\t"                \
     3572    "movdqa     %%xmm0, %%xmm15\n\t"                \
     3573    "pclmulqdq  $0x11, %%xmm12, %%xmm15\n\t"        \
     3574    "aesenc     " #o1 "(%[KEY]), %%xmm5\n\t"        \
     3575    "aesenc     " #o1 "(%[KEY]), %%xmm6\n\t"        \
     3576    "pclmulqdq  $0x00, %%xmm0, %%xmm12\n\t"         \
     3577    "aesenc     " #o1 "(%[KEY]), %%xmm7\n\t"        \
     3578    "aesenc     " #o1 "(%[KEY]), %%xmm8\n\t"        \
     3579    "pclmulqdq  $0x00, %%xmm14, %%xmm13\n\t"        \
     3580    "aesenc     " #o1 "(%[KEY]), %%xmm9\n\t"        \
     3581    "aesenc     " #o1 "(%[KEY]), %%xmm10\n\t"       \
     3582    "aesenc     " #o1 "(%[KEY]), %%xmm11\n\t"       \
     3583    "pxor      %%xmm12, %%xmm1\n\t"                 \
     3584    "pxor      %%xmm12, %%xmm2\n\t"                 \
     3585    "pxor      %%xmm15, %%xmm1\n\t"                 \
     3586    "pxor      %%xmm15, %%xmm3\n\t"                 \
     3587    "pxor      %%xmm13, %%xmm1\n\t"                 \
     3588
     3589#define AESENC_PCLMUL_L(o)                   \
     3590    "movdqa     %%xmm1, %%xmm14\n\t"         \
     3591    "psrldq     $8, %%xmm1\n\t"              \
     3592    "pslldq     $8, %%xmm14\n\t"             \
     3593    "aesenc     " #o "(%[KEY]), %%xmm4\n\t"  \
     3594    "pxor      %%xmm14, %%xmm2\n\t"          \
     3595    "pxor      %%xmm1, %%xmm3\n\t"           \
     3596    "movdqa     %%xmm2, %%xmm12\n\t"         \
     3597    "movdqa     %%xmm2, %%xmm13\n\t"         \
     3598    "movdqa     %%xmm2, %%xmm14\n\t"         \
     3599    "aesenc     " #o "(%[KEY]), %%xmm5\n\t"  \
     3600    "pslld      $31, %%xmm12\n\t"            \
     3601    "pslld      $30, %%xmm13\n\t"            \
     3602    "pslld      $25, %%xmm14\n\t"            \
     3603    "aesenc     " #o "(%[KEY]), %%xmm6\n\t"  \
     3604    "pxor       %%xmm13, %%xmm12\n\t"        \
     3605    "pxor       %%xmm14, %%xmm12\n\t"        \
     3606    "aesenc     " #o "(%[KEY]), %%xmm7\n\t"  \
     3607    "movdqa     %%xmm12, %%xmm13\n\t"        \
     3608    "pslldq     $12, %%xmm12\n\t"            \
     3609    "psrldq     $4, %%xmm13\n\t"             \
     3610    "aesenc     " #o "(%[KEY]), %%xmm8\n\t"  \
     3611    "pxor       %%xmm12, %%xmm2\n\t"         \
     3612    "movdqa     %%xmm2, %%xmm14\n\t"         \
     3613    "movdqa     %%xmm2, %%xmm1\n\t"          \
     3614    "movdqa     %%xmm2, %%xmm0\n\t"          \
     3615    "aesenc     " #o "(%[KEY]), %%xmm9\n\t"  \
     3616    "psrld      $1, %%xmm14\n\t"             \
     3617    "psrld      $2, %%xmm1\n\t"              \
     3618    "psrld      $7, %%xmm0\n\t"              \
     3619    "aesenc     " #o "(%[KEY]), %%xmm10\n\t" \
     3620    "pxor       %%xmm1, %%xmm14\n\t"         \
     3621    "pxor       %%xmm0, %%xmm14\n\t"         \
     3622    "aesenc     " #o "(%[KEY]), %%xmm11\n\t" \
     3623    "pxor       %%xmm13, %%xmm14\n\t"        \
     3624    "pxor       %%xmm14, %%xmm2\n\t"         \
     3625    "pxor       %%xmm3, %%xmm2\n\t"          \
     3626
     3627/* Encrypt and carry-less multiply with last key. */
     3628#define AESENC_LAST(in, out)                \
     3629    "aesenclast %%xmm12, %%xmm4\n\t"        \
     3630    "aesenclast %%xmm12, %%xmm5\n\t"        \
     3631    "movdqu        (" #in "),%%xmm0\n\t"    \
     3632    "movdqu      16(" #in "),%%xmm1\n\t"    \
     3633    "pxor       %%xmm0, %%xmm4\n\t"         \
     3634    "pxor       %%xmm1, %%xmm5\n\t"         \
     3635    "movdqu     %%xmm4,    (" #out ")\n\t"  \
     3636    "movdqu     %%xmm5,  16(" #out ")\n\t"  \
     3637    "aesenclast %%xmm12, %%xmm6\n\t"        \
     3638    "aesenclast %%xmm12, %%xmm7\n\t"        \
     3639    "movdqu      32(" #in "),%%xmm0\n\t"    \
     3640    "movdqu      48(" #in "),%%xmm1\n\t"    \
     3641    "pxor       %%xmm0, %%xmm6\n\t"         \
     3642    "pxor       %%xmm1, %%xmm7\n\t"         \
     3643    "movdqu     %%xmm6,  32(" #out ")\n\t"  \
     3644    "movdqu     %%xmm7,  48(" #out ")\n\t"  \
     3645    "aesenclast %%xmm12, %%xmm8\n\t"        \
     3646    "aesenclast %%xmm12, %%xmm9\n\t"        \
     3647    "movdqu      64(" #in "),%%xmm0\n\t"    \
     3648    "movdqu      80(" #in "),%%xmm1\n\t"    \
     3649    "pxor       %%xmm0, %%xmm8\n\t"         \
     3650    "pxor       %%xmm1, %%xmm9\n\t"         \
     3651    "movdqu     %%xmm8,  64(" #out ")\n\t"  \
     3652    "movdqu     %%xmm9,  80(" #out ")\n\t"  \
     3653    "aesenclast %%xmm12, %%xmm10\n\t"       \
     3654    "aesenclast %%xmm12, %%xmm11\n\t"       \
     3655    "movdqu      96(" #in "),%%xmm0\n\t"    \
     3656    "movdqu     112(" #in "),%%xmm1\n\t"    \
     3657    "pxor       %%xmm0, %%xmm10\n\t"        \
     3658    "pxor       %%xmm1, %%xmm11\n\t"        \
     3659    "movdqu     %%xmm10,  96(" #out ")\n\t" \
     3660    "movdqu     %%xmm11, 112(" #out ")\n\t"
     3661
     3662#define _AESENC_AVX(r)                    \
     3663    "aesenc     16(%[KEY]), " #r "\n\t"   \
     3664    "aesenc     32(%[KEY]), " #r "\n\t"   \
     3665    "aesenc     48(%[KEY]), " #r "\n\t"   \
     3666    "aesenc     64(%[KEY]), " #r "\n\t"   \
     3667    "aesenc     80(%[KEY]), " #r "\n\t"   \
     3668    "aesenc     96(%[KEY]), " #r "\n\t"   \
     3669    "aesenc     112(%[KEY]), " #r "\n\t"  \
     3670    "aesenc     128(%[KEY]), " #r "\n\t"  \
     3671    "aesenc     144(%[KEY]), " #r "\n\t"  \
     3672    "cmpl       $11, %[nr]\n\t"           \
     3673    "movdqa     160(%[KEY]), %%xmm5\n\t"  \
     3674    "jl         %=f\n\t"                  \
     3675    "aesenc     %%xmm5, " #r "\n\t"       \
     3676    "aesenc     176(%[KEY]), " #r "\n\t"  \
     3677    "cmpl       $13, %[nr]\n\t"           \
     3678    "movdqa     192(%[KEY]), %%xmm5\n\t"  \
     3679    "jl         %=f\n\t"                  \
     3680    "aesenc     %%xmm5, " #r "\n\t"       \
     3681    "aesenc     208(%[KEY]), " #r "\n\t"  \
     3682    "movdqa     224(%[KEY]), %%xmm5\n\t"  \
     3683    "%=:\n\t"                             \
     3684    "aesenclast %%xmm5, " #r "\n\t"
     3685#define AESENC_AVX(r)                     \
     3686        _AESENC_AVX(r)
     3687
     3688#define AESENC_BLOCK(in, out)               \
     3689    "movdqu     " VAR(CTR1) ", %%xmm4\n\t"  \
     3690    "movdqu     %%xmm4, %%xmm5\n\t"         \
     3691    "pshufb     %[BSWAP_EPI64], %%xmm4\n\t" \
     3692    "paddd      %[ONE], %%xmm5\n\t"         \
     3693    "pxor       (%[KEY]), %%xmm4\n\t"       \
     3694    "movdqu     %%xmm5, " VAR(CTR1) "\n\t"  \
     3695    AESENC_AVX(%%xmm4)                      \
     3696    "movdqu     (" #in "), %%xmm5\n\t"      \
     3697    "pxor       %%xmm5, %%xmm4\n\t"         \
     3698    "movdqu     %%xmm4, (" #out ")\n\t"     \
     3699    "pshufb     %[BSWAP_MASK], %%xmm4\n\t"  \
     3700    "pxor       %%xmm4, " VAR(XR) "\n\t"
     3701
     3702#define _AESENC_GFMUL(in, out, H, X)            \
     3703    "movdqu     " VAR(CTR1) ", %%xmm4\n\t"      \
     3704    "movdqu     %%xmm4, %%xmm5\n\t"             \
     3705    "pshufb     %[BSWAP_EPI64], %%xmm4\n\t"     \
     3706    "paddd      %[ONE], %%xmm5\n\t"             \
     3707    "pxor       (%[KEY]), %%xmm4\n\t"           \
     3708    "movdqu     %%xmm5, " VAR(CTR1) "\n\t"      \
     3709    "movdqa     " #X ", %%xmm6\n\t"             \
     3710    "pclmulqdq  $0x10, " #H ", %%xmm6\n\t"      \
     3711    "aesenc     16(%[KEY]), %%xmm4\n\t"         \
     3712    "aesenc     32(%[KEY]), %%xmm4\n\t"         \
     3713    "movdqa     " #X ", %%xmm7\n\t"             \
     3714    "pclmulqdq  $0x01, " #H ", %%xmm7\n\t"      \
     3715    "aesenc     48(%[KEY]), %%xmm4\n\t"         \
     3716    "aesenc     64(%[KEY]), %%xmm4\n\t"         \
     3717    "movdqa     " #X ", %%xmm8\n\t"             \
     3718    "pclmulqdq  $0x00, " #H ", %%xmm8\n\t"      \
     3719    "aesenc     80(%[KEY]), %%xmm4\n\t"         \
     3720    "movdqa     " #X ", %%xmm1\n\t"             \
     3721    "pclmulqdq  $0x11, " #H ", %%xmm1\n\t"      \
     3722    "aesenc     96(%[KEY]), %%xmm4\n\t"         \
     3723    "pxor       %%xmm7, %%xmm6\n\t"             \
     3724    "movdqa     %%xmm6, %%xmm2\n\t"             \
     3725    "psrldq     $8, %%xmm6\n\t"                 \
     3726    "pslldq     $8, %%xmm2\n\t"                 \
     3727    "aesenc     112(%[KEY]), %%xmm4\n\t"        \
     3728    "movdqa     %%xmm1, %%xmm3\n\t"             \
     3729    "pxor       %%xmm8, %%xmm2\n\t"             \
     3730    "pxor       %%xmm6, %%xmm3\n\t"             \
     3731    "movdqa     %[MOD2_128], %%xmm0\n\t"        \
     3732    "movdqa     %%xmm2, %%xmm7\n\t"             \
     3733    "pclmulqdq  $0x10, %%xmm0, %%xmm7\n\t"      \
     3734    "aesenc     128(%[KEY]), %%xmm4\n\t"        \
     3735    "pshufd     $0x4e, %%xmm2, %%xmm6\n\t"      \
     3736    "pxor       %%xmm7, %%xmm6\n\t"             \
     3737    "movdqa     %%xmm6, %%xmm7\n\t"             \
     3738    "pclmulqdq  $0x10, %%xmm0, %%xmm7\n\t"      \
     3739    "aesenc     144(%[KEY]), %%xmm4\n\t"        \
     3740    "pshufd     $0x4e, %%xmm6, " VAR(XR) "\n\t" \
     3741    "pxor       %%xmm7, " VAR(XR) "\n\t"        \
     3742    "pxor       %%xmm3, " VAR(XR) "\n\t"        \
     3743    "cmpl       $11, %[nr]\n\t"                 \
     3744    "movdqu     160(%[KEY]), %%xmm5\n\t"        \
     3745    "jl         %=f\n\t"                        \
     3746    "aesenc     %%xmm5, %%xmm4\n\t"             \
     3747    "aesenc     176(%[KEY]), %%xmm4\n\t"        \
     3748    "cmpl       $13, %[nr]\n\t"                 \
     3749    "movdqu     192(%[KEY]), %%xmm5\n\t"        \
     3750    "jl         %=f\n\t"                        \
     3751    "aesenc     %%xmm5, %%xmm4\n\t"             \
     3752    "aesenc     208(%[KEY]), %%xmm4\n\t"        \
     3753    "movdqa     224(%[KEY]), %%xmm5\n\t"        \
     3754    "%=:\n\t"                                   \
     3755    "aesenclast %%xmm5, %%xmm4\n\t"             \
     3756    "movdqu     (" #in "), %%xmm5\n\t"          \
     3757    "pxor       %%xmm5, %%xmm4\n\t"             \
     3758    "movdqu     %%xmm4, (" #out ")\n\t"
     3759#define AESENC_GFMUL(in, out, H, X)             \
     3760       _AESENC_GFMUL(in, out, H, X)
     3761
     3762#define _GHASH_GFMUL_AVX(r, r2, a, b)      \
     3763    "pshufd     $0x4e, "#a", %%xmm1\n\t"   \
     3764    "pshufd     $0x4e, "#b", %%xmm2\n\t"   \
     3765    "movdqa     "#b", %%xmm3\n\t"          \
     3766    "movdqa     "#b", %%xmm0\n\t"          \
     3767    "pclmulqdq  $0x11, "#a", %%xmm3\n\t"   \
     3768    "pclmulqdq  $0x00, "#a", %%xmm0\n\t"   \
     3769    "pxor       "#a", %%xmm1\n\t"          \
     3770    "pxor       "#b", %%xmm2\n\t"          \
     3771    "pclmulqdq  $0x00, %%xmm2, %%xmm1\n\t" \
     3772    "pxor       %%xmm0, %%xmm1\n\t"        \
     3773    "pxor       %%xmm3, %%xmm1\n\t"        \
     3774    "movdqa     %%xmm1, %%xmm2\n\t"        \
     3775    "movdqa     %%xmm0, "#r2"\n\t"         \
     3776    "movdqa     %%xmm3, " #r "\n\t"        \
     3777    "pslldq     $8, %%xmm2\n\t"            \
     3778    "psrldq     $8, %%xmm1\n\t"            \
     3779    "pxor       %%xmm2, "#r2"\n\t"         \
     3780    "pxor       %%xmm1, " #r "\n\t"
     3781#define GHASH_GFMUL_AVX(r, r2, a, b)       \
     3782       _GHASH_GFMUL_AVX(r, r2, a, b)
     3783
     3784#define _GHASH_GFMUL_XOR_AVX(r, r2, a, b)  \
     3785    "pshufd     $0x4e, "#a", %%xmm1\n\t"   \
     3786    "pshufd     $0x4e, "#b", %%xmm2\n\t"   \
     3787    "movdqa     "#b", %%xmm3\n\t"          \
     3788    "movdqa     "#b", %%xmm0\n\t"          \
     3789    "pclmulqdq  $0x11, "#a", %%xmm3\n\t"   \
     3790    "pclmulqdq  $0x00, "#a", %%xmm0\n\t"   \
     3791    "pxor       "#a", %%xmm1\n\t"          \
     3792    "pxor       "#b", %%xmm2\n\t"          \
     3793    "pclmulqdq  $0x00, %%xmm2, %%xmm1\n\t" \
     3794    "pxor       %%xmm0, %%xmm1\n\t"        \
     3795    "pxor       %%xmm3, %%xmm1\n\t"        \
     3796    "movdqa     %%xmm1, %%xmm2\n\t"        \
     3797    "pxor       %%xmm0, "#r2"\n\t"         \
     3798    "pxor       %%xmm3, " #r "\n\t"        \
     3799    "pslldq     $8, %%xmm2\n\t"            \
     3800    "psrldq     $8, %%xmm1\n\t"            \
     3801    "pxor       %%xmm2, "#r2"\n\t"         \
     3802    "pxor       %%xmm1, " #r "\n\t"
     3803#define GHASH_GFMUL_XOR_AVX(r, r2, a, b)   \
     3804       _GHASH_GFMUL_XOR_AVX(r, r2, a, b)
     3805
     3806#define GHASH_MID_AVX(r, r2)        \
     3807    "movdqa     "#r2", %%xmm0\n\t"  \
     3808    "movdqa     " #r ", %%xmm1\n\t" \
     3809    "psrld      $31, %%xmm0\n\t"    \
     3810    "psrld      $31, %%xmm1\n\t"    \
     3811    "pslld      $1, "#r2"\n\t"      \
     3812    "pslld      $1, " #r "\n\t"     \
     3813    "movdqa     %%xmm0, %%xmm2\n\t" \
     3814    "pslldq     $4, %%xmm0\n\t"     \
     3815    "psrldq     $12, %%xmm2\n\t"    \
     3816    "pslldq     $4, %%xmm1\n\t"     \
     3817    "por        %%xmm2, " #r "\n\t" \
     3818    "por        %%xmm0, "#r2"\n\t"  \
     3819    "por        %%xmm1, " #r "\n\t"
     3820
     3821#define _GHASH_GFMUL_RED_AVX(r, a, b)      \
     3822    "pshufd     $0x4e, "#a", %%xmm5\n\t"   \
     3823    "pshufd     $0x4e, "#b", %%xmm6\n\t"   \
     3824    "movdqa     "#b", %%xmm7\n\t"          \
     3825    "movdqa     "#b", %%xmm4\n\t"          \
     3826    "pclmulqdq  $0x11, "#a", %%xmm7\n\t"   \
     3827    "pclmulqdq  $0x00, "#a", %%xmm4\n\t"   \
     3828    "pxor       "#a", %%xmm5\n\t"          \
     3829    "pxor       "#b", %%xmm6\n\t"          \
     3830    "pclmulqdq  $0x00, %%xmm6, %%xmm5\n\t" \
     3831    "pxor       %%xmm4, %%xmm5\n\t"        \
     3832    "pxor       %%xmm7, %%xmm5\n\t"        \
     3833    "movdqa     %%xmm5, %%xmm6\n\t"        \
     3834    "movdqa     %%xmm7, " #r "\n\t"        \
     3835    "pslldq     $8, %%xmm6\n\t"            \
     3836    "psrldq     $8, %%xmm5\n\t"            \
     3837    "pxor       %%xmm6, %%xmm4\n\t"        \
     3838    "pxor       %%xmm5, " #r "\n\t"        \
     3839    "movdqa     %%xmm4, %%xmm8\n\t"        \
     3840    "movdqa     %%xmm4, %%xmm9\n\t"        \
     3841    "movdqa     %%xmm4, %%xmm10\n\t"       \
     3842    "pslld      $31, %%xmm8\n\t"           \
     3843    "pslld      $30, %%xmm9\n\t"           \
     3844    "pslld      $25, %%xmm10\n\t"          \
     3845    "pxor       %%xmm9, %%xmm8\n\t"        \
     3846    "pxor       %%xmm10, %%xmm8\n\t"       \
     3847    "movdqa     %%xmm8, %%xmm9\n\t"        \
     3848    "psrldq     $4, %%xmm9\n\t"            \
     3849    "pslldq     $12, %%xmm8\n\t"           \
     3850    "pxor       %%xmm8, %%xmm4\n\t"        \
     3851    "movdqa     %%xmm4, %%xmm10\n\t"       \
     3852    "movdqa     %%xmm4, %%xmm6\n\t"        \
     3853    "movdqa     %%xmm4, %%xmm5\n\t"        \
     3854    "psrld      $1, %%xmm10\n\t"           \
     3855    "psrld      $2, %%xmm6\n\t"            \
     3856    "psrld      $7, %%xmm5\n\t"            \
     3857    "pxor       %%xmm6, %%xmm10\n\t"       \
     3858    "pxor       %%xmm5, %%xmm10\n\t"       \
     3859    "pxor       %%xmm9, %%xmm10\n\t"       \
     3860    "pxor       %%xmm4, %%xmm10\n\t"       \
     3861    "pxor       %%xmm10, " #r "\n\t"
     3862#define GHASH_GFMUL_RED_AVX(r, a, b)       \
     3863       _GHASH_GFMUL_RED_AVX(r, a, b)
     3864
     3865#define GHASH_RED_AVX(r, r2)           \
     3866    "movdqa     "#r2", %%xmm0\n\t"     \
     3867    "movdqa     "#r2", %%xmm1\n\t"     \
     3868    "movdqa     "#r2", %%xmm2\n\t"     \
     3869    "pslld      $31, %%xmm0\n\t"       \
     3870    "pslld      $30, %%xmm1\n\t"       \
     3871    "pslld      $25, %%xmm2\n\t"       \
     3872    "pxor       %%xmm1, %%xmm0\n\t"    \
     3873    "pxor       %%xmm2, %%xmm0\n\t"    \
     3874    "movdqa     %%xmm0, %%xmm1\n\t"    \
     3875    "psrldq     $4, %%xmm1\n\t"        \
     3876    "pslldq     $12, %%xmm0\n\t"       \
     3877    "pxor       %%xmm0, "#r2"\n\t"     \
     3878    "movdqa     "#r2", %%xmm2\n\t"     \
     3879    "movdqa     "#r2", %%xmm3\n\t"     \
     3880    "movdqa     "#r2", %%xmm0\n\t"     \
     3881    "psrld      $1, %%xmm2\n\t"        \
     3882    "psrld      $2, %%xmm3\n\t"        \
     3883    "psrld      $7, %%xmm0\n\t"        \
     3884    "pxor       %%xmm3, %%xmm2\n\t"    \
     3885    "pxor       %%xmm0, %%xmm2\n\t"    \
     3886    "pxor       %%xmm1, %%xmm2\n\t"    \
     3887    "pxor       "#r2", %%xmm2\n\t"     \
     3888    "pxor       %%xmm2, " #r "\n\t"
     3889
     3890#define GHASH_GFMUL_RED_XOR_AVX(r, r2, a, b) \
     3891    GHASH_GFMUL_XOR_AVX(r, r2, a, b)         \
     3892    GHASH_RED_AVX(r, r2)
     3893
     3894#define GHASH_FULL_AVX(r, r2, a, b) \
     3895    GHASH_GFMUL_AVX(r, r2, a, b)    \
     3896    GHASH_MID_AVX(r, r2)            \
     3897    GHASH_RED_AVX(r, r2)
     3898
     3899#define CALC_IV_12() \
     3900    "# Calculate values when IV is 12 bytes\n\t"      \
     3901    "# Set counter based on IV\n\t"                   \
     3902    "movl       $0x01000000, %%ecx\n\t"               \
     3903    "pinsrq     $0, 0(%%rax), %%xmm13\n\t"            \
     3904    "pinsrd     $2, 8(%%rax), %%xmm13\n\t"            \
     3905    "pinsrd     $3, %%ecx, %%xmm13\n\t"               \
     3906    "# H = Encrypt X(=0) and T = Encrypt counter\n\t" \
     3907    "movdqu     %%xmm13, %%xmm1\n\t"                  \
     3908    "movdqa       0(%[KEY]), " VAR(HR) "\n\t"         \
     3909    "pxor       " VAR(HR) ", %%xmm1\n\t"              \
     3910    "movdqa      16(%[KEY]), %%xmm12\n\t"             \
     3911    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3912    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3913    "movdqa      32(%[KEY]), %%xmm12\n\t"             \
     3914    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3915    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3916    "movdqa      48(%[KEY]), %%xmm12\n\t"             \
     3917    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3918    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3919    "movdqa      64(%[KEY]), %%xmm12\n\t"             \
     3920    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3921    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3922    "movdqa      80(%[KEY]), %%xmm12\n\t"             \
     3923    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3924    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3925    "movdqa      96(%[KEY]), %%xmm12\n\t"             \
     3926    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3927    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3928    "movdqa     112(%[KEY]), %%xmm12\n\t"             \
     3929    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3930    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3931    "movdqa     128(%[KEY]), %%xmm12\n\t"             \
     3932    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3933    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3934    "movdqa     144(%[KEY]), %%xmm12\n\t"             \
     3935    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3936    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3937    "cmpl       $11, %[nr]\n\t"                       \
     3938    "movdqa     160(%[KEY]), %%xmm12\n\t"             \
     3939    "jl 31f\n\t"                                      \
     3940    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3941    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3942    "movdqa     176(%[KEY]), %%xmm12\n\t"             \
     3943    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3944    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3945    "cmpl       $13, %[nr]\n\t"                       \
     3946    "movdqa     192(%[KEY]), %%xmm12\n\t"             \
     3947    "jl 31f\n\t"                                      \
     3948    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3949    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3950    "movdqu     208(%[KEY]), %%xmm12\n\t"             \
     3951    "aesenc     %%xmm12, " VAR(HR) "\n\t"             \
     3952    "aesenc     %%xmm12, %%xmm1\n\t"                  \
     3953    "movdqu     224(%[KEY]), %%xmm12\n\t"             \
     3954    "31:\n\t"                                         \
     3955    "aesenclast %%xmm12, " VAR(HR) "\n\t"             \
     3956    "aesenclast %%xmm12, %%xmm1\n\t"                  \
     3957    "pshufb     %[BSWAP_MASK], " VAR(HR) "\n\t"       \
     3958    "movdqu     %%xmm1, " VAR(TR) "\n\t"              \
     3959    "jmp        39f\n\t"
     3960
     3961#define CALC_IV()                                    \
     3962    "# Calculate values when IV is not 12 bytes\n\t" \
     3963    "# H = Encrypt X(=0)\n\t"                        \
     3964    "movdqa     0(%[KEY]), " VAR(HR) "\n\t"          \
     3965    AESENC_AVX(HR)                                   \
     3966    "pshufb     %[BSWAP_MASK], " VAR(HR) "\n\t"      \
     3967    "# Calc counter\n\t"                             \
     3968    "# Initialization vector\n\t"                    \
     3969    "cmpl       $0, %%edx\n\t"                       \
     3970    "movq       $0, %%rcx\n\t"                       \
     3971    "je 45f\n\t"                                     \
     3972    "cmpl       $16, %%edx\n\t"                      \
     3973    "jl 44f\n\t"                                     \
     3974    "andl       $0xfffffff0, %%edx\n\t"              \
     3975    "\n"                                             \
     3976    "43:\n\t"                                        \
     3977    "movdqu     (%%rax,%%rcx,1), %%xmm4\n\t"         \
     3978    "pshufb     %[BSWAP_MASK], %%xmm4\n\t"           \
     3979    "pxor       %%xmm4, %%xmm13\n\t"                 \
     3980    GHASH_FULL_AVX(%%xmm13, %%xmm12, %%xmm13, HR)    \
     3981    "addl       $16, %%ecx\n\t"                      \
     3982    "cmpl       %%edx, %%ecx\n\t"                    \
     3983    "jl 43b\n\t"                                     \
     3984    "movl       %[ibytes], %%edx\n\t"                \
     3985    "cmpl       %%edx, %%ecx\n\t"                    \
     3986    "je 45f\n\t"                                     \
     3987    "\n"                                             \
     3988    "44:\n\t"                                        \
     3989    "subq       $16, %%rsp\n\t"                      \
     3990    "pxor       %%xmm4, %%xmm4\n\t"                  \
     3991    "xorl       %%ebx, %%ebx\n\t"                    \
     3992    "movdqu     %%xmm4, (%%rsp)\n\t"                 \
     3993    "42:\n\t"                                        \
     3994    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t"         \
     3995    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t"         \
     3996    "incl       %%ecx\n\t"                           \
     3997    "incl       %%ebx\n\t"                           \
     3998    "cmpl       %%edx, %%ecx\n\t"                    \
     3999    "jl 42b\n\t"                                     \
     4000    "movdqu     (%%rsp), %%xmm4\n\t"                 \
     4001    "addq       $16, %%rsp\n\t"                      \
     4002    "pshufb     %[BSWAP_MASK], %%xmm4\n\t"           \
     4003    "pxor       %%xmm4, %%xmm13\n\t"                 \
     4004    GHASH_FULL_AVX(%%xmm13, %%xmm12, %%xmm13, HR)    \
     4005    "\n"                                             \
     4006    "45:\n\t"                                        \
     4007    "# T = Encrypt counter\n\t"                      \
     4008    "pxor       %%xmm0, %%xmm0\n\t"                  \
     4009    "shll       $3, %%edx\n\t"                       \
     4010    "pinsrq     $0, %%rdx, %%xmm0\n\t"               \
     4011    "pxor       %%xmm0, %%xmm13\n\t"                 \
     4012    GHASH_FULL_AVX(%%xmm13, %%xmm12, %%xmm13, HR)    \
     4013    "pshufb     %[BSWAP_MASK], %%xmm13\n\t"          \
     4014    "#   Encrypt counter\n\t"                        \
     4015    "movdqa     0(%[KEY]), %%xmm4\n\t"               \
     4016    "pxor       %%xmm13, %%xmm4\n\t"                 \
     4017    AESENC_AVX(%%xmm4)                               \
     4018    "movdqu     %%xmm4, " VAR(TR) "\n\t"
     4019
     4020#define CALC_AAD()                           \
     4021    "# Additional authentication data\n\t"   \
     4022    "movl       %[abytes], %%edx\n\t"        \
     4023    "cmpl       $0, %%edx\n\t"               \
     4024    "je         25f\n\t"                     \
     4025    "movq       %[addt], %%rax\n\t"          \
     4026    "xorl       %%ecx, %%ecx\n\t"            \
     4027    "cmpl       $16, %%edx\n\t"              \
     4028    "jl         24f\n\t"                     \
     4029    "andl       $0xfffffff0, %%edx\n\t"      \
     4030    "\n"                                     \
     4031    "23:\n\t"                                \
     4032    "movdqu     (%%rax,%%rcx,1), %%xmm4\n\t" \
     4033    "pshufb     %[BSWAP_MASK], %%xmm4\n\t"   \
     4034    "pxor       %%xmm4, " VAR(XR) "\n\t"     \
     4035    GHASH_FULL_AVX(XR, %%xmm12, XR, HR)      \
     4036    "addl       $16, %%ecx\n\t"              \
     4037    "cmpl       %%edx, %%ecx\n\t"            \
     4038    "jl         23b\n\t"                     \
     4039    "movl       %[abytes], %%edx\n\t"        \
     4040    "cmpl       %%edx, %%ecx\n\t"            \
     4041    "je         25f\n\t"                     \
     4042    "\n"                                     \
     4043    "24:\n\t"                                \
     4044    "subq       $16, %%rsp\n\t"              \
     4045    "pxor       %%xmm4, %%xmm4\n\t"          \
     4046    "xorl       %%ebx, %%ebx\n\t"            \
     4047    "movdqu     %%xmm4, (%%rsp)\n\t"         \
     4048    "22:\n\t"                                \
     4049    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t" \
     4050    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t" \
     4051    "incl       %%ecx\n\t"                   \
     4052    "incl       %%ebx\n\t"                   \
     4053    "cmpl       %%edx, %%ecx\n\t"            \
     4054    "jl         22b\n\t"                     \
     4055    "movdqu     (%%rsp), %%xmm4\n\t"         \
     4056    "addq       $16, %%rsp\n\t"              \
     4057    "pshufb     %[BSWAP_MASK], %%xmm4\n\t"   \
     4058    "pxor       %%xmm4, " VAR(XR) "\n\t"     \
     4059    GHASH_FULL_AVX(XR, %%xmm12, XR, HR)      \
     4060    "\n"                                     \
     4061    "25:\n\t"
     4062
     4063#define CALC_HT_8_AVX()                            \
     4064    "movdqa     " VAR(XR) ", %%xmm2\n\t"           \
     4065    "# H ^ 1\n\t"                                  \
     4066    "movdqu     " VAR(HR) ", 0(" VAR(HTR) ")\n\t"  \
     4067    "# H ^ 2\n\t"                                  \
     4068    GHASH_GFMUL_RED_AVX(%%xmm0, HR, HR)            \
     4069    "movdqu     %%xmm0 ,  16(" VAR(HTR) ")\n\t"    \
     4070    "# H ^ 3\n\t"                                  \
     4071    GHASH_GFMUL_RED_AVX(%%xmm1, HR, %%xmm0)        \
     4072    "movdqu     %%xmm1 ,  32(" VAR(HTR) ")\n\t"    \
     4073    "# H ^ 4\n\t"                                  \
     4074    GHASH_GFMUL_RED_AVX(%%xmm3, %%xmm0, %%xmm0)    \
     4075    "movdqu     %%xmm3 ,  48(" VAR(HTR) ")\n\t"    \
     4076    "# H ^ 5\n\t"                                  \
     4077    GHASH_GFMUL_RED_AVX(%%xmm12, %%xmm0, %%xmm1)   \
     4078    "movdqu     %%xmm12,  64(" VAR(HTR) ")\n\t"    \
     4079    "# H ^ 6\n\t"                                  \
     4080    GHASH_GFMUL_RED_AVX(%%xmm12, %%xmm1, %%xmm1)   \
     4081    "movdqu     %%xmm12,  80(" VAR(HTR) ")\n\t"    \
     4082    "# H ^ 7\n\t"                                  \
     4083    GHASH_GFMUL_RED_AVX(%%xmm12, %%xmm1, %%xmm3)   \
     4084    "movdqu     %%xmm12,  96(" VAR(HTR) ")\n\t"    \
     4085    "# H ^ 8\n\t"                                  \
     4086    GHASH_GFMUL_RED_AVX(%%xmm12, %%xmm3, %%xmm3)   \
     4087    "movdqu     %%xmm12, 112(" VAR(HTR) ")\n\t"
     4088
     4089#define AESENC_128_GHASH_AVX(src, o)                 \
     4090    "leaq       (%[in]," VAR(KR64) ",1), %%rcx\n\t"  \
     4091    "leaq       (%[out]," VAR(KR64) ",1), %%rdx\n\t" \
     4092    /* src is either %%rcx or %%rdx */               \
     4093    AESENC_CTR()                                     \
     4094    AESENC_XOR()                                     \
     4095    AESENC_PCLMUL_1(src,  16, o-128, 112)            \
     4096    AESENC_PCLMUL_N(src,  32, o-112,  96)            \
     4097    AESENC_PCLMUL_N(src,  48, o -96,  80)            \
     4098    AESENC_PCLMUL_N(src,  64, o -80,  64)            \
     4099    AESENC_PCLMUL_N(src,  80, o -64,  48)            \
     4100    AESENC_PCLMUL_N(src,  96, o -48,  32)            \
     4101    AESENC_PCLMUL_N(src, 112, o -32,  16)            \
     4102    AESENC_PCLMUL_N(src, 128, o -16,   0)            \
     4103    AESENC_PCLMUL_L(144)                             \
     4104    "cmpl       $11, %[nr]\n\t"                      \
     4105    "movdqa     160(%[KEY]), %%xmm12\n\t"            \
     4106    "jl         4f\n\t"                              \
     4107    AESENC()                                         \
     4108    AESENC_SET(176)                                  \
     4109    "cmpl       $13, %[nr]\n\t"                      \
     4110    "movdqa     192(%[KEY]), %%xmm12\n\t"            \
     4111    "jl         4f\n\t"                              \
     4112    AESENC()                                         \
     4113    AESENC_SET(208)                                  \
     4114    "movdqa     224(%[KEY]), %%xmm12\n\t"            \
     4115    "\n"                                             \
     4116"4:\n\t"                                             \
     4117    AESENC_LAST(%%rcx, %%rdx)
     4118
     4119#define AESENC_LAST15_ENC_AVX()                       \
     4120    "movl       %[nbytes], %%ecx\n\t"                 \
     4121    "movl       %%ecx, %%edx\n\t"                     \
     4122    "andl       $0x0f, %%ecx\n\t"                     \
     4123    "jz         55f\n\t"                              \
     4124    "movdqu     " VAR(CTR1) ", %%xmm13\n\t"           \
     4125    "pshufb     %[BSWAP_EPI64], %%xmm13\n\t"          \
     4126    "pxor       0(%[KEY]), %%xmm13\n\t"               \
     4127    AESENC_AVX(%%xmm13)                               \
     4128    "subq       $16, %%rsp\n\t"                       \
     4129    "xorl       %%ecx, %%ecx\n\t"                     \
     4130    "movdqu     %%xmm13, (%%rsp)\n\t"                 \
     4131    "\n"                                              \
     4132    "51:\n\t"                                         \
     4133    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"  \
     4134    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"          \
     4135    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t" \
     4136    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"          \
     4137    "incl       " VAR(KR) "\n\t"                      \
     4138    "incl       %%ecx\n\t"                            \
     4139    "cmpl       %%edx, " VAR(KR) "\n\t"               \
     4140    "jl         51b\n\t"                              \
     4141    "xorq       %%r13, %%r13\n\t"                     \
     4142    "cmpl       $16, %%ecx\n\t"                       \
     4143    "je         53f\n\t"                              \
     4144    "\n"                                              \
     4145    "52:\n\t"                                         \
     4146    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"          \
     4147    "incl       %%ecx\n\t"                            \
     4148    "cmpl       $16, %%ecx\n\t"                       \
     4149    "jl         52b\n\t"                              \
     4150    "53:\n\t"                                         \
     4151    "movdqu     (%%rsp), %%xmm13\n\t"                 \
     4152    "addq       $16, %%rsp\n\t"                       \
     4153    "pshufb     %[BSWAP_MASK], %%xmm13\n\t"           \
     4154    "pxor       %%xmm13, " VAR(XR) "\n\t"             \
     4155    GHASH_GFMUL_RED_AVX(XR, HR, XR)                   \
     4156
     4157#define AESENC_LAST15_DEC_AVX()                       \
     4158    "movl       %[nbytes], %%ecx\n\t"                 \
     4159    "movl       %%ecx, %%edx\n\t"                     \
     4160    "andl       $0x0f, %%ecx\n\t"                     \
     4161    "jz         55f\n\t"                              \
     4162    "movdqu     " VAR(CTR1) ", %%xmm13\n\t"           \
     4163    "pshufb     %[BSWAP_EPI64], %%xmm13\n\t"          \
     4164    "pxor       0(%[KEY]), %%xmm13\n\t"               \
     4165    AESENC_AVX(%%xmm13)                               \
     4166    "subq       $32, %%rsp\n\t"                       \
     4167    "xorl       %%ecx, %%ecx\n\t"                     \
     4168    "movdqu     %%xmm13, (%%rsp)\n\t"                 \
     4169    "pxor       %%xmm0, %%xmm0\n\t"                   \
     4170    "movdqu     %%xmm0, 16(%%rsp)\n\t"                \
     4171    "\n"                                              \
     4172    "51:\n\t"                                         \
     4173    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"  \
     4174    "movb       %%r13b, 16(%%rsp,%%rcx,1)\n\t"        \
     4175    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"          \
     4176    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t" \
     4177    "incl       " VAR(KR) "\n\t"                      \
     4178    "incl       %%ecx\n\t"                            \
     4179    "cmpl       %%edx, " VAR(KR) "\n\t"               \
     4180    "jl         51b\n\t"                              \
     4181    "53:\n\t"                                         \
     4182    "movdqu     16(%%rsp), %%xmm13\n\t"               \
     4183    "addq       $32, %%rsp\n\t"                       \
     4184    "pshufb     %[BSWAP_MASK], %%xmm13\n\t"           \
     4185    "pxor       %%xmm13, " VAR(XR) "\n\t"             \
     4186    GHASH_GFMUL_RED_AVX(XR, HR, XR)                   \
     4187
     4188#define CALC_TAG()                              \
     4189    "movl       %[nbytes], %%edx\n\t"           \
     4190    "movl       %[abytes], %%ecx\n\t"           \
     4191    "shlq       $3, %%rdx\n\t"                  \
     4192    "shlq       $3, %%rcx\n\t"                  \
     4193    "pinsrq     $0, %%rdx, %%xmm0\n\t"          \
     4194    "pinsrq     $1, %%rcx, %%xmm0\n\t"          \
     4195    "pxor       %%xmm0, " VAR(XR) "\n\t"        \
     4196    GHASH_GFMUL_RED_AVX(XR, HR, XR)             \
     4197    "pshufb     %[BSWAP_MASK], " VAR(XR) "\n\t" \
     4198    "movdqu     " VAR(TR) ", %%xmm0\n\t"        \
     4199    "pxor       " VAR(XR) ", %%xmm0\n\t"        \
     4200
     4201#define STORE_TAG()                           \
     4202    "cmpl       $16, %[tbytes]\n\t"           \
     4203    "je         71f\n\t"                      \
     4204    "xorq       %%rcx, %%rcx\n\t"             \
     4205    "movdqu     %%xmm0, (%%rsp)\n\t"          \
     4206    "73:\n\t"                                 \
     4207    "movzbl     (%%rsp,%%rcx,1), %%r13d\n\t"  \
     4208    "movb       %%r13b, (%[tag],%%rcx,1)\n\t" \
     4209    "incl       %%ecx\n\t"                    \
     4210    "cmpl       %[tbytes], %%ecx\n\t"         \
     4211    "jne        73b\n\t"                      \
     4212    "jmp        72f\n\t"                      \
     4213    "\n"                                      \
     4214    "71:\n\t"                                 \
     4215    "movdqu     %%xmm0, (%[tag])\n\t"         \
     4216    "\n"                                      \
     4217    "72:\n\t"
     4218
     4219#define CMP_TAG()                                          \
     4220    "cmpl       $16, %[tbytes]\n\t"                        \
     4221    "je         71f\n\t"                                   \
     4222    "subq       $16, %%rsp\n\t"                            \
     4223    "xorq       %%rcx, %%rcx\n\t"                          \
     4224    "xorq       %%rax, %%rax\n\t"                          \
     4225    "movdqu     %%xmm0, (%%rsp)\n\t"                       \
     4226    "\n"                                                   \
     4227    "73:\n\t"                                              \
     4228    "movzbl     (%%rsp,%%rcx,1), %%r13d\n\t"               \
     4229    "xorb       (%[tag],%%rcx,1), %%r13b\n\t"              \
     4230    "orb        %%r13b, %%al\n\t"                          \
     4231    "incl       %%ecx\n\t"                                 \
     4232    "cmpl       %[tbytes], %%ecx\n\t"                      \
     4233    "jne        73b\n\t"                                   \
     4234    "cmpb       $0x00, %%al\n\t"                           \
     4235    "sete       %%al\n\t"                                  \
     4236    "addq       $16, %%rsp\n\t"                            \
     4237    "xorq       %%rcx, %%rcx\n\t"                          \
     4238    "jmp        72f\n\t"                                   \
     4239    "\n"                                                   \
     4240    "71:\n\t"                                              \
     4241    "movdqu     (%[tag]), %%xmm1\n\t"                      \
     4242    "pcmpeqb    %%xmm1, %%xmm0\n\t"                        \
     4243    "pmovmskb   %%xmm0, %%edx\n\t"                         \
     4244    "# %%edx == 0xFFFF then return 1 else => return 0\n\t" \
     4245    "xorl       %%eax, %%eax\n\t"                          \
     4246    "cmpl       $0xffff, %%edx\n\t"                        \
     4247    "sete       %%al\n\t"                                  \
     4248    "\n"                                                   \
     4249    "72:\n\t"                                              \
     4250    "movl       %%eax, (%[res])\n\t"
     4251
     4252static void AES_GCM_encrypt(const unsigned char *in, unsigned char *out,
     4253                            const unsigned char* addt,
     4254                            const unsigned char* ivec, unsigned char *tag,
     4255                            unsigned int nbytes, unsigned int abytes,
     4256                            unsigned int ibytes, unsigned int tbytes,
     4257                            const unsigned char* key, int nr)
     4258{
     4259    register const unsigned char* iv asm("rax") = ivec;
     4260    register unsigned int ivLen asm("ebx") = ibytes;
     4261
     4262    __asm__ __volatile__ (
     4263        "subq   $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     4264        /* Counter is xmm13 */
     4265        "pxor   %%xmm13, %%xmm13\n\t"
     4266        "pxor   " VAR(XR) ", " VAR(XR) "\n\t"
     4267        "movl   %[ibytes], %%edx\n\t"
     4268        "cmpl   $12, %%edx\n\t"
     4269        "jne    35f\n\t"
     4270        CALC_IV_12()
     4271        "\n"
     4272        "35:\n\t"
     4273        CALC_IV()
     4274        "\n"
     4275        "39:\n\t"
     4276
     4277        CALC_AAD()
     4278
     4279        "# Calculate counter and H\n\t"
     4280        "pshufb %[BSWAP_EPI64], %%xmm13\n\t"
     4281        "movdqa " VAR(HR) ", %%xmm5\n\t"
     4282        "paddd  %[ONE], %%xmm13\n\t"
     4283        "movdqa " VAR(HR) ", %%xmm4\n\t"
     4284        "movdqu %%xmm13, " VAR(CTR1) "\n\t"
     4285        "psrlq  $63, %%xmm5\n\t"
     4286        "psllq  $1, %%xmm4\n\t"
     4287        "pslldq $8, %%xmm5\n\t"
     4288        "por    %%xmm5, %%xmm4\n\t"
     4289        "pshufd $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     4290        "psrad  $31, " VAR(HR) "\n\t"
     4291        "pand   %[MOD2_128], " VAR(HR) "\n\t"
     4292        "pxor   %%xmm4, " VAR(HR) "\n\t"
     4293
     4294        "xorl   " VAR(KR) ", " VAR(KR) "\n\t"
     4295
     4296#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     4297        "cmpl   $128, %[nbytes]\n\t"
     4298        "movl   %[nbytes], %%r13d\n\t"
     4299        "jl     5f\n\t"
     4300        "andl   $0xffffff80, %%r13d\n\t"
     4301
     4302        CALC_HT_8_AVX()
     4303
     4304        "# First 128 bytes of input\n\t"
     4305        AESENC_CTR()
     4306        AESENC_XOR()
     4307        AESENC_SET(16)
     4308        AESENC_SET(32)
     4309        AESENC_SET(48)
     4310        AESENC_SET(64)
     4311        AESENC_SET(80)
     4312        AESENC_SET(96)
     4313        AESENC_SET(112)
     4314        AESENC_SET(128)
     4315        AESENC_SET(144)
     4316        "cmpl   $11, %[nr]\n\t"
     4317        "movdqa 160(%[KEY]), %%xmm12\n\t"
     4318        "jl     1f\n\t"
     4319        AESENC()
     4320        AESENC_SET(176)
     4321        "cmpl   $13, %[nr]\n\t"
     4322        "movdqa 192(%[KEY]), %%xmm12\n\t"
     4323        "jl     1f\n\t"
     4324        AESENC()
     4325        AESENC_SET(208)
     4326        "movdqa 224(%[KEY]), %%xmm12\n\t"
     4327        "\n"
     4328    "1:\n\t"
     4329        AESENC_LAST(%[in], %[out])
     4330
     4331        "cmpl   $128, %%r13d\n\t"
     4332        "movl   $128, " VAR(KR) "\n\t"
     4333        "jle    2f\n\t"
     4334
     4335        "# More 128 bytes of input\n\t"
     4336        "\n"
     4337    "3:\n\t"
     4338        AESENC_128_GHASH_AVX(%%rdx, 0)
     4339        "addl   $128, " VAR(KR) "\n\t"
     4340        "cmpl   %%r13d, " VAR(KR) "\n\t"
     4341        "jl     3b\n\t"
     4342        "\n"
     4343    "2:\n\t"
     4344        "movdqa %[BSWAP_MASK], %%xmm13\n\t"
     4345        "pshufb %%xmm13, %%xmm4\n\t"
     4346        "pshufb %%xmm13, %%xmm5\n\t"
     4347        "pshufb %%xmm13, %%xmm6\n\t"
     4348        "pshufb %%xmm13, %%xmm7\n\t"
     4349        "pxor   %%xmm2, %%xmm4\n\t"
     4350        "pshufb %%xmm13, %%xmm8\n\t"
     4351        "pshufb %%xmm13, %%xmm9\n\t"
     4352        "pshufb %%xmm13, %%xmm10\n\t"
     4353        "pshufb %%xmm13, %%xmm11\n\t"
     4354
     4355        "movdqu 112(" VAR(HTR) "), %%xmm12\n\t"
     4356        GHASH_GFMUL_AVX(XR, %%xmm13, %%xmm4, %%xmm12)
     4357        "movdqu  96(" VAR(HTR) "), %%xmm12\n\t"
     4358        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm5, %%xmm12)
     4359        "movdqu  80(" VAR(HTR) "), %%xmm12\n\t"
     4360        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm6, %%xmm12)
     4361        "movdqu  64(" VAR(HTR) "), %%xmm12\n\t"
     4362        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm7, %%xmm12)
     4363        "movdqu  48(" VAR(HTR) "), %%xmm12\n\t"
     4364        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm8, %%xmm12)
     4365        "movdqu  32(" VAR(HTR) "), %%xmm12\n\t"
     4366        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm9, %%xmm12)
     4367        "movdqu  16(" VAR(HTR) "), %%xmm12\n\t"
     4368        GHASH_GFMUL_XOR_AVX(XR, %%xmm13, %%xmm10, %%xmm12)
     4369        "movdqu    (" VAR(HTR) "), %%xmm12\n\t"
     4370        GHASH_GFMUL_RED_XOR_AVX(XR, %%xmm13, %%xmm11, %%xmm12)
     4371
     4372        "movdqu 0(" VAR(HTR) "), " VAR(HR) "\n\t"
     4373        "\n"
     4374    "5:\n\t"
     4375        "movl   %[nbytes], %%edx\n\t"
     4376        "cmpl   %%edx, " VAR(KR) "\n\t"
     4377        "jge    55f\n\t"
     4378#endif
     4379
     4380        "movl   %[nbytes], %%r13d\n\t"
     4381        "andl   $0xfffffff0, %%r13d\n\t"
     4382        "cmpl   %%r13d, " VAR(KR) "\n\t"
     4383        "jge    14f\n\t"
     4384
     4385        "leaq   (%[in]," VAR(KR64) ",1), %%rcx\n\t"
     4386        "leaq   (%[out]," VAR(KR64) ",1), %%rdx\n\t"
     4387        AESENC_BLOCK(%%rcx, %%rdx)
     4388        "addl   $16, " VAR(KR) "\n\t"
     4389        "cmpl   %%r13d, " VAR(KR) "\n\t"
     4390        "jge    13f\n\t"
     4391        "\n"
     4392        "12:\n\t"
     4393        "leaq   (%[in]," VAR(KR64) ",1), %%rcx\n\t"
     4394        "leaq   (%[out]," VAR(KR64) ",1), %%rdx\n\t"
     4395        AESENC_GFMUL(%%rcx, %%rdx, HR, XR)
     4396        "pshufb %[BSWAP_MASK], %%xmm4\n\t"
     4397        "pxor   %%xmm4, " VAR(XR) "\n\t"
     4398        "addl   $16, " VAR(KR) "\n\t"
     4399        "cmpl   %%r13d, " VAR(KR) "\n\t"
     4400        "jl     12b\n\t"
     4401        "\n"
     4402        "13:\n\t"
     4403        GHASH_GFMUL_RED_AVX(XR, HR, XR)
     4404        "\n"
     4405        "14:\n\t"
     4406
     4407        AESENC_LAST15_ENC_AVX()
     4408        "\n"
     4409        "55:\n\t"
     4410
     4411        CALC_TAG()
     4412        STORE_TAG()
     4413        "addq   $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     4414
     4415        :
     4416        : [KEY] "r" (key),
     4417          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     4418          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     4419          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tbytes),
     4420          [tag] "r" (tag),
     4421          [BSWAP_MASK] "m" (BSWAP_MASK),
     4422          [BSWAP_EPI64] "m" (BSWAP_EPI64),
     4423          [ONE] "m" (ONE),
     4424#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     4425          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     4426          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     4427          [EIGHT] "m" (EIGHT),
     4428#endif
     4429          [MOD2_128] "m" (MOD2_128)
     4430        : "xmm15", "xmm14", "xmm13", "xmm12",
     4431          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     4432          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     4433          "rcx", "rdx", "r13"
     4434    );
     4435}
     4436
     4437#ifdef HAVE_INTEL_AVX1
     4438/* Encrypt with key in xmm12. */
     4439#define VAESENC()                              \
     4440    "vaesenc    %%xmm12, %%xmm4, %%xmm4\n\t"   \
     4441    "vaesenc    %%xmm12, %%xmm5, %%xmm5\n\t"   \
     4442    "vaesenc    %%xmm12, %%xmm6, %%xmm6\n\t"   \
     4443    "vaesenc    %%xmm12, %%xmm7, %%xmm7\n\t"   \
     4444    "vaesenc    %%xmm12, %%xmm8, %%xmm8\n\t"   \
     4445    "vaesenc    %%xmm12, %%xmm9, %%xmm9\n\t"   \
     4446    "vaesenc    %%xmm12, %%xmm10, %%xmm10\n\t" \
     4447    "vaesenc    %%xmm12, %%xmm11, %%xmm11\n\t"
     4448
     4449#define VAESENC_SET(o)                         \
     4450    "vmovdqa    "#o"(%[KEY]), %%xmm12\n\t"     \
     4451    VAESENC()
     4452
     4453#define VAESENC_CTR()                          \
     4454    "vmovdqu    " VAR(CTR1) ", %%xmm0\n\t"     \
     4455    "vmovdqa    %[BSWAP_EPI64], %%xmm1\n\t"    \
     4456    "vpshufb    %%xmm1, %%xmm0, %%xmm4\n\t"    \
     4457    "vpaddd     %[ONE], %%xmm0, %%xmm5\n\t"    \
     4458    "vpshufb    %%xmm1, %%xmm5, %%xmm5\n\t"    \
     4459    "vpaddd     %[TWO], %%xmm0, %%xmm6\n\t"    \
     4460    "vpshufb    %%xmm1, %%xmm6, %%xmm6\n\t"    \
     4461    "vpaddd     %[THREE], %%xmm0, %%xmm7\n\t"  \
     4462    "vpshufb    %%xmm1, %%xmm7, %%xmm7\n\t"    \
     4463    "vpaddd     %[FOUR], %%xmm0, %%xmm8\n\t"   \
     4464    "vpshufb    %%xmm1, %%xmm8, %%xmm8\n\t"    \
     4465    "vpaddd     %[FIVE], %%xmm0, %%xmm9\n\t"   \
     4466    "vpshufb    %%xmm1, %%xmm9, %%xmm9\n\t"    \
     4467    "vpaddd     %[SIX], %%xmm0, %%xmm10\n\t"   \
     4468    "vpshufb    %%xmm1, %%xmm10, %%xmm10\n\t"  \
     4469    "vpaddd     %[SEVEN], %%xmm0, %%xmm11\n\t" \
     4470    "vpshufb    %%xmm1, %%xmm11, %%xmm11\n\t"  \
     4471    "vpaddd     %[EIGHT], %%xmm0, %%xmm0\n\t"
     4472
     4473#define VAESENC_XOR()                          \
     4474    "vmovdqa    (%[KEY]), %%xmm12\n\t"         \
     4475    "vmovdqu    %%xmm0, " VAR(CTR1) "\n\t"     \
     4476    "vpxor      %%xmm12, %%xmm4, %%xmm4\n\t"   \
     4477    "vpxor      %%xmm12, %%xmm5, %%xmm5\n\t"   \
     4478    "vpxor      %%xmm12, %%xmm6, %%xmm6\n\t"   \
     4479    "vpxor      %%xmm12, %%xmm7, %%xmm7\n\t"   \
     4480    "vpxor      %%xmm12, %%xmm8, %%xmm8\n\t"   \
     4481    "vpxor      %%xmm12, %%xmm9, %%xmm9\n\t"   \
     4482    "vpxor      %%xmm12, %%xmm10, %%xmm10\n\t" \
     4483    "vpxor      %%xmm12, %%xmm11, %%xmm11\n\t"
     4484
     4485#define VAESENC_128()                     \
     4486    VAESENC_CTR()                         \
     4487    VAESENC_XOR()                         \
     4488    VAESENC_SET(16)                       \
     4489    VAESENC_SET(32)                       \
     4490    VAESENC_SET(48)                       \
     4491    VAESENC_SET(64)                       \
     4492    VAESENC_SET(80)                       \
     4493    VAESENC_SET(96)                       \
     4494    VAESENC_SET(112)                      \
     4495    VAESENC_SET(128)                      \
     4496    VAESENC_SET(144)                      \
     4497    "cmpl       $11, %[nr]\n\t"           \
     4498    "vmovdqa    160(%[KEY]), %%xmm12\n\t" \
     4499    "jl 1f\n\t"                           \
     4500    VAESENC()                             \
     4501    VAESENC_SET(176)                      \
     4502    "cmpl       $13, %[nr]\n\t"           \
     4503    "vmovdqa    192(%[KEY]), %%xmm12\n\t" \
     4504    "jl 1f\n\t"                           \
     4505    VAESENC()                             \
     4506    VAESENC_SET(208)                      \
     4507    "vmovdqa    224(%[KEY]), %%xmm12\n\t" \
     4508    "\n"                                  \
     4509"1:\n\t"                                  \
     4510    VAESENC_LAST(%[in], %[out])
     4511
     4512/* Encrypt and carry-less multiply for AVX1. */
     4513#define VAESENC_PCLMUL_1(src, o1, o2, o3)              \
     4514    "vmovdqu    " #o3 "(" VAR(HTR) "), %%xmm12\n\t"    \
     4515    "vmovdqu    " #o2 "(" #src "), %%xmm0\n\t"         \
     4516    "vaesenc    " #o1 "(%[KEY]), %%xmm4, %%xmm4\n\t"   \
     4517    "vpshufb    %[BSWAP_MASK], %%xmm0, %%xmm0\n\t"     \
     4518    "vpxor      %%xmm2, %%xmm0, %%xmm0\n\t"            \
     4519    "vpshufd    $0x4e, %%xmm12, %%xmm1\n\t"            \
     4520    "vpshufd    $0x4e, %%xmm0, %%xmm14\n\t"            \
     4521    "vpxor      %%xmm12, %%xmm1, %%xmm1\n\t"           \
     4522    "vpxor      %%xmm0, %%xmm14, %%xmm14\n\t"          \
     4523    "vpclmulqdq $0x11, %%xmm12, %%xmm0, %%xmm3\n\t"    \
     4524    "vaesenc    " #o1 "(%[KEY]), %%xmm5, %%xmm5\n\t"   \
     4525    "vaesenc    " #o1 "(%[KEY]), %%xmm6, %%xmm6\n\t"   \
     4526    "vpclmulqdq $0x00, %%xmm12, %%xmm0, %%xmm2\n\t"    \
     4527    "vaesenc    " #o1 "(%[KEY]), %%xmm7, %%xmm7\n\t"   \
     4528    "vaesenc    " #o1 "(%[KEY]), %%xmm8, %%xmm8\n\t"   \
     4529    "vpclmulqdq $0x00, %%xmm14, %%xmm1, %%xmm1\n\t"    \
     4530    "vaesenc    " #o1 "(%[KEY]), %%xmm9, %%xmm9\n\t"   \
     4531    "vaesenc    " #o1 "(%[KEY]), %%xmm10, %%xmm10\n\t" \
     4532    "vaesenc    " #o1 "(%[KEY]), %%xmm11, %%xmm11\n\t" \
     4533    "vpxor      %%xmm2, %%xmm1, %%xmm1\n\t"            \
     4534    "vpxor      %%xmm3, %%xmm1, %%xmm1\n\t"            \
     4535
     4536#define VAESENC_PCLMUL_N(src, o1, o2, o3)               \
     4537    "vmovdqu    " #o3 "(" VAR(HTR) "), %%xmm12\n\t"     \
     4538    "vmovdqu    " #o2 "(" #src "), %%xmm0\n\t"          \
     4539    "vpshufd    $0x4e, %%xmm12, %%xmm13\n\t"            \
     4540    "vpshufb    %[BSWAP_MASK], %%xmm0, %%xmm0\n\t"      \
     4541    "vaesenc    " #o1 "(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     4542    "vpxor      %%xmm12, %%xmm13, %%xmm13\n\t"          \
     4543    "vpshufd    $0x4e, %%xmm0, %%xmm14\n\t"             \
     4544    "vpxor      %%xmm0, %%xmm14, %%xmm14\n\t"           \
     4545    "vpclmulqdq $0x11, %%xmm12, %%xmm0, %%xmm15\n\t"    \
     4546    "vaesenc    " #o1 "(%[KEY]), %%xmm5, %%xmm5\n\t"    \
     4547    "vaesenc    " #o1 "(%[KEY]), %%xmm6, %%xmm6\n\t"    \
     4548    "vpclmulqdq $0x00, %%xmm12, %%xmm0, %%xmm12\n\t"    \
     4549    "vaesenc    " #o1 "(%[KEY]), %%xmm7, %%xmm7\n\t"    \
     4550    "vaesenc    " #o1 "(%[KEY]), %%xmm8, %%xmm8\n\t"    \
     4551    "vpclmulqdq $0x00, %%xmm14, %%xmm13, %%xmm13\n\t"   \
     4552    "vaesenc    " #o1 "(%[KEY]), %%xmm9, %%xmm9\n\t"    \
     4553    "vaesenc    " #o1 "(%[KEY]), %%xmm10, %%xmm10\n\t"  \
     4554    "vaesenc    " #o1 "(%[KEY]), %%xmm11, %%xmm11\n\t"  \
     4555    "vpxor      %%xmm12, %%xmm1, %%xmm1\n\t"            \
     4556    "vpxor      %%xmm12, %%xmm2, %%xmm2\n\t"            \
     4557    "vpxor      %%xmm15, %%xmm1, %%xmm1\n\t"            \
     4558    "vpxor      %%xmm15, %%xmm3, %%xmm3\n\t"            \
     4559    "vpxor      %%xmm13, %%xmm1, %%xmm1\n\t"            \
     4560
     4561#define VAESENC_PCLMUL_L(o)                         \
     4562    "vpslldq    $8, %%xmm1, %%xmm14\n\t"            \
     4563    "vpsrldq    $8, %%xmm1, %%xmm1\n\t"             \
     4564    "vaesenc    "#o"(%[KEY]), %%xmm4, %%xmm4\n\t"   \
     4565    "vpxor      %%xmm14, %%xmm2, %%xmm2\n\t"        \
     4566    "vpxor      %%xmm1, %%xmm3, %%xmm3\n\t"         \
     4567    "vaesenc    "#o"(%[KEY]), %%xmm5, %%xmm5\n\t"   \
     4568    "vpslld     $31, %%xmm2, %%xmm12\n\t"           \
     4569    "vpslld     $30, %%xmm2, %%xmm13\n\t"           \
     4570    "vpslld     $25, %%xmm2, %%xmm14\n\t"           \
     4571    "vaesenc    "#o"(%[KEY]), %%xmm6, %%xmm6\n\t"   \
     4572    "vpxor      %%xmm13, %%xmm12, %%xmm12\n\t"      \
     4573    "vpxor      %%xmm14, %%xmm12, %%xmm12\n\t"      \
     4574    "vaesenc    "#o"(%[KEY]), %%xmm7, %%xmm7\n\t"   \
     4575    "vpsrldq    $4, %%xmm12, %%xmm13\n\t"           \
     4576    "vpslldq    $12, %%xmm12, %%xmm12\n\t"          \
     4577    "vaesenc    "#o"(%[KEY]), %%xmm8, %%xmm8\n\t"   \
     4578    "vpxor      %%xmm12, %%xmm2, %%xmm2\n\t"        \
     4579    "vpsrld     $1, %%xmm2, %%xmm14\n\t"            \
     4580    "vaesenc    "#o"(%[KEY]), %%xmm9, %%xmm9\n\t"   \
     4581    "vpsrld     $2, %%xmm2, %%xmm1\n\t"             \
     4582    "vpsrld     $7, %%xmm2, %%xmm0\n\t"             \
     4583    "vaesenc    "#o"(%[KEY]), %%xmm10, %%xmm10\n\t" \
     4584    "vpxor      %%xmm1, %%xmm14, %%xmm14\n\t"       \
     4585    "vpxor      %%xmm0, %%xmm14, %%xmm14\n\t"       \
     4586    "vaesenc    "#o"(%[KEY]), %%xmm11, %%xmm11\n\t" \
     4587    "vpxor      %%xmm13, %%xmm14, %%xmm14\n\t"      \
     4588    "vpxor      %%xmm14, %%xmm2, %%xmm2\n\t"        \
     4589    "vpxor      %%xmm3, %%xmm2, %%xmm2\n\t"         \
     4590
     4591
     4592/* Encrypt and carry-less multiply with last key. */
     4593#define VAESENC_LAST(in, out)                          \
     4594    "vaesenclast        %%xmm12, %%xmm4, %%xmm4\n\t"   \
     4595    "vaesenclast        %%xmm12, %%xmm5, %%xmm5\n\t"   \
     4596    "vmovdqu               (" #in "), %%xmm0\n\t"      \
     4597    "vmovdqu             16(" #in "), %%xmm1\n\t"      \
     4598    "vpxor              %%xmm0, %%xmm4, %%xmm4\n\t"    \
     4599    "vpxor              %%xmm1, %%xmm5, %%xmm5\n\t"    \
     4600    "vmovdqu            %%xmm4,    (" #out ")\n\t"     \
     4601    "vmovdqu            %%xmm5,  16(" #out ")\n\t"     \
     4602    "vaesenclast        %%xmm12, %%xmm6, %%xmm6\n\t"   \
     4603    "vaesenclast        %%xmm12, %%xmm7, %%xmm7\n\t"   \
     4604    "vmovdqu             32(" #in "), %%xmm0\n\t"      \
     4605    "vmovdqu             48(" #in "), %%xmm1\n\t"      \
     4606    "vpxor              %%xmm0, %%xmm6, %%xmm6\n\t"    \
     4607    "vpxor              %%xmm1, %%xmm7, %%xmm7\n\t"    \
     4608    "vmovdqu            %%xmm6,  32(" #out ")\n\t"     \
     4609    "vmovdqu            %%xmm7,  48(" #out ")\n\t"     \
     4610    "vaesenclast        %%xmm12, %%xmm8, %%xmm8\n\t"   \
     4611    "vaesenclast        %%xmm12, %%xmm9, %%xmm9\n\t"   \
     4612    "vmovdqu             64(" #in "), %%xmm0\n\t"      \
     4613    "vmovdqu             80(" #in "), %%xmm1\n\t"      \
     4614    "vpxor              %%xmm0, %%xmm8, %%xmm8\n\t"    \
     4615    "vpxor              %%xmm1, %%xmm9, %%xmm9\n\t"    \
     4616    "vmovdqu            %%xmm8,  64(" #out ")\n\t"     \
     4617    "vmovdqu            %%xmm9,  80(" #out ")\n\t"     \
     4618    "vaesenclast        %%xmm12, %%xmm10, %%xmm10\n\t" \
     4619    "vaesenclast        %%xmm12, %%xmm11, %%xmm11\n\t" \
     4620    "vmovdqu             96(" #in "), %%xmm0\n\t"      \
     4621    "vmovdqu            112(" #in "), %%xmm1\n\t"      \
     4622    "vpxor              %%xmm0, %%xmm10, %%xmm10\n\t"  \
     4623    "vpxor              %%xmm1, %%xmm11, %%xmm11\n\t"  \
     4624    "vmovdqu            %%xmm10,  96(" #out ")\n\t"    \
     4625    "vmovdqu            %%xmm11, 112(" #out ")\n\t"
     4626
     4627#define VAESENC_BLOCK()                                       \
     4628    "vmovdqu            " VAR(CTR1) ", %%xmm5\n\t"            \
     4629    "vpshufb            %[BSWAP_EPI64], %%xmm5, %%xmm4\n\t"   \
     4630    "vpaddd             %[ONE], %%xmm5, %%xmm5\n\t"           \
     4631    "vmovdqu            %%xmm5, " VAR(CTR1) "\n\t"            \
     4632    "vpxor              (%[KEY]), %%xmm4, %%xmm4\n\t"         \
     4633    "vaesenc            16(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4634    "vaesenc            32(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4635    "vaesenc            48(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4636    "vaesenc            64(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4637    "vaesenc            80(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4638    "vaesenc            96(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4639    "vaesenc            112(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4640    "vaesenc            128(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4641    "vaesenc            144(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4642    "cmpl               $11, %[nr]\n\t"                       \
     4643    "vmovdqa            160(%[KEY]), %%xmm5\n\t"              \
     4644    "jl                 %=f\n\t"                              \
     4645    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4646    "vaesenc            176(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4647    "cmpl               $13, %[nr]\n\t"                       \
     4648    "vmovdqa            192(%[KEY]), %%xmm5\n\t"              \
     4649    "jl                 %=f\n\t"                              \
     4650    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4651    "vaesenc            208(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4652    "vmovdqa            224(%[KEY]), %%xmm5\n\t"              \
     4653    "%=:\n\t"                                                 \
     4654    "vaesenclast        %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4655    "vmovdqu            (%[in]," VAR(KR64) ",1), %%xmm5\n\t"  \
     4656    "vpxor              %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4657    "vmovdqu            %%xmm4, (%[out]," VAR(KR64) ",1)\n\t" \
     4658    "vpshufb            %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"    \
     4659    "vpxor              %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"
     4660
     4661#define _VAESENC_GFMUL(in, H, X)                              \
     4662    "vmovdqu            " VAR(CTR1) ", %%xmm5\n\t"            \
     4663    "vpshufb            %[BSWAP_EPI64], %%xmm5, %%xmm4\n\t"   \
     4664    "vpaddd             %[ONE], %%xmm5, %%xmm5\n\t"           \
     4665    "vmovdqu            %%xmm5, " VAR(CTR1) "\n\t"            \
     4666    "vpxor              (%[KEY]), %%xmm4, %%xmm4\n\t"         \
     4667    "vpclmulqdq         $0x10, " #H ", " #X ", %%xmm6\n\t"    \
     4668    "vaesenc            16(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4669    "vaesenc            32(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4670    "vpclmulqdq         $0x01, " #H ", " #X ", %%xmm7\n\t"    \
     4671    "vaesenc            48(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4672    "vaesenc            64(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4673    "vpclmulqdq         $0x00, " #H ", " #X ", %%xmm8\n\t"    \
     4674    "vaesenc            80(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4675    "vpclmulqdq         $0x11, " #H ", " #X ", %%xmm1\n\t"    \
     4676    "vaesenc            96(%[KEY]), %%xmm4, %%xmm4\n\t"       \
     4677    "vpxor              %%xmm7, %%xmm6, %%xmm6\n\t"           \
     4678    "vpslldq            $8, %%xmm6, %%xmm2\n\t"               \
     4679    "vpsrldq            $8, %%xmm6, %%xmm6\n\t"               \
     4680    "vaesenc            112(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4681    "vpxor              %%xmm8, %%xmm2, %%xmm2\n\t"           \
     4682    "vpxor              %%xmm6, %%xmm1, %%xmm3\n\t"           \
     4683    "vmovdqa            %[MOD2_128], %%xmm0\n\t"              \
     4684    "vpclmulqdq         $0x10, %%xmm0, %%xmm2, %%xmm7\n\t"    \
     4685    "vaesenc            128(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4686    "vpshufd            $0x4e, %%xmm2, %%xmm6\n\t"            \
     4687    "vpxor              %%xmm7, %%xmm6, %%xmm6\n\t"           \
     4688    "vpclmulqdq         $0x10, %%xmm0, %%xmm6, %%xmm7\n\t"    \
     4689    "vaesenc            144(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4690    "vpshufd            $0x4e, %%xmm6, %%xmm6\n\t"            \
     4691    "vpxor              %%xmm7, %%xmm6, %%xmm6\n\t"           \
     4692    "vpxor              %%xmm3, %%xmm6, " VAR(XR) "\n\t"      \
     4693    "cmpl               $11, %[nr]\n\t"                       \
     4694    "vmovdqa            160(%[KEY]), %%xmm5\n\t"              \
     4695    "jl                 1f\n\t"                               \
     4696    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4697    "vaesenc            176(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4698    "cmpl               $13, %[nr]\n\t"                       \
     4699    "vmovdqa            192(%[KEY]), %%xmm5\n\t"              \
     4700    "jl                 1f\n\t"                               \
     4701    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4702    "vaesenc            208(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     4703    "vmovdqa            224(%[KEY]), %%xmm5\n\t"              \
     4704    "1:\n\t"                                                  \
     4705    "vaesenclast        %%xmm5, %%xmm4, %%xmm4\n\t"           \
     4706    "vmovdqu            " #in ", %%xmm0\n\t"                  \
     4707    "vpxor              %%xmm0, %%xmm4, %%xmm4\n\t"           \
     4708    "vmovdqu            %%xmm4, (%[out]," VAR(KR64) ",1)\n\t"
     4709#define VAESENC_GFMUL(in, H, X)                               \
     4710       _VAESENC_GFMUL(in, H, X)
     4711
     4712
     4713#define _GHASH_GFMUL_AVX1(r, r2, a, b)             \
     4714    "vpshufd    $0x4e, "#a", %%xmm1\n\t"           \
     4715    "vpshufd    $0x4e, "#b", %%xmm2\n\t"           \
     4716    "vpclmulqdq $0x11, "#a", "#b", %%xmm3\n\t"     \
     4717    "vpclmulqdq $0x00, "#a", "#b", %%xmm0\n\t"     \
     4718    "vpxor      "#a", %%xmm1, %%xmm1\n\t"          \
     4719    "vpxor      "#b", %%xmm2, %%xmm2\n\t"          \
     4720    "vpclmulqdq $0x00, %%xmm2, %%xmm1, %%xmm1\n\t" \
     4721    "vpxor      %%xmm0, %%xmm1, %%xmm1\n\t"        \
     4722    "vpxor      %%xmm3, %%xmm1, %%xmm1\n\t"        \
     4723    "vmovdqa    %%xmm0, "#r2"\n\t"                 \
     4724    "vmovdqa    %%xmm3, " #r "\n\t"                \
     4725    "vpslldq    $8, %%xmm1, %%xmm2\n\t"            \
     4726    "vpsrldq    $8, %%xmm1, %%xmm1\n\t"            \
     4727    "vpxor      %%xmm2, "#r2", "#r2"\n\t"          \
     4728    "vpxor      %%xmm1, " #r ", " #r "\n\t"
     4729#define GHASH_GFMUL_AVX1(r, r2, a, b)              \
     4730       _GHASH_GFMUL_AVX1(r, r2, a, b)
     4731
     4732#define _GHASH_GFMUL_XOR_AVX1(r, r2, a, b)         \
     4733    "vpshufd    $0x4e, "#a", %%xmm1\n\t"           \
     4734    "vpshufd    $0x4e, "#b", %%xmm2\n\t"           \
     4735    "vpclmulqdq $0x11, "#a", "#b", %%xmm3\n\t"     \
     4736    "vpclmulqdq $0x00, "#a", "#b", %%xmm0\n\t"     \
     4737    "vpxor      "#a", %%xmm1, %%xmm1\n\t"          \
     4738    "vpxor      "#b", %%xmm2, %%xmm2\n\t"          \
     4739    "vpclmulqdq $0x00, %%xmm2, %%xmm1, %%xmm1\n\t" \
     4740    "vpxor      %%xmm0, %%xmm1, %%xmm1\n\t"        \
     4741    "vpxor      %%xmm3, %%xmm1, %%xmm1\n\t"        \
     4742    "vpxor      %%xmm0, "#r2", "#r2"\n\t"          \
     4743    "vpxor      %%xmm3, " #r ", " #r "\n\t"        \
     4744    "vpslldq    $8, %%xmm1, %%xmm2\n\t"            \
     4745    "vpsrldq    $8, %%xmm1, %%xmm1\n\t"            \
     4746    "vpxor      %%xmm2, "#r2", "#r2"\n\t"          \
     4747    "vpxor      %%xmm1, " #r ", " #r "\n\t"
     4748#define GHASH_GFMUL_XOR_AVX1(r, r2, a, b)          \
     4749       _GHASH_GFMUL_XOR_AVX1(r, r2, a, b)
     4750
     4751#define GHASH_MID_AVX1(r, r2)               \
     4752    "vpsrld     $31, "#r2", %%xmm0\n\t"     \
     4753    "vpsrld     $31, " #r ", %%xmm1\n\t"    \
     4754    "vpslld     $1, "#r2", "#r2"\n\t"       \
     4755    "vpslld     $1, " #r ", " #r "\n\t"     \
     4756    "vpsrldq    $12, %%xmm0, %%xmm2\n\t"    \
     4757    "vpslldq    $4, %%xmm0, %%xmm0\n\t"     \
     4758    "vpslldq    $4, %%xmm1, %%xmm1\n\t"     \
     4759    "vpor       %%xmm2, " #r ", " #r "\n\t" \
     4760    "vpor       %%xmm0, "#r2", "#r2"\n\t"   \
     4761    "vpor       %%xmm1, " #r ", " #r "\n\t"
     4762
     4763#define _GHASH_GFMUL_RED_AVX1(r, a, b)             \
     4764    "vpshufd    $0x4e, "#a", %%xmm5\n\t"           \
     4765    "vpshufd    $0x4e, "#b", %%xmm6\n\t"           \
     4766    "vpclmulqdq $0x11, "#a", "#b", %%xmm7\n\t"     \
     4767    "vpclmulqdq $0x00, "#a", "#b", %%xmm4\n\t"     \
     4768    "vpxor      "#a", %%xmm5, %%xmm5\n\t"          \
     4769    "vpxor      "#b", %%xmm6, %%xmm6\n\t"          \
     4770    "vpclmulqdq $0x00, %%xmm6, %%xmm5, %%xmm5\n\t" \
     4771    "vpxor      %%xmm4, %%xmm5, %%xmm5\n\t"        \
     4772    "vpxor      %%xmm7, %%xmm5, %%xmm5\n\t"        \
     4773    "vpslldq    $8, %%xmm5, %%xmm6\n\t"            \
     4774    "vpsrldq    $8, %%xmm5, %%xmm5\n\t"            \
     4775    "vpxor      %%xmm6, %%xmm4, %%xmm4\n\t"        \
     4776    "vpxor      %%xmm5, %%xmm7, " #r "\n\t"        \
     4777    "vpslld     $31, %%xmm4, %%xmm8\n\t"           \
     4778    "vpslld     $30, %%xmm4, %%xmm9\n\t"           \
     4779    "vpslld     $25, %%xmm4, %%xmm10\n\t"          \
     4780    "vpxor      %%xmm9, %%xmm8, %%xmm8\n\t"        \
     4781    "vpxor      %%xmm10, %%xmm8, %%xmm8\n\t"       \
     4782    "vpsrldq    $4, %%xmm8, %%xmm9\n\t"            \
     4783    "vpslldq    $12, %%xmm8, %%xmm8\n\t"           \
     4784    "vpxor      %%xmm8, %%xmm4, %%xmm4\n\t"        \
     4785    "vpsrld     $1, %%xmm4, %%xmm10\n\t"           \
     4786    "vpsrld     $2, %%xmm4, %%xmm6\n\t"            \
     4787    "vpsrld     $7, %%xmm4, %%xmm5\n\t"            \
     4788    "vpxor      %%xmm6, %%xmm10, %%xmm10\n\t"      \
     4789    "vpxor      %%xmm5, %%xmm10, %%xmm10\n\t"      \
     4790    "vpxor      %%xmm9, %%xmm10, %%xmm10\n\t"      \
     4791    "vpxor      %%xmm4, %%xmm10, %%xmm10\n\t"      \
     4792    "vpxor      %%xmm10, " #r ", " #r "\n\t"
     4793#define GHASH_GFMUL_RED_AVX1(r, a, b)              \
     4794       _GHASH_GFMUL_RED_AVX1(r, a, b)
     4795
     4796#define _GHASH_GFSQR_RED_AVX1(r, a)                \
     4797    "vpclmulqdq $0x00, "#a", "#a", %%xmm4\n\t"     \
     4798    "vpclmulqdq $0x11, "#a", "#a", " #r "\n\t"     \
     4799    "vpslld     $31, %%xmm4, %%xmm8\n\t"           \
     4800    "vpslld     $30, %%xmm4, %%xmm9\n\t"           \
     4801    "vpslld     $25, %%xmm4, %%xmm10\n\t"          \
     4802    "vpxor      %%xmm9, %%xmm8, %%xmm8\n\t"        \
     4803    "vpxor      %%xmm10, %%xmm8, %%xmm8\n\t"       \
     4804    "vpsrldq    $4, %%xmm8, %%xmm9\n\t"            \
     4805    "vpslldq    $12, %%xmm8, %%xmm8\n\t"           \
     4806    "vpxor      %%xmm8, %%xmm4, %%xmm4\n\t"        \
     4807    "vpsrld     $1, %%xmm4, %%xmm10\n\t"           \
     4808    "vpsrld     $2, %%xmm4, %%xmm6\n\t"            \
     4809    "vpsrld     $7, %%xmm4, %%xmm5\n\t"            \
     4810    "vpxor      %%xmm6, %%xmm10, %%xmm10\n\t"      \
     4811    "vpxor      %%xmm5, %%xmm10, %%xmm10\n\t"      \
     4812    "vpxor      %%xmm9, %%xmm10, %%xmm10\n\t"      \
     4813    "vpxor      %%xmm4, %%xmm10, %%xmm10\n\t"      \
     4814    "vpxor      %%xmm10, " #r ", " #r "\n\t"
     4815#define GHASH_GFSQR_RED_AVX1(r, a)                 \
     4816       _GHASH_GFSQR_RED_AVX1(r, a)
     4817
     4818#define GHASH_RED_AVX1(r, r2)                \
     4819    "vpslld     $31, "#r2", %%xmm0\n\t"      \
     4820    "vpslld     $30, "#r2", %%xmm1\n\t"      \
     4821    "vpslld     $25, "#r2", %%xmm2\n\t"      \
     4822    "vpxor      %%xmm1, %%xmm0, %%xmm0\n\t"  \
     4823    "vpxor      %%xmm2, %%xmm0, %%xmm0\n\t"  \
     4824    "vmovdqa    %%xmm0, %%xmm1\n\t"          \
     4825    "vpsrldq    $4, %%xmm1, %%xmm1\n\t"      \
     4826    "vpslldq    $12, %%xmm0, %%xmm0\n\t"     \
     4827    "vpxor      %%xmm0, "#r2", "#r2"\n\t"    \
     4828    "vpsrld     $1, "#r2", %%xmm2\n\t"       \
     4829    "vpsrld     $2, "#r2", %%xmm3\n\t"       \
     4830    "vpsrld     $7, "#r2", %%xmm0\n\t"       \
     4831    "vpxor      %%xmm3, %%xmm2, %%xmm2\n\t"  \
     4832    "vpxor      %%xmm0, %%xmm2, %%xmm2\n\t"  \
     4833    "vpxor      %%xmm1, %%xmm2, %%xmm2\n\t"  \
     4834    "vpxor      "#r2", %%xmm2, %%xmm2\n\t"   \
     4835    "vpxor      %%xmm2, " #r ", " #r "\n\t"
     4836
     4837#define GHASH_GFMUL_RED_XOR_AVX1(r, r2, a, b) \
     4838    GHASH_GFMUL_XOR_AVX1(r, r2, a, b)         \
     4839    GHASH_RED_AVX1(r, r2)
     4840
     4841#define GHASH_FULL_AVX1(r, r2, a, b) \
     4842    GHASH_GFMUL_AVX1(r, r2, a, b)    \
     4843    GHASH_MID_AVX1(r, r2)            \
     4844    GHASH_RED_AVX1(r, r2)
     4845
     4846#define CALC_IV_12_AVX1()                                            \
     4847    "# Calculate values when IV is 12 bytes\n\t"                     \
     4848    "# Set counter based on IV\n\t"                                  \
     4849    "movl               $0x01000000, %%ecx\n\t"                      \
     4850    "vpinsrq            $0, 0(%%rax), %%xmm13, %%xmm13\n\t"          \
     4851    "vpinsrd            $2, 8(%%rax), %%xmm13, %%xmm13\n\t"          \
     4852    "vpinsrd            $3, %%ecx, %%xmm13, %%xmm13\n\t"             \
     4853    "# H = Encrypt X(=0) and T = Encrypt counter\n\t"                \
     4854    "vmovdqa              0(%[KEY]), " VAR(HR) "\n\t"                \
     4855    "vpxor              " VAR(HR) ", %%xmm13, %%xmm1\n\t"            \
     4856    "vmovdqa             16(%[KEY]), %%xmm12\n\t"                    \
     4857    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4858    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4859    "vmovdqa             32(%[KEY]), %%xmm12\n\t"                    \
     4860    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4861    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4862    "vmovdqa             48(%[KEY]), %%xmm12\n\t"                    \
     4863    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4864    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4865    "vmovdqa             64(%[KEY]), %%xmm12\n\t"                    \
     4866    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4867    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4868    "vmovdqa             80(%[KEY]), %%xmm12\n\t"                    \
     4869    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4870    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4871    "vmovdqa             96(%[KEY]), %%xmm12\n\t"                    \
     4872    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4873    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4874    "vmovdqa            112(%[KEY]), %%xmm12\n\t"                    \
     4875    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4876    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4877    "vmovdqa            128(%[KEY]), %%xmm12\n\t"                    \
     4878    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4879    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4880    "vmovdqa            144(%[KEY]), %%xmm12\n\t"                    \
     4881    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4882    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4883    "cmpl               $11, %[nr]\n\t"                              \
     4884    "vmovdqa            160(%[KEY]), %%xmm12\n\t"                    \
     4885    "jl 31f\n\t"                                                     \
     4886    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4887    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4888    "vmovdqa            176(%[KEY]), %%xmm12\n\t"                    \
     4889    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4890    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4891    "cmpl               $13, %[nr]\n\t"                              \
     4892    "vmovdqa            192(%[KEY]), %%xmm12\n\t"                    \
     4893    "jl 31f\n\t"                                                     \
     4894    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4895    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4896    "vmovdqa            208(%[KEY]), %%xmm12\n\t"                    \
     4897    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4898    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4899    "vmovdqu            224(%[KEY]), %%xmm12\n\t"                    \
     4900    "31:\n\t"                                                        \
     4901    "vaesenclast        %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     4902    "vaesenclast        %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     4903    "vpshufb            %[BSWAP_MASK], " VAR(HR) ", " VAR(HR) "\n\t" \
     4904    "vmovdqu            %%xmm1, " VAR(TR) "\n\t"                     \
     4905    "jmp                39f\n\t"
     4906
     4907#define CALC_IV_AVX1()                                       \
     4908    "# Calculate values when IV is not 12 bytes\n\t"         \
     4909    "# H = Encrypt X(=0)\n\t"                                \
     4910    "vmovdqa    0(%[KEY]), " VAR(HR) "\n\t"                  \
     4911    VAESENC_AVX(HR)                                          \
     4912    "vpshufb    %[BSWAP_MASK], " VAR(HR) ", " VAR(HR) "\n\t" \
     4913    "# Calc counter\n\t"                                     \
     4914    "# Initialization vector\n\t"                            \
     4915    "cmpl       $0, %%edx\n\t"                               \
     4916    "movq       $0, %%rcx\n\t"                               \
     4917    "je 45f\n\t"                                             \
     4918    "cmpl       $16, %%edx\n\t"                              \
     4919    "jl 44f\n\t"                                             \
     4920    "andl       $0xfffffff0, %%edx\n\t"                      \
     4921    "\n"                                                     \
     4922    "43:\n\t"                                                \
     4923    "vmovdqu    (%%rax,%%rcx,1), %%xmm4\n\t"                 \
     4924    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"           \
     4925    "vpxor      %%xmm4, %%xmm13, %%xmm13\n\t"                \
     4926    GHASH_FULL_AVX1(%%xmm13, %%xmm12, %%xmm13, HR)           \
     4927    "addl       $16, %%ecx\n\t"                              \
     4928    "cmpl       %%edx, %%ecx\n\t"                            \
     4929    "jl 43b\n\t"                                             \
     4930    "movl       %[ibytes], %%edx\n\t"                        \
     4931    "cmpl       %%edx, %%ecx\n\t"                            \
     4932    "je 45f\n\t"                                             \
     4933    "\n"                                                     \
     4934    "44:\n\t"                                                \
     4935    "subq       $16, %%rsp\n\t"                              \
     4936    "vpxor      %%xmm4, %%xmm4, %%xmm4\n\t"                  \
     4937    "xorl       %%ebx, %%ebx\n\t"                            \
     4938    "vmovdqu    %%xmm4, (%%rsp)\n\t"                         \
     4939    "42:\n\t"                                                \
     4940    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t"                 \
     4941    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t"                 \
     4942    "incl       %%ecx\n\t"                                   \
     4943    "incl       %%ebx\n\t"                                   \
     4944    "cmpl       %%edx, %%ecx\n\t"                            \
     4945    "jl 42b\n\t"                                             \
     4946    "vmovdqu    (%%rsp), %%xmm4\n\t"                         \
     4947    "addq       $16, %%rsp\n\t"                              \
     4948    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"           \
     4949    "vpxor      %%xmm4, %%xmm13, %%xmm13\n\t"                \
     4950    GHASH_FULL_AVX1(%%xmm13, %%xmm12, %%xmm13, HR)           \
     4951    "\n"                                                     \
     4952    "45:\n\t"                                                \
     4953    "# T = Encrypt counter\n\t"                              \
     4954    "vpxor      %%xmm0, %%xmm0, %%xmm0\n\t"                  \
     4955    "shll       $3, %%edx\n\t"                               \
     4956    "vpinsrq    $0, %%rdx, %%xmm0, %%xmm0\n\t"               \
     4957    "vpxor      %%xmm0, %%xmm13, %%xmm13\n\t"                \
     4958    GHASH_FULL_AVX1(%%xmm13, %%xmm12, %%xmm13, HR)           \
     4959    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"         \
     4960    "#   Encrypt counter\n\t"                                \
     4961    "vmovdqa    0(%[KEY]), %%xmm4\n\t"                       \
     4962    "vpxor      %%xmm13, %%xmm4, %%xmm4\n\t"                 \
     4963    VAESENC_AVX(%%xmm4)                                      \
     4964    "vmovdqu    %%xmm4, " VAR(TR) "\n\t"
     4965
     4966#define CALC_AAD_AVX1()                                \
     4967    "# Additional authentication data\n\t"             \
     4968    "movl       %[abytes], %%edx\n\t"                  \
     4969    "cmpl       $0, %%edx\n\t"                         \
     4970    "je         25f\n\t"                               \
     4971    "movq       %[addt], %%rax\n\t"                    \
     4972    "xorl       %%ecx, %%ecx\n\t"                      \
     4973    "cmpl       $16, %%edx\n\t"                        \
     4974    "jl         24f\n\t"                               \
     4975    "andl       $0xfffffff0, %%edx\n\t"                \
     4976    "\n"                                               \
     4977    "23:\n\t"                                          \
     4978    "vmovdqu    (%%rax,%%rcx,1), %%xmm4\n\t"           \
     4979    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"     \
     4980    "vpxor      %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"  \
     4981    GHASH_FULL_AVX1(XR, %%xmm12, XR, HR)               \
     4982    "addl       $16, %%ecx\n\t"                        \
     4983    "cmpl       %%edx, %%ecx\n\t"                      \
     4984    "jl         23b\n\t"                               \
     4985    "movl       %[abytes], %%edx\n\t"                  \
     4986    "cmpl       %%edx, %%ecx\n\t"                      \
     4987    "je         25f\n\t"                               \
     4988    "\n"                                               \
     4989    "24:\n\t"                                          \
     4990    "subq       $16, %%rsp\n\t"                        \
     4991    "vpxor      %%xmm4, %%xmm4, %%xmm4\n\t"            \
     4992    "xorl       %%ebx, %%ebx\n\t"                      \
     4993    "vmovdqu    %%xmm4, (%%rsp)\n\t"                   \
     4994    "22:\n\t"                                          \
     4995    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t"           \
     4996    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t"           \
     4997    "incl       %%ecx\n\t"                             \
     4998    "incl       %%ebx\n\t"                             \
     4999    "cmpl       %%edx, %%ecx\n\t"                      \
     5000    "jl         22b\n\t"                               \
     5001    "vmovdqu    (%%rsp), %%xmm4\n\t"                   \
     5002    "addq       $16, %%rsp\n\t"                        \
     5003    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"     \
     5004    "vpxor      %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5005    GHASH_FULL_AVX1(XR, %%xmm12, XR, HR)               \
     5006    "\n"                                               \
     5007    "25:\n\t"
     5008
     5009#define CALC_HT_8_AVX1()                          \
     5010    "vmovdqa    " VAR(XR) ", %%xmm2\n\t"          \
     5011    "# H ^ 1\n\t"                                 \
     5012    "vmovdqu    " VAR(HR) ", 0(" VAR(HTR) ")\n\t" \
     5013    "# H ^ 2\n\t"                                 \
     5014    GHASH_GFSQR_RED_AVX1(%%xmm0, HR)              \
     5015    "vmovdqu    %%xmm0 ,  16(" VAR(HTR) ")\n\t"   \
     5016    "# H ^ 3\n\t"                                 \
     5017    GHASH_GFMUL_RED_AVX1(%%xmm1, HR, %%xmm0)      \
     5018    "vmovdqu    %%xmm1 ,  32(" VAR(HTR) ")\n\t"   \
     5019    "# H ^ 4\n\t"                                 \
     5020    GHASH_GFSQR_RED_AVX1(%%xmm3, %%xmm0)          \
     5021    "vmovdqu    %%xmm3 ,  48(" VAR(HTR) ")\n\t"   \
     5022    "# H ^ 5\n\t"                                 \
     5023    GHASH_GFMUL_RED_AVX1(%%xmm12, %%xmm0, %%xmm1) \
     5024    "vmovdqu    %%xmm12,  64(" VAR(HTR) ")\n\t"   \
     5025    "# H ^ 6\n\t"                                 \
     5026    GHASH_GFSQR_RED_AVX1(%%xmm12, %%xmm1)         \
     5027    "vmovdqu    %%xmm12,  80(" VAR(HTR) ")\n\t"   \
     5028    "# H ^ 7\n\t"                                 \
     5029    GHASH_GFMUL_RED_AVX1(%%xmm12, %%xmm1, %%xmm3) \
     5030    "vmovdqu    %%xmm12,  96(" VAR(HTR) ")\n\t"   \
     5031    "# H ^ 8\n\t"                                 \
     5032    GHASH_GFSQR_RED_AVX1(%%xmm12, %%xmm3)         \
     5033    "vmovdqu    %%xmm12, 112(" VAR(HTR) ")\n\t"
     5034
     5035#define VAESENC_128_GHASH_AVX1(src, o)               \
     5036    "leaq       (%[in]," VAR(KR64) ",1), %%rcx\n\t"  \
     5037    "leaq       (%[out]," VAR(KR64) ",1), %%rdx\n\t" \
     5038    /* src is either %%rcx or %%rdx */             \
     5039    VAESENC_CTR()                                  \
     5040    VAESENC_XOR()                                  \
     5041    VAESENC_PCLMUL_1(src,  16, (o-128), 112)       \
     5042    VAESENC_PCLMUL_N(src,  32, (o-112),  96)       \
     5043    VAESENC_PCLMUL_N(src,  48, (o- 96),  80)       \
     5044    VAESENC_PCLMUL_N(src,  64, (o- 80),  64)       \
     5045    VAESENC_PCLMUL_N(src,  80, (o- 64),  48)       \
     5046    VAESENC_PCLMUL_N(src,  96, (o- 48),  32)       \
     5047    VAESENC_PCLMUL_N(src, 112, (o- 32),  16)       \
     5048    VAESENC_PCLMUL_N(src, 128, (o- 16),   0)       \
     5049    VAESENC_PCLMUL_L(144)                          \
     5050    "cmpl       $11, %[nr]\n\t"                    \
     5051    "vmovdqa    160(%[KEY]), %%xmm12\n\t"          \
     5052    "jl         4f\n\t"                            \
     5053    VAESENC()                                      \
     5054    VAESENC_SET(176)                               \
     5055    "cmpl       $13, %[nr]\n\t"                    \
     5056    "vmovdqa    192(%[KEY]), %%xmm12\n\t"          \
     5057    "jl         4f\n\t"                            \
     5058    VAESENC()                                      \
     5059    VAESENC_SET(208)                               \
     5060    "vmovdqa    224(%[KEY]), %%xmm12\n\t"          \
     5061    "\n"                                           \
     5062"4:\n\t"                                           \
     5063    VAESENC_LAST(%%rcx, %%rdx)
     5064
     5065#define _VAESENC_AVX(r)                                  \
     5066    "vaesenc            16(%[KEY]), " #r ", " #r "\n\t"  \
     5067    "vaesenc            32(%[KEY]), " #r ", " #r "\n\t"  \
     5068    "vaesenc            48(%[KEY]), " #r ", " #r "\n\t"  \
     5069    "vaesenc            64(%[KEY]), " #r ", " #r "\n\t"  \
     5070    "vaesenc            80(%[KEY]), " #r ", " #r "\n\t"  \
     5071    "vaesenc            96(%[KEY]), " #r ", " #r "\n\t"  \
     5072    "vaesenc            112(%[KEY]), " #r ", " #r "\n\t" \
     5073    "vaesenc            128(%[KEY]), " #r ", " #r "\n\t" \
     5074    "vaesenc            144(%[KEY]), " #r ", " #r "\n\t" \
     5075    "cmpl               $11, %[nr]\n\t"                  \
     5076    "vmovdqa            160(%[KEY]), %%xmm5\n\t"         \
     5077    "jl                 %=f\n\t"                         \
     5078    "vaesenc            %%xmm5, " #r ", " #r "\n\t"      \
     5079    "vaesenc            176(%[KEY]), " #r ", " #r "\n\t" \
     5080    "cmpl               $13, %[nr]\n\t"                  \
     5081    "vmovdqa            192(%[KEY]), %%xmm5\n\t"         \
     5082    "jl                 %=f\n\t"                         \
     5083    "vaesenc            %%xmm5, " #r ", " #r "\n\t"      \
     5084    "vaesenc            208(%[KEY]), " #r ", " #r "\n\t" \
     5085    "vmovdqa            224(%[KEY]), %%xmm5\n\t"         \
     5086    "%=:\n\t"                                            \
     5087    "vaesenclast        %%xmm5, " #r ", " #r "\n\t"
     5088#define VAESENC_AVX(r)                                   \
     5089        _VAESENC_AVX(r)
     5090
     5091#define AESENC_LAST15_ENC_AVX1()                        \
     5092    "movl       %[nbytes], %%ecx\n\t"                   \
     5093    "movl       %%ecx, %%edx\n\t"                       \
     5094    "andl       $0x0f, %%ecx\n\t"                       \
     5095    "jz         55f\n\t"                                \
     5096    "vmovdqu    " VAR(CTR1) ", %%xmm13\n\t"             \
     5097    "vpshufb    %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"   \
     5098    "vpxor      0(%[KEY]), %%xmm13, %%xmm13\n\t"        \
     5099    VAESENC_AVX(%%xmm13)                                \
     5100    "subq       $16, %%rsp\n\t"                         \
     5101    "xorl       %%ecx, %%ecx\n\t"                       \
     5102    "vmovdqu    %%xmm13, (%%rsp)\n\t"                   \
     5103    "\n"                                                \
     5104    "51:\n\t"                                           \
     5105    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"    \
     5106    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"            \
     5107    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t"   \
     5108    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"            \
     5109    "incl       " VAR(KR) "\n\t"                        \
     5110    "incl       %%ecx\n\t"                              \
     5111    "cmpl       %%edx, " VAR(KR) "\n\t"                 \
     5112    "jl         51b\n\t"                                \
     5113    "xorq       %%r13, %%r13\n\t"                       \
     5114    "cmpl       $16, %%ecx\n\t"                         \
     5115    "je         53f\n\t"                                \
     5116    "\n"                                                \
     5117    "52:\n\t"                                           \
     5118    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"            \
     5119    "incl       %%ecx\n\t"                              \
     5120    "cmpl       $16, %%ecx\n\t"                         \
     5121    "jl         52b\n\t"                                \
     5122    "53:\n\t"                                           \
     5123    "vmovdqu    (%%rsp), %%xmm13\n\t"                   \
     5124    "addq       $16, %%rsp\n\t"                         \
     5125    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"    \
     5126    "vpxor      %%xmm13, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5127    GHASH_GFMUL_RED_AVX1(XR, HR, XR)                    \
     5128
     5129#define AESENC_LAST15_DEC_AVX1()                        \
     5130    "movl       %[nbytes], %%ecx\n\t"                   \
     5131    "movl       %%ecx, %%edx\n\t"                       \
     5132    "andl       $0x0f, %%ecx\n\t"                       \
     5133    "jz         55f\n\t"                                \
     5134    "vmovdqu    " VAR(CTR1) ", %%xmm13\n\t"             \
     5135    "vpshufb    %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"   \
     5136    "vpxor      0(%[KEY]), %%xmm13, %%xmm13\n\t"        \
     5137    VAESENC_AVX(%%xmm13)                                \
     5138    "subq       $32, %%rsp\n\t"                         \
     5139    "xorl       %%ecx, %%ecx\n\t"                       \
     5140    "vmovdqu    %%xmm13, (%%rsp)\n\t"                   \
     5141    "vpxor      %%xmm0, %%xmm0, %%xmm0\n\t"             \
     5142    "vmovdqu    %%xmm0, 16(%%rsp)\n\t"                  \
     5143    "\n"                                                \
     5144    "51:\n\t"                                           \
     5145    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"    \
     5146    "movb       %%r13b, 16(%%rsp,%%rcx,1)\n\t"          \
     5147    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"            \
     5148    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t"   \
     5149    "incl       " VAR(KR) "\n\t"                        \
     5150    "incl       %%ecx\n\t"                              \
     5151    "cmpl       %%edx, " VAR(KR) "\n\t"                 \
     5152    "jl         51b\n\t"                                \
     5153    "53:\n\t"                                           \
     5154    "vmovdqu    16(%%rsp), %%xmm13\n\t"                 \
     5155    "addq       $32, %%rsp\n\t"                         \
     5156    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"    \
     5157    "vpxor      %%xmm13, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5158    GHASH_GFMUL_RED_AVX1(XR, HR, XR)                    \
     5159
     5160#define CALC_TAG_AVX1()                                      \
     5161    "movl       %[nbytes], %%edx\n\t"                        \
     5162    "movl       %[abytes], %%ecx\n\t"                        \
     5163    "shlq       $3, %%rdx\n\t"                               \
     5164    "shlq       $3, %%rcx\n\t"                               \
     5165    "vpinsrq    $0, %%rdx, %%xmm0, %%xmm0\n\t"               \
     5166    "vpinsrq    $1, %%rcx, %%xmm0, %%xmm0\n\t"               \
     5167    "vpxor      %%xmm0, " VAR(XR) ", " VAR(XR) "\n\t"        \
     5168    GHASH_GFMUL_RED_AVX1(XR, HR, XR)                         \
     5169    "vpshufb    %[BSWAP_MASK], " VAR(XR) ", " VAR(XR) "\n\t" \
     5170    "vpxor      " VAR(TR) ", " VAR(XR) ", %%xmm0\n\t"        \
     5171
     5172#define STORE_TAG_AVX()                       \
     5173    "cmpl       $16, %[tbytes]\n\t"           \
     5174    "je         71f\n\t"                      \
     5175    "xorq       %%rcx, %%rcx\n\t"             \
     5176    "vmovdqu    %%xmm0, (%%rsp)\n\t"          \
     5177    "73:\n\t"                                 \
     5178    "movzbl     (%%rsp,%%rcx,1), %%r13d\n\t"  \
     5179    "movb       %%r13b, (%[tag],%%rcx,1)\n\t" \
     5180    "incl       %%ecx\n\t"                    \
     5181    "cmpl       %[tbytes], %%ecx\n\t"         \
     5182    "jne        73b\n\t"                      \
     5183    "jmp        72f\n\t"                      \
     5184    "\n"                                      \
     5185    "71:\n\t"                                 \
     5186    "vmovdqu    %%xmm0, (%[tag])\n\t"         \
     5187    "\n"                                      \
     5188    "72:\n\t"
     5189
     5190#define CMP_TAG_AVX()                                      \
     5191    "cmpl       $16, %[tbytes]\n\t"                        \
     5192    "je         71f\n\t"                                   \
     5193    "subq       $16, %%rsp\n\t"                            \
     5194    "xorq       %%rcx, %%rcx\n\t"                          \
     5195    "xorq       %%rax, %%rax\n\t"                          \
     5196    "vmovdqu    %%xmm0, (%%rsp)\n\t"                       \
     5197    "\n"                                                   \
     5198    "73:\n\t"                                              \
     5199    "movzbl     (%%rsp,%%rcx,1), %%r13d\n\t"               \
     5200    "xorb       (%[tag],%%rcx,1), %%r13b\n\t"              \
     5201    "orb        %%r13b, %%al\n\t"                          \
     5202    "incl       %%ecx\n\t"                                 \
     5203    "cmpl       %[tbytes], %%ecx\n\t"                      \
     5204    "jne        73b\n\t"                                   \
     5205    "cmpb       $0x00, %%al\n\t"                           \
     5206    "sete       %%al\n\t"                                  \
     5207    "addq       $16, %%rsp\n\t"                            \
     5208    "jmp        72f\n\t"                                   \
     5209    "\n"                                                   \
     5210    "71:\n\t"                                              \
     5211    "vmovdqu    (%[tag]), %%xmm1\n\t"                      \
     5212    "vpcmpeqb   %%xmm1, %%xmm0, %%xmm0\n\t"                \
     5213    "vpmovmskb  %%xmm0, %%edx\n\t"                         \
     5214    "# %%edx == 0xFFFF then return 1 else => return 0\n\t" \
     5215    "xorl       %%eax, %%eax\n\t"                          \
     5216    "cmpl       $0xffff, %%edx\n\t"                        \
     5217    "sete       %%al\n\t"                                  \
     5218    "\n"                                                   \
     5219    "72:\n\t"                                              \
     5220    "movl       %%eax, (%[res])\n\t"
     5221
     5222static void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
     5223                            const unsigned char* addt,
     5224                                 const unsigned char* ivec, unsigned char *tag,
     5225                                 unsigned int nbytes, unsigned int abytes,
     5226                                 unsigned int ibytes, unsigned int tbytes,
     5227                            const unsigned char* key, int nr)
     5228{
     5229    register const unsigned char* iv asm("rax") = ivec;
     5230    register unsigned int ivLen asm("ebx") = ibytes;
     5231
     5232    __asm__ __volatile__ (
     5233        "subq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     5234        /* Counter is xmm13 */
     5235        "vpxor          %%xmm13, %%xmm13, %%xmm13\n\t"
     5236        "vpxor          " VAR(XR) ", " VAR(XR) ", " VAR(XR) "\n\t"
     5237        "movl           %[ibytes], %%edx\n\t"
     5238        "cmpl           $12, %%edx\n\t"
     5239        "jne            35f\n\t"
     5240        CALC_IV_12_AVX1()
     5241        "\n"
     5242        "35:\n\t"
     5243        CALC_IV_AVX1()
     5244        "\n"
     5245        "39:\n\t"
     5246
     5247        CALC_AAD_AVX1()
     5248
     5249        "# Calculate counter and H\n\t"
     5250        "vpsrlq         $63, " VAR(HR) ", %%xmm5\n\t"
     5251        "vpsllq         $1, " VAR(HR) ", %%xmm4\n\t"
     5252        "vpslldq        $8, %%xmm5, %%xmm5\n\t"
     5253        "vpor           %%xmm5, %%xmm4, %%xmm4\n\t"
     5254        "vpshufd        $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     5255        "vpsrad         $31, " VAR(HR) ", " VAR(HR) "\n\t"
     5256        "vpshufb        %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"
     5257        "vpand          %[MOD2_128], " VAR(HR) ", " VAR(HR) "\n\t"
     5258        "vpaddd         %[ONE], %%xmm13, %%xmm13\n\t"
     5259        "vpxor          %%xmm4, " VAR(HR) ", " VAR(HR) "\n\t"
     5260        "vmovdqu        %%xmm13, " VAR(CTR1) "\n\t"
     5261
     5262        "xorl           " VAR(KR) ", " VAR(KR) "\n\t"
     5263
     5264#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     5265        "cmpl   $128, %[nbytes]\n\t"
     5266        "movl   %[nbytes], %%r13d\n\t"
     5267        "jl     5f\n\t"
     5268        "andl   $0xffffff80, %%r13d\n\t"
     5269
     5270        CALC_HT_8_AVX1()
     5271
     5272        "# First 128 bytes of input\n\t"
     5273        VAESENC_128()
     5274
     5275        "cmpl   $128, %%r13d\n\t"
     5276        "movl   $128, " VAR(KR) "\n\t"
     5277        "jle    2f\n\t"
     5278
     5279        "# More 128 bytes of input\n\t"
     5280        "\n"
     5281    "3:\n\t"
     5282        VAESENC_128_GHASH_AVX1(%%rdx, 0)
     5283        "addl   $128, " VAR(KR) "\n\t"
     5284        "cmpl   %%r13d, " VAR(KR) "\n\t"
     5285        "jl     3b\n\t"
     5286        "\n"
     5287    "2:\n\t"
     5288        "vmovdqa        %[BSWAP_MASK], %%xmm13\n\t"
     5289        "vpshufb        %%xmm13, %%xmm4, %%xmm4\n\t"
     5290        "vpshufb        %%xmm13, %%xmm5, %%xmm5\n\t"
     5291        "vpshufb        %%xmm13, %%xmm6, %%xmm6\n\t"
     5292        "vpshufb        %%xmm13, %%xmm7, %%xmm7\n\t"
     5293        "vpxor          %%xmm2, %%xmm4, %%xmm4\n\t"
     5294        "vpshufb        %%xmm13, %%xmm8, %%xmm8\n\t"
     5295        "vpshufb        %%xmm13, %%xmm9, %%xmm9\n\t"
     5296        "vpshufb        %%xmm13, %%xmm10, %%xmm10\n\t"
     5297        "vpshufb        %%xmm13, %%xmm11, %%xmm11\n\t"
     5298
     5299        "vmovdqu           (" VAR(HTR) "), %%xmm12\n\t"
     5300        "vmovdqu         16(" VAR(HTR) "), %%xmm14\n\t"
     5301        GHASH_GFMUL_AVX1(XR, %%xmm13, %%xmm11, %%xmm12)
     5302        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm10, %%xmm14)
     5303        "vmovdqu         32(" VAR(HTR) "), %%xmm12\n\t"
     5304        "vmovdqu         48(" VAR(HTR) "), %%xmm14\n\t"
     5305        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm9, %%xmm12)
     5306        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm8, %%xmm14)
     5307        "vmovdqu         64(" VAR(HTR) "), %%xmm12\n\t"
     5308        "vmovdqu         80(" VAR(HTR) "), %%xmm14\n\t"
     5309        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm7, %%xmm12)
     5310        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm6, %%xmm14)
     5311        "vmovdqu         96(" VAR(HTR) "), %%xmm12\n\t"
     5312        "vmovdqu        112(" VAR(HTR) "), %%xmm14\n\t"
     5313        GHASH_GFMUL_XOR_AVX1(XR, %%xmm13, %%xmm5, %%xmm12)
     5314        GHASH_GFMUL_RED_XOR_AVX1(XR, %%xmm13, %%xmm4, %%xmm14)
     5315
     5316        "vmovdqu        0(" VAR(HTR) "), " VAR(HR) "\n\t"
     5317        "\n"
     5318    "5:\n\t"
     5319        "movl           %[nbytes], %%edx\n\t"
     5320        "cmpl           %%edx, " VAR(KR) "\n\t"
     5321        "jge            55f\n\t"
     5322#endif
     5323
     5324        "movl           %[nbytes], %%r13d\n\t"
     5325        "andl           $0xfffffff0, %%r13d\n\t"
     5326        "cmpl           %%r13d, " VAR(KR) "\n\t"
     5327        "jge            14f\n\t"
     5328
     5329        VAESENC_BLOCK()
     5330        "addl           $16, " VAR(KR) "\n\t"
     5331        "cmpl           %%r13d, " VAR(KR) "\n\t"
     5332        "jge            13f\n\t"
     5333        "\n"
     5334        "12:\n\t"
     5335        "vmovdqu        (%[in]," VAR(KR64) ",1), %%xmm9\n\t"
     5336        VAESENC_GFMUL(%%xmm9, HR, XR)
     5337        "vpshufb        %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"
     5338        "addl           $16, " VAR(KR) "\n\t"
     5339        "vpxor          %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"
     5340        "cmpl           %%r13d, " VAR(KR) "\n\t"
     5341        "jl             12b\n\t"
     5342        "\n"
     5343        "13:\n\t"
     5344        GHASH_GFMUL_RED_AVX1(XR, HR, XR)
     5345        "\n"
     5346        "14:\n\t"
     5347
     5348        AESENC_LAST15_ENC_AVX1()
     5349        "\n"
     5350        "55:\n\t"
     5351
     5352        CALC_TAG_AVX1()
     5353        STORE_TAG_AVX()
     5354        "addq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     5355        "vzeroupper\n\t"
     5356
     5357        :
     5358        : [KEY] "r" (key),
     5359          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     5360          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     5361          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tbytes),
     5362          [tag] "r" (tag),
     5363          [BSWAP_MASK] "m" (BSWAP_MASK),
     5364          [BSWAP_EPI64] "m" (BSWAP_EPI64),
     5365          [ONE] "m" (ONE),
     5366#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     5367          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     5368          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     5369          [EIGHT] "m" (EIGHT),
     5370#endif
     5371          [MOD2_128] "m" (MOD2_128)
     5372        : "xmm15", "xmm14", "xmm13", "xmm12",
     5373          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     5374          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     5375          "rcx", "rdx", "r13"
     5376    );
     5377    }
     5378
     5379#ifdef HAVE_INTEL_AVX2
     5380/* Encrypt and carry-less multiply for AVX2. */
     5381#define VAESENC_PCLMUL_AVX2_1(src, o1, o2, o3)        \
     5382    "vmovdqu    " #o2 "(" #src "), %%xmm12\n\t"       \
     5383    "vmovdqa    " #o1 "(%[KEY]), %%xmm0\n\t"          \
     5384    "vpshufb    %[BSWAP_MASK], %%xmm12, %%xmm12\n\t"  \
     5385    "vmovdqu    " #o3 "(" VAR(HTR) "), %%xmm13\n\t"   \
     5386    "vpxor      %%xmm2, %%xmm12, %%xmm12\n\t"         \
     5387    "vpclmulqdq $0x10, %%xmm13, %%xmm12, %%xmm1\n\t"  \
     5388    "vpclmulqdq $0x01, %%xmm13, %%xmm12, %%xmm14\n\t" \
     5389    "vpclmulqdq $0x00, %%xmm13, %%xmm12, %%xmm2\n\t"  \
     5390    "vpclmulqdq $0x11, %%xmm13, %%xmm12, %%xmm3\n\t"  \
     5391    "vaesenc    %%xmm0, %%xmm4, %%xmm4\n\t"           \
     5392    "vaesenc    %%xmm0, %%xmm5, %%xmm5\n\t"           \
     5393    "vaesenc    %%xmm0, %%xmm6, %%xmm6\n\t"           \
     5394    "vaesenc    %%xmm0, %%xmm7, %%xmm7\n\t"           \
     5395    "vaesenc    %%xmm0, %%xmm8, %%xmm8\n\t"           \
     5396    "vaesenc    %%xmm0, %%xmm9, %%xmm9\n\t"           \
     5397    "vaesenc    %%xmm0, %%xmm10, %%xmm10\n\t"         \
     5398    "vaesenc    %%xmm0, %%xmm11, %%xmm11\n\t"         \
     5399
     5400#define VAESENC_PCLMUL_AVX2_2(src, o1, o2, o3)        \
     5401    "vmovdqu    " #o2 "(" #src "), %%xmm12\n\t"       \
     5402    "vmovdqu    " #o3 "(" VAR(HTR) "), %%xmm0\n\t"    \
     5403    "vpshufb    %[BSWAP_MASK], %%xmm12, %%xmm12\n\t"  \
     5404    "vpxor      %%xmm14, %%xmm1, %%xmm1\n\t"          \
     5405    "vpclmulqdq $0x10, %%xmm0, %%xmm12, %%xmm13\n\t"  \
     5406    "vpclmulqdq $0x01, %%xmm0, %%xmm12, %%xmm14\n\t"  \
     5407    "vpclmulqdq $0x00, %%xmm0, %%xmm12, %%xmm15\n\t"  \
     5408    "vpclmulqdq $0x11, %%xmm0, %%xmm12, %%xmm12\n\t"  \
     5409    "vmovdqa    " #o1 "(%[KEY]), %%xmm0\n\t"          \
     5410    "vpxor      %%xmm13, %%xmm1, %%xmm1\n\t"          \
     5411    "vpxor      %%xmm12, %%xmm3, %%xmm3\n\t"          \
     5412    "vaesenc    %%xmm0, %%xmm4, %%xmm4\n\t"           \
     5413    "vaesenc    %%xmm0, %%xmm5, %%xmm5\n\t"           \
     5414    "vaesenc    %%xmm0, %%xmm6, %%xmm6\n\t"           \
     5415    "vaesenc    %%xmm0, %%xmm7, %%xmm7\n\t"           \
     5416    "vaesenc    %%xmm0, %%xmm8, %%xmm8\n\t"           \
     5417    "vaesenc    %%xmm0, %%xmm9, %%xmm9\n\t"           \
     5418    "vaesenc    %%xmm0, %%xmm10, %%xmm10\n\t"         \
     5419    "vaesenc    %%xmm0, %%xmm11, %%xmm11\n\t"         \
     5420
     5421#define VAESENC_PCLMUL_AVX2_N(src, o1, o2, o3)        \
     5422    "vmovdqu    " #o2 "(" #src "), %%xmm12\n\t"       \
     5423    "vmovdqu    " #o3 "(" VAR(HTR) "), %%xmm0\n\t"    \
     5424    "vpshufb    %[BSWAP_MASK], %%xmm12, %%xmm12\n\t"  \
     5425    "vpxor      %%xmm14, %%xmm1, %%xmm1\n\t"          \
     5426    "vpxor      %%xmm15, %%xmm2, %%xmm2\n\t"          \
     5427    "vpclmulqdq $0x10, %%xmm0, %%xmm12, %%xmm13\n\t"  \
     5428    "vpclmulqdq $0x01, %%xmm0, %%xmm12, %%xmm14\n\t"  \
     5429    "vpclmulqdq $0x00, %%xmm0, %%xmm12, %%xmm15\n\t"  \
     5430    "vpclmulqdq $0x11, %%xmm0, %%xmm12, %%xmm12\n\t"  \
     5431    "vmovdqa    " #o1 "(%[KEY]), %%xmm0\n\t"          \
     5432    "vpxor      %%xmm13, %%xmm1, %%xmm1\n\t"          \
     5433    "vpxor      %%xmm12, %%xmm3, %%xmm3\n\t"          \
     5434    "vaesenc    %%xmm0, %%xmm4, %%xmm4\n\t"           \
     5435    "vaesenc    %%xmm0, %%xmm5, %%xmm5\n\t"           \
     5436    "vaesenc    %%xmm0, %%xmm6, %%xmm6\n\t"           \
     5437    "vaesenc    %%xmm0, %%xmm7, %%xmm7\n\t"           \
     5438    "vaesenc    %%xmm0, %%xmm8, %%xmm8\n\t"           \
     5439    "vaesenc    %%xmm0, %%xmm9, %%xmm9\n\t"           \
     5440    "vaesenc    %%xmm0, %%xmm10, %%xmm10\n\t"         \
     5441    "vaesenc    %%xmm0, %%xmm11, %%xmm11\n\t"         \
     5442
     5443#define VAESENC_PCLMUL_AVX2_L(o)                      \
     5444    "vpxor      %%xmm14, %%xmm1, %%xmm1\n\t"          \
     5445    "vpxor      %%xmm15, %%xmm2, %%xmm2\n\t"          \
     5446    "vpslldq    $8, %%xmm1, %%xmm12\n\t"              \
     5447    "vpsrldq    $8, %%xmm1, %%xmm1\n\t"               \
     5448    "vmovdqa    "#o"(%[KEY]), %%xmm15\n\t"            \
     5449    "vmovdqa    %[MOD2_128], %%xmm0\n\t"              \
     5450    "vaesenc    %%xmm15, %%xmm4, %%xmm4\n\t"          \
     5451    "vpxor      %%xmm12, %%xmm2, %%xmm2\n\t"          \
     5452    "vpxor      %%xmm1, %%xmm3, %%xmm3\n\t"           \
     5453    "vpclmulqdq $0x10, %%xmm0, %%xmm2, %%xmm14\n\t"   \
     5454    "vaesenc    %%xmm15, %%xmm5, %%xmm5\n\t"          \
     5455    "vaesenc    %%xmm15, %%xmm6, %%xmm6\n\t"          \
     5456    "vaesenc    %%xmm15, %%xmm7, %%xmm7\n\t"          \
     5457    "vpshufd    $0x4e, %%xmm2, %%xmm2\n\t"            \
     5458    "vpxor      %%xmm14, %%xmm2, %%xmm2\n\t"          \
     5459    "vpclmulqdq $0x10, %%xmm0, %%xmm2, %%xmm14\n\t"   \
     5460    "vaesenc    %%xmm15, %%xmm8, %%xmm8\n\t"          \
     5461    "vaesenc    %%xmm15, %%xmm9, %%xmm9\n\t"          \
     5462    "vaesenc    %%xmm15, %%xmm10, %%xmm10\n\t"        \
     5463    "vpshufd    $0x4e, %%xmm2, %%xmm2\n\t"            \
     5464    "vpxor      %%xmm14, %%xmm2, %%xmm2\n\t"          \
     5465    "vpxor      %%xmm3, %%xmm2, %%xmm2\n\t"           \
     5466    "vaesenc    %%xmm15, %%xmm11, %%xmm11\n\t"
     5467
     5468#define VAESENC_BLOCK_AVX2()                                  \
     5469    "vmovdqu            " VAR(CTR1) ", %%xmm5\n\t"            \
     5470    "vpshufb            %[BSWAP_EPI64], %%xmm5, %%xmm4\n\t"   \
     5471    "vpaddd             %[ONE], %%xmm5, %%xmm5\n\t"           \
     5472    "vmovdqu            %%xmm5, " VAR(CTR1) "\n\t"            \
     5473    "vpxor                 (%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5474    "vaesenc             16(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5475    "vaesenc             32(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5476    "vaesenc             48(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5477    "vaesenc             64(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5478    "vaesenc             80(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5479    "vaesenc             96(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5480    "vaesenc            112(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5481    "vaesenc            128(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5482    "vaesenc            144(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5483    "cmpl               $11, %[nr]\n\t"                       \
     5484    "vmovdqa            160(%[KEY]), %%xmm5\n\t"              \
     5485    "jl                 %=f\n\t"                              \
     5486    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     5487    "vaesenc            176(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5488    "cmpl               $13, %[nr]\n\t"                       \
     5489    "vmovdqa            192(%[KEY]), %%xmm5\n\t"              \
     5490    "jl                 %=f\n\t"                              \
     5491    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"           \
     5492    "vaesenc            208(%[KEY]), %%xmm4, %%xmm4\n\t"      \
     5493    "vmovdqa            224(%[KEY]), %%xmm5\n\t"              \
     5494    "%=:\n\t"                                                 \
     5495    "vaesenclast        %%xmm5, %%xmm4, %%xmm4\n\t"           \
     5496    "vmovdqu            (%[in]," VAR(KR64) ",1), %%xmm5\n\t"  \
     5497    "vpxor              %%xmm5, %%xmm4, %%xmm4\n\t"           \
     5498    "vmovdqu            %%xmm4, (%[out]," VAR(KR64) ",1)\n\t" \
     5499    "vpshufb            %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"    \
     5500    "vpxor              %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"
     5501
     5502/* Karatsuba multiplication - slower
     5503 * H01 = H[1] ^ H[0] (top and bottom 64-bits XORed)
     5504 */
     5505#define _VAESENC_GFMUL_AVX2(in, H, X, ctr1, H01)            \
     5506    "vpxor                 (%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5507    "vaesenc             16(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5508    "vaesenc             32(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5509    "vaesenc             48(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5510    "vaesenc             64(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5511    "vaesenc             80(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5512    "vaesenc             96(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5513    "vaesenc            112(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5514    "vaesenc            128(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5515    "vaesenc            144(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5516    "cmpl               $11, %[nr]\n\t"                     \
     5517    "vmovdqa            160(%[KEY]), %%xmm5\n\t"            \
     5518    "jl                 %=f\n\t"                            \
     5519    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"         \
     5520    "vaesenc            176(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5521    "cmpl               $13, %[nr]\n\t"                     \
     5522    "vmovdqa            192(%[KEY]), %%xmm5\n\t"            \
     5523    "jl                 %=f\n\t"                            \
     5524    "vaesenc            %%xmm5, %%xmm4, %%xmm4\n\t"         \
     5525    "vaesenc            208(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5526    "vmovdqa            224(%[KEY]), %%xmm5\n\t"            \
     5527    "%=:\n\t"                                               \
     5528    "vaesenclast        %%xmm5, %%xmm4, %%xmm4\n\t"         \
     5529    "vmovdqu            " #in ", %%xmm0\n\t"                \
     5530    "vpxor              %%xmm0, %%xmm4, %%xmm4\n\t"         \
     5531                                                            \
     5532    "vpsrldq    $8, " #X ", %%xmm2\n\t"                     \
     5533    "vpxor      " #X ", %%xmm2, %%xmm2\n\t"                 \
     5534    "vpclmulqdq $0x00, " #H ", " #X ", %%xmm5\n\t"          \
     5535    "vpclmulqdq $0x11, " #H ", " #X ", %%xmm8\n\t"          \
     5536    "vpclmulqdq $0x00, "#H01", %%xmm2, %%xmm7\n\t"          \
     5537    "vpxor      %%xmm5, %%xmm7, %%xmm7\n\t"                 \
     5538    "vpxor      %%xmm8, %%xmm7, %%xmm7\n\t"                 \
     5539    "vpslldq    $8, %%xmm7, %%xmm6\n\t"                     \
     5540    "vpsrldq    $8, %%xmm7, %%xmm7\n\t"                     \
     5541    "vpxor      %%xmm7, %%xmm8, %%xmm8\n\t"                 \
     5542    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"                 \
     5543                                                            \
     5544    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t"     \
     5545    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"                  \
     5546    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"                 \
     5547    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t"     \
     5548    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"                  \
     5549    "vpxor      %%xmm8, %%xmm6, %%xmm6\n\t"                 \
     5550    "vpxor      %%xmm5, %%xmm6, " VAR(XR) "\n\t"
     5551#define VAESENC_GFMUL_AVX2(in, H, X, ctr1)                  \
     5552       _VAESENC_GFMUL_AVX2(in, H, X, ctr1)
     5553
     5554#define _VAESENC_GFMUL_SB_AVX2(in, H, X, ctr1)              \
     5555    "vpclmulqdq $0x10, " #H ", " #X ", %%xmm7\n\t"          \
     5556    "vpclmulqdq $0x01, " #H ", " #X ", %%xmm6\n\t"          \
     5557    "vpclmulqdq $0x00, " #H ", " #X ", %%xmm5\n\t"          \
     5558    "vpclmulqdq $0x11, " #H ", " #X ", %%xmm8\n\t"          \
     5559    "vpxor                 (%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5560    "vaesenc             16(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5561    "vpxor      %%xmm6, %%xmm7, %%xmm7\n\t"                 \
     5562    "vpslldq    $8, %%xmm7, %%xmm6\n\t"                     \
     5563    "vpsrldq    $8, %%xmm7, %%xmm7\n\t"                     \
     5564    "vaesenc             32(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5565    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"                 \
     5566    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t"     \
     5567    "vaesenc             48(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5568    "vaesenc             64(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5569    "vaesenc             80(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5570    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"                  \
     5571    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"                 \
     5572    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t"     \
     5573    "vaesenc             96(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5574    "vaesenc            112(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5575    "vaesenc            128(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5576    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"                  \
     5577    "vaesenc            144(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5578    "vpxor      %%xmm7, %%xmm8, %%xmm8\n\t"                 \
     5579    "vpxor      %%xmm8, %%xmm6, %%xmm6\n\t"                 \
     5580    "cmpl               $11, %[nr]\n\t"                     \
     5581    "vmovdqa            160(%[KEY]), %%xmm3\n\t"            \
     5582    "jl                 %=f\n\t"                            \
     5583    "vaesenc            %%xmm3, %%xmm4, %%xmm4\n\t"         \
     5584    "vaesenc            176(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5585    "cmpl               $13, %[nr]\n\t"                     \
     5586    "vmovdqa            192(%[KEY]), %%xmm3\n\t"            \
     5587    "jl                 %=f\n\t"                            \
     5588    "vaesenc            %%xmm3, %%xmm4, %%xmm4\n\t"         \
     5589    "vaesenc            208(%[KEY]), %%xmm4, %%xmm4\n\t"    \
     5590    "vmovdqa            224(%[KEY]), %%xmm3\n\t"            \
     5591    "%=:\n\t"                                               \
     5592    "vaesenclast        %%xmm3, %%xmm4, %%xmm4\n\t"         \
     5593    "vpxor      %%xmm5, %%xmm6, " VAR(XR) "\n\t"            \
     5594    "vmovdqu            " #in ", %%xmm5\n\t"                \
     5595    "vpxor              %%xmm5, %%xmm4, %%xmm4\n\t"
     5596#define VAESENC_GFMUL_SB_AVX2(in, H, X, ctr1)               \
     5597       _VAESENC_GFMUL_SB_AVX2(in, H, X, ctr1)
     5598
     5599
     5600#define _GHASH_GFMUL_AVX2(r, r2, a, b)         \
     5601    "vpclmulqdq $0x10, "#a", "#b", %%xmm2\n\t" \
     5602    "vpclmulqdq $0x01, "#a", "#b", %%xmm1\n\t" \
     5603    "vpclmulqdq $0x00, "#a", "#b", %%xmm0\n\t" \
     5604    "vpclmulqdq $0x11, "#a", "#b", %%xmm3\n\t" \
     5605    "vpxor      %%xmm1, %%xmm2, %%xmm2\n\t"    \
     5606    "vpslldq    $8, %%xmm2, %%xmm1\n\t"        \
     5607    "vpsrldq    $8, %%xmm2, %%xmm2\n\t"        \
     5608    "vpxor      %%xmm1, %%xmm0, "#r2"\n\t"     \
     5609    "vpxor      %%xmm2, %%xmm3, " #r "\n\t"
     5610#define GHASH_GFMUL_AVX2(r, r2, a, b)          \
     5611       _GHASH_GFMUL_AVX2(r, r2, a, b)
     5612
     5613#define GHASH_MID_AVX2(r, r2)               \
     5614    "vpsrld     $31, "#r2", %%xmm0\n\t"     \
     5615    "vpsrld     $31, " #r ", %%xmm1\n\t"    \
     5616    "vpslld     $1, "#r2", "#r2"\n\t"       \
     5617    "vpslld     $1, " #r ", " #r "\n\t"     \
     5618    "vpsrldq    $12, %%xmm0, %%xmm2\n\t"    \
     5619    "vpslldq    $4, %%xmm0, %%xmm0\n\t"     \
     5620    "vpslldq    $4, %%xmm1, %%xmm1\n\t"     \
     5621    "vpor       %%xmm2, " #r ", " #r "\n\t" \
     5622    "vpor       %%xmm0, "#r2", "#r2"\n\t"   \
     5623    "vpor       %%xmm1, " #r ", " #r "\n\t"
     5624
     5625#define _GHASH_GFMUL_RED_AVX2(r, a, b)                  \
     5626    "vpclmulqdq $0x10, "#a", "#b", %%xmm7\n\t"          \
     5627    "vpclmulqdq $0x01, "#a", "#b", %%xmm6\n\t"          \
     5628    "vpclmulqdq $0x00, "#a", "#b", %%xmm5\n\t"          \
     5629    "vpxor      %%xmm6, %%xmm7, %%xmm7\n\t"             \
     5630    "vpslldq    $8, %%xmm7, %%xmm6\n\t"                 \
     5631    "vpsrldq    $8, %%xmm7, %%xmm7\n\t"                 \
     5632    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"             \
     5633    "vpclmulqdq $0x11, "#a", "#b", %%xmm8\n\t"          \
     5634    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t" \
     5635    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"              \
     5636    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"             \
     5637    "vpclmulqdq $0x10, %[MOD2_128], %%xmm6, %%xmm5\n\t" \
     5638    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"              \
     5639    "vpxor      %%xmm7, %%xmm8, %%xmm8\n\t"             \
     5640    "vpxor      %%xmm8, %%xmm6, %%xmm6\n\t"             \
     5641    "vpxor      %%xmm5, %%xmm6, " #r "\n\t"
     5642#define GHASH_GFMUL_RED_AVX2(r, a, b)                   \
     5643       _GHASH_GFMUL_RED_AVX2(r, a, b)
     5644
     5645#define _GHASH_GFSQR_RED2_AVX2(r, a, mod128)            \
     5646    "vpclmulqdq $0x00, "#a", "#a", %%xmm6\n\t"          \
     5647    "vpclmulqdq $0x11, "#a", "#a", %%xmm8\n\t"          \
     5648    "vpclmulqdq $0x10, "#mod128", %%xmm6, %%xmm5\n\t"   \
     5649    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"              \
     5650    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"             \
     5651    "vpclmulqdq $0x10, "#mod128", %%xmm6, %%xmm5\n\t"   \
     5652    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"              \
     5653    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"             \
     5654    "vpxor      %%xmm6, %%xmm8, " #r "\n\t"
     5655#define GHASH_GFSQR_RED2_AVX2(r, a, mod128)             \
     5656       _GHASH_GFSQR_RED2_AVX2(r, a, mod128)
     5657
     5658#define _GHASH_GFMUL_SQR_RED2_AVX2(rm, rs, a, b, mod128) \
     5659    "vpclmulqdq $0x10, "#a", "#b", %%xmm7\n\t"           \
     5660    "vpclmulqdq $0x01, "#a", "#b", %%xmm6\n\t"           \
     5661    "vpclmulqdq $0x00, "#a", "#b", %%xmm5\n\t"           \
     5662    "vpclmulqdq $0x11, "#a", "#b", %%xmm8\n\t"           \
     5663    "vpclmulqdq $0x00, "#b", "#b", %%xmm9\n\t"           \
     5664    "vpclmulqdq $0x11, "#b", "#b", %%xmm10\n\t"          \
     5665    "vpxor      %%xmm6, %%xmm7, %%xmm7\n\t"              \
     5666    "vpslldq    $8, %%xmm7, %%xmm6\n\t"                  \
     5667    "vpsrldq    $8, %%xmm7, %%xmm7\n\t"                  \
     5668    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"              \
     5669    "vpclmulqdq $0x10, "#mod128", %%xmm9, %%xmm4\n\t"    \
     5670    "vpclmulqdq $0x10, "#mod128", %%xmm6, %%xmm5\n\t"    \
     5671    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"               \
     5672    "vpshufd    $0x4e, %%xmm9, %%xmm9\n\t"               \
     5673    "vpxor      %%xmm5, %%xmm6, %%xmm6\n\t"              \
     5674    "vpxor      %%xmm4, %%xmm9, %%xmm9\n\t"              \
     5675    "vpclmulqdq $0x10, "#mod128", %%xmm6, %%xmm5\n\t"    \
     5676    "vpclmulqdq $0x10, "#mod128", %%xmm9, %%xmm4\n\t"    \
     5677    "vpshufd    $0x4e, %%xmm6, %%xmm6\n\t"               \
     5678    "vpshufd    $0x4e, %%xmm9, %%xmm9\n\t"               \
     5679    "vpxor      %%xmm7, %%xmm8, %%xmm8\n\t"              \
     5680    "vpxor      %%xmm4, %%xmm9, %%xmm9\n\t"              \
     5681    "vpxor      %%xmm8, %%xmm6, %%xmm6\n\t"              \
     5682    "vpxor      %%xmm10, %%xmm9, "#rs"\n\t"              \
     5683    "vpxor      %%xmm5, %%xmm6, "#rm"\n\t"
     5684#define GHASH_GFMUL_SQR_RED2_AVX2(rm, rs, a, b, mod128)  \
     5685       _GHASH_GFMUL_SQR_RED2_AVX2(rm, rs, a, b, mod128)
     5686
     5687#define CALC_HT_8_AVX2()                                                \
     5688    "vmovdqa    %[MOD2_128], %%xmm11\n\t"                               \
     5689    "vmovdqa    " VAR(XR) ", %%xmm2\n\t"                                \
     5690    "# H ^ 1 and H ^ 2\n\t"                                             \
     5691    GHASH_GFSQR_RED2_AVX2(%%xmm0, HR, %%xmm11)                          \
     5692    "vmovdqu    " VAR(HR) ", 0(" VAR(HTR) ")\n\t"                       \
     5693    "vmovdqu    %%xmm0 ,  16(" VAR(HTR) ")\n\t"                         \
     5694    "# H ^ 3 and H ^ 4\n\t"                                             \
     5695    GHASH_GFMUL_SQR_RED2_AVX2(%%xmm1, %%xmm3, HR, %%xmm0, %%xmm11)      \
     5696    "vmovdqu    %%xmm1 ,  32(" VAR(HTR) ")\n\t"                         \
     5697    "vmovdqu    %%xmm3 ,  48(" VAR(HTR) ")\n\t"                         \
     5698    "# H ^ 5 and H ^ 6\n\t"                                             \
     5699    GHASH_GFMUL_SQR_RED2_AVX2(%%xmm12, %%xmm0, %%xmm0, %%xmm1, %%xmm11) \
     5700    "vmovdqu    %%xmm12,  64(" VAR(HTR) ")\n\t"                         \
     5701    "vmovdqu    %%xmm0 ,  80(" VAR(HTR) ")\n\t"                         \
     5702    "# H ^ 7 and H ^ 8\n\t"                                             \
     5703    GHASH_GFMUL_SQR_RED2_AVX2(%%xmm12, %%xmm0, %%xmm1, %%xmm3, %%xmm11) \
     5704    "vmovdqu    %%xmm12,  96(" VAR(HTR) ")\n\t"                         \
     5705    "vmovdqu    %%xmm0 , 112(" VAR(HTR) ")\n\t"
     5706
     5707#define _GHASH_RED_AVX2(r, r2)                     \
     5708    "vmovdqa    %[MOD2_128], %%xmm2\n\t"           \
     5709    "vpclmulqdq $0x10, %%xmm2, "#r2", %%xmm0\n\t"  \
     5710    "vpshufd    $0x4e, "#r2", %%xmm1\n\t"          \
     5711    "vpxor      %%xmm0, %%xmm1, %%xmm1\n\t"        \
     5712    "vpclmulqdq $0x10, %%xmm2, %%xmm1, %%xmm0\n\t" \
     5713    "vpshufd    $0x4e, %%xmm1, %%xmm1\n\t"         \
     5714    "vpxor      %%xmm0, %%xmm1, %%xmm1\n\t"        \
     5715    "vpxor      %%xmm1, " #r ", " #r "\n\t"
     5716#define GHASH_RED_AVX2(r, r2)                      \
     5717       _GHASH_RED_AVX2(r, r2)
     5718
     5719#define GHASH_FULL_AVX2(r, r2, a, b) \
     5720    GHASH_GFMUL_AVX2(r, r2, a, b)    \
     5721    GHASH_MID_AVX2(r, r2)            \
     5722    GHASH_RED_AVX2(r, r2)
     5723
     5724#define _GFMUL_3V_AVX2(r, r2, r3, a, b)        \
     5725    "vpclmulqdq $0x10, "#a", "#b", "#r3"\n\t"  \
     5726    "vpclmulqdq $0x01, "#a", "#b", %%xmm1\n\t" \
     5727    "vpclmulqdq $0x00, "#a", "#b", "#r2"\n\t"  \
     5728    "vpclmulqdq $0x11, "#a", "#b", " #r "\n\t" \
     5729    "vpxor      %%xmm1, "#r3", "#r3"\n\t"
     5730#define GFMUL_3V_AVX2(r, r2, r3, a, b)         \
     5731       _GFMUL_3V_AVX2(r, r2, r3, a, b)
     5732
     5733#define _GFMUL_XOR_3V_AVX2(r, r2, r3, a, b)    \
     5734    "vpclmulqdq $0x10, "#a", "#b", %%xmm2\n\t" \
     5735    "vpclmulqdq $0x01, "#a", "#b", %%xmm1\n\t" \
     5736    "vpclmulqdq $0x00, "#a", "#b", %%xmm0\n\t" \
     5737    "vpclmulqdq $0x11, "#a", "#b", %%xmm3\n\t" \
     5738    "vpxor      %%xmm1, %%xmm2, %%xmm2\n\t"    \
     5739    "vpxor      %%xmm3, " #r ", " #r "\n\t"    \
     5740    "vpxor      %%xmm2, "#r3", "#r3"\n\t"      \
     5741    "vpxor      %%xmm0, "#r2", "#r2"\n\t"
     5742#define GFMUL_XOR_3V_AVX2(r, r2, r3, a, b)     \
     5743       _GFMUL_XOR_3V_AVX2(r, r2, r3, a, b)
     5744
     5745#define GHASH_GFMUL_RED_8_AVX2()                              \
     5746    "vmovdqu       (" VAR(HTR) "), %%xmm12\n\t"               \
     5747    GFMUL_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm11, %%xmm12)     \
     5748    "vmovdqu     16(" VAR(HTR) "), %%xmm12\n\t"               \
     5749    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm10, %%xmm12) \
     5750    "vmovdqu     32(" VAR(HTR) "), %%xmm11\n\t"               \
     5751    "vmovdqu     48(" VAR(HTR) "), %%xmm12\n\t"               \
     5752    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm9, %%xmm11)  \
     5753    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm8, %%xmm12)  \
     5754    "vmovdqu     64(" VAR(HTR) "), %%xmm11\n\t"               \
     5755    "vmovdqu     80(" VAR(HTR) "), %%xmm12\n\t"               \
     5756    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm7, %%xmm11)  \
     5757    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm6, %%xmm12)  \
     5758    "vmovdqu     96(" VAR(HTR) "), %%xmm11\n\t"               \
     5759    "vmovdqu    112(" VAR(HTR) "), %%xmm12\n\t"               \
     5760    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm5, %%xmm11)  \
     5761    GFMUL_XOR_3V_AVX2(XR, %%xmm13, %%xmm14, %%xmm4, %%xmm12)  \
     5762    "vpslldq    $8, %%xmm14, %%xmm12\n\t"                     \
     5763    "vpsrldq    $8, %%xmm14, %%xmm14\n\t"                     \
     5764    "vpxor      %%xmm12, %%xmm13, %%xmm13\n\t"                \
     5765    "vpxor      %%xmm14, " VAR(XR) ", " VAR(XR) "\n\t"        \
     5766    GHASH_RED_AVX2(XR, %%xmm13)
     5767
     5768#define CALC_IV_12_AVX2()                                            \
     5769    "# Calculate values when IV is 12 bytes\n\t"                     \
     5770    "# Set counter based on IV\n\t"                                  \
     5771    "movl               $0x01000000, %%ecx\n\t"                      \
     5772    "vpinsrq            $0, 0(%%rax), %%xmm13, %%xmm13\n\t"          \
     5773    "vpinsrd            $2, 8(%%rax), %%xmm13, %%xmm13\n\t"          \
     5774    "vpinsrd            $3, %%ecx, %%xmm13, %%xmm13\n\t"             \
     5775    "# H = Encrypt X(=0) and T = Encrypt counter\n\t"                \
     5776    "vmovdqa              0(%[KEY]), " VAR(HR) "\n\t"                \
     5777    "vmovdqa             16(%[KEY]), %%xmm12\n\t"                    \
     5778    "vpxor              " VAR(HR) ", %%xmm13, %%xmm1\n\t"            \
     5779    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5780    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5781    "vmovdqa             32(%[KEY]), %%xmm0\n\t"                     \
     5782    "vmovdqa             48(%[KEY]), %%xmm12\n\t"                    \
     5783    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5784    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5785    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5786    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5787    "vmovdqa             64(%[KEY]), %%xmm0\n\t"                     \
     5788    "vmovdqa             80(%[KEY]), %%xmm12\n\t"                    \
     5789    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5790    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5791    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5792    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5793    "vmovdqa             96(%[KEY]), %%xmm0\n\t"                     \
     5794    "vmovdqa            112(%[KEY]), %%xmm12\n\t"                    \
     5795    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5796    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5797    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5798    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5799    "vmovdqa            128(%[KEY]), %%xmm0\n\t"                     \
     5800    "vmovdqa            144(%[KEY]), %%xmm12\n\t"                    \
     5801    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5802    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5803    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5804    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5805    "cmpl               $11, %[nr]\n\t"                              \
     5806    "vmovdqa            160(%[KEY]), %%xmm0\n\t"                     \
     5807    "jl 31f\n\t"                                                     \
     5808    "vmovdqa            176(%[KEY]), %%xmm12\n\t"                    \
     5809    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5810    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5811    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5812    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5813    "cmpl               $13, %[nr]\n\t"                              \
     5814    "vmovdqa            192(%[KEY]), %%xmm0\n\t"                     \
     5815    "jl 31f\n\t"                                                     \
     5816    "vmovdqa            208(%[KEY]), %%xmm12\n\t"                    \
     5817    "vaesenc            %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5818    "vaesenc            %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5819    "vaesenc            %%xmm12, " VAR(HR) ", " VAR(HR) "\n\t"       \
     5820    "vaesenc            %%xmm12, %%xmm1, %%xmm1\n\t"                 \
     5821    "vmovdqu            224(%[KEY]), %%xmm0\n\t"                     \
     5822    "31:\n\t"                                                        \
     5823    "vaesenclast        %%xmm0, " VAR(HR) ", " VAR(HR) "\n\t"        \
     5824    "vaesenclast        %%xmm0, %%xmm1, %%xmm1\n\t"                  \
     5825    "vpshufb            %[BSWAP_MASK], " VAR(HR) ", " VAR(HR) "\n\t" \
     5826    "vmovdqu            %%xmm1, " VAR(TR) "\n\t"                     \
     5827
     5828#define CALC_IV_AVX2()                                       \
     5829    "# Calculate values when IV is not 12 bytes\n\t"         \
     5830    "# H = Encrypt X(=0)\n\t"                                \
     5831    "vmovdqa    0(%[KEY]), " VAR(HR) "\n\t"                  \
     5832    VAESENC_AVX(HR)                                          \
     5833    "vpshufb    %[BSWAP_MASK], " VAR(HR) ", " VAR(HR) "\n\t" \
     5834    "# Calc counter\n\t"                                     \
     5835    "# Initialization vector\n\t"                            \
     5836    "cmpl       $0, %%edx\n\t"                               \
     5837    "movq       $0, %%rcx\n\t"                               \
     5838    "je 45f\n\t"                                             \
     5839    "cmpl       $16, %%edx\n\t"                              \
     5840    "jl 44f\n\t"                                             \
     5841    "andl       $0xfffffff0, %%edx\n\t"                      \
     5842    "\n"                                                     \
     5843    "43:\n\t"                                                \
     5844    "vmovdqu    (%%rax,%%rcx,1), %%xmm4\n\t"                 \
     5845    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"           \
     5846    "vpxor      %%xmm4, %%xmm13, %%xmm13\n\t"                \
     5847    GHASH_FULL_AVX2(%%xmm13, %%xmm12, %%xmm13, HR)           \
     5848    "addl       $16, %%ecx\n\t"                              \
     5849    "cmpl       %%edx, %%ecx\n\t"                            \
     5850    "jl 43b\n\t"                                             \
     5851    "movl       %[ibytes], %%edx\n\t"                        \
     5852    "cmpl       %%edx, %%ecx\n\t"                            \
     5853    "je 45f\n\t"                                             \
     5854    "\n"                                                     \
     5855    "44:\n\t"                                                \
     5856    "subq       $16, %%rsp\n\t"                              \
     5857    "vpxor      %%xmm4, %%xmm4, %%xmm4\n\t"                  \
     5858    "xorl       %%ebx, %%ebx\n\t"                            \
     5859    "vmovdqu    %%xmm4, (%%rsp)\n\t"                         \
     5860    "42:\n\t"                                                \
     5861    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t"                 \
     5862    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t"                 \
     5863    "incl       %%ecx\n\t"                                   \
     5864    "incl       %%ebx\n\t"                                   \
     5865    "cmpl       %%edx, %%ecx\n\t"                            \
     5866    "jl 42b\n\t"                                             \
     5867    "vmovdqu    (%%rsp), %%xmm4\n\t"                         \
     5868    "addq       $16, %%rsp\n\t"                              \
     5869    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"           \
     5870    "vpxor      %%xmm4, %%xmm13, %%xmm13\n\t"                \
     5871    GHASH_FULL_AVX2(%%xmm13, %%xmm12, %%xmm13, HR)           \
     5872    "\n"                                                     \
     5873    "45:\n\t"                                                \
     5874    "# T = Encrypt counter\n\t"                              \
     5875    "vpxor      %%xmm0, %%xmm0, %%xmm0\n\t"                  \
     5876    "shll       $3, %%edx\n\t"                               \
     5877    "vpinsrq    $0, %%rdx, %%xmm0, %%xmm0\n\t"               \
     5878    "vpxor      %%xmm0, %%xmm13, %%xmm13\n\t"                \
     5879    GHASH_FULL_AVX2(%%xmm13, %%xmm12, %%xmm13, HR)           \
     5880    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"         \
     5881    "#   Encrypt counter\n\t"                                \
     5882    "vmovdqa    0(%[KEY]), %%xmm4\n\t"                       \
     5883    "vpxor      %%xmm13, %%xmm4, %%xmm4\n\t"                 \
     5884    VAESENC_AVX(%%xmm4)                                      \
     5885    "vmovdqu    %%xmm4, " VAR(TR) "\n\t"
     5886
     5887#define CALC_AAD_AVX2()                                \
     5888    "# Additional authentication data\n\t"             \
     5889    "movl       %[abytes], %%edx\n\t"                  \
     5890    "cmpl       $0, %%edx\n\t"                         \
     5891    "je         25f\n\t"                               \
     5892    "movq       %[addt], %%rax\n\t"                    \
     5893    "xorl       %%ecx, %%ecx\n\t"                      \
     5894    "cmpl       $16, %%edx\n\t"                        \
     5895    "jl         24f\n\t"                               \
     5896    "andl       $0xfffffff0, %%edx\n\t"                \
     5897    "\n"                                               \
     5898    "23:\n\t"                                          \
     5899    "vmovdqu    (%%rax,%%rcx,1), %%xmm4\n\t"           \
     5900    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"     \
     5901    "vpxor      %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5902    GHASH_FULL_AVX2(XR, %%xmm12, XR, HR)               \
     5903    "addl       $16, %%ecx\n\t"                        \
     5904    "cmpl       %%edx, %%ecx\n\t"                      \
     5905    "jl         23b\n\t"                               \
     5906    "movl       %[abytes], %%edx\n\t"                  \
     5907    "cmpl       %%edx, %%ecx\n\t"                      \
     5908    "je         25f\n\t"                               \
     5909    "\n"                                               \
     5910    "24:\n\t"                                          \
     5911    "subq       $16, %%rsp\n\t"                        \
     5912    "vpxor      %%xmm4, %%xmm4, %%xmm4\n\t"            \
     5913    "xorl       %%ebx, %%ebx\n\t"                      \
     5914    "vmovdqu    %%xmm4, (%%rsp)\n\t"                   \
     5915    "22:\n\t"                                          \
     5916    "movzbl     (%%rax,%%rcx,1), %%r13d\n\t"           \
     5917    "movb       %%r13b, (%%rsp,%%rbx,1)\n\t"           \
     5918    "incl       %%ecx\n\t"                             \
     5919    "incl       %%ebx\n\t"                             \
     5920    "cmpl       %%edx, %%ecx\n\t"                      \
     5921    "jl         22b\n\t"                               \
     5922    "vmovdqu    (%%rsp), %%xmm4\n\t"                   \
     5923    "addq       $16, %%rsp\n\t"                        \
     5924    "vpshufb    %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"     \
     5925    "vpxor      %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5926    GHASH_FULL_AVX2(XR, %%xmm12, XR, HR)               \
     5927    "\n"                                               \
     5928    "25:\n\t"
     5929
     5930#define VAESENC_128_GHASH_AVX2(src, o)               \
     5931    "leaq       (%[in]," VAR(KR64) ",1), %%rcx\n\t"  \
     5932    "leaq       (%[out]," VAR(KR64) ",1), %%rdx\n\t" \
     5933    /* src is either %%rcx or %%rdx */             \
     5934    VAESENC_CTR()                                  \
     5935    VAESENC_XOR()                                  \
     5936    VAESENC_PCLMUL_AVX2_1(src,  16, (o-128), 112)  \
     5937    VAESENC_PCLMUL_AVX2_2(src,  32, (o-112),  96)  \
     5938    VAESENC_PCLMUL_AVX2_N(src,  48, (o- 96),  80)  \
     5939    VAESENC_PCLMUL_AVX2_N(src,  64, (o- 80),  64)  \
     5940    VAESENC_PCLMUL_AVX2_N(src,  80, (o- 64),  48)  \
     5941    VAESENC_PCLMUL_AVX2_N(src,  96, (o- 48),  32)  \
     5942    VAESENC_PCLMUL_AVX2_N(src, 112, (o- 32),  16)  \
     5943    VAESENC_PCLMUL_AVX2_N(src, 128, (o- 16),   0)  \
     5944    VAESENC_PCLMUL_AVX2_L(144)                     \
     5945    "cmpl       $11, %[nr]\n\t"                    \
     5946    "vmovdqa    160(%[KEY]), %%xmm12\n\t"          \
     5947    "jl         4f\n\t"                            \
     5948    VAESENC()                                      \
     5949    VAESENC_SET(176)                               \
     5950    "cmpl       $13, %[nr]\n\t"                    \
     5951    "vmovdqa    192(%[KEY]), %%xmm12\n\t"          \
     5952    "jl         4f\n\t"                            \
     5953    VAESENC()                                      \
     5954    VAESENC_SET(208)                               \
     5955    "vmovdqa    224(%[KEY]), %%xmm12\n\t"          \
     5956    "\n"                                           \
     5957"4:\n\t"                                           \
     5958    VAESENC_LAST(%%rcx, %%rdx)
     5959
     5960#define AESENC_LAST15_ENC_AVX2()                        \
     5961    "movl       %[nbytes], %%ecx\n\t"                   \
     5962    "movl       %%ecx, %%edx\n\t"                       \
     5963    "andl       $0x0f, %%ecx\n\t"                       \
     5964    "jz         55f\n\t"                                \
     5965    "vmovdqu    " VAR(CTR1) ", %%xmm13\n\t"             \
     5966    "vpshufb    %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"   \
     5967    "vpxor      0(%[KEY]), %%xmm13, %%xmm13\n\t"        \
     5968    VAESENC_AVX(%%xmm13)                                \
     5969    "subq       $16, %%rsp\n\t"                         \
     5970    "xorl       %%ecx, %%ecx\n\t"                       \
     5971    "vmovdqu    %%xmm13, (%%rsp)\n\t"                   \
     5972    "\n"                                                \
     5973    "51:\n\t"                                           \
     5974    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"    \
     5975    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"            \
     5976    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t"   \
     5977    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"            \
     5978    "incl       " VAR(KR) "\n\t"                        \
     5979    "incl       %%ecx\n\t"                              \
     5980    "cmpl       %%edx, " VAR(KR) "\n\t"                 \
     5981    "jl         51b\n\t"                                \
     5982    "xorq       %%r13, %%r13\n\t"                       \
     5983    "cmpl       $16, %%ecx\n\t"                         \
     5984    "je         53f\n\t"                                \
     5985    "\n"                                                \
     5986    "52:\n\t"                                           \
     5987    "movb       %%r13b, (%%rsp,%%rcx,1)\n\t"            \
     5988    "incl       %%ecx\n\t"                              \
     5989    "cmpl       $16, %%ecx\n\t"                         \
     5990    "jl         52b\n\t"                                \
     5991    "53:\n\t"                                           \
     5992    "vmovdqu    (%%rsp), %%xmm13\n\t"                   \
     5993    "addq       $16, %%rsp\n\t"                         \
     5994    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"    \
     5995    "vpxor      %%xmm13, " VAR(XR) ", " VAR(XR) "\n\t"  \
     5996    GHASH_GFMUL_RED_AVX2(XR, HR, XR)                    \
     5997
     5998#define AESENC_LAST15_DEC_AVX2()                        \
     5999    "movl       %[nbytes], %%ecx\n\t"                   \
     6000    "movl       %%ecx, %%edx\n\t"                       \
     6001    "andl       $0x0f, %%ecx\n\t"                       \
     6002    "jz         55f\n\t"                                \
     6003    "vmovdqu    " VAR(CTR1) ", %%xmm13\n\t"             \
     6004    "vpshufb    %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"   \
     6005    "vpxor      0(%[KEY]), %%xmm13, %%xmm13\n\t"        \
     6006    VAESENC_AVX(%%xmm13)                                \
     6007    "subq       $32, %%rsp\n\t"                         \
     6008    "xorl       %%ecx, %%ecx\n\t"                       \
     6009    "vmovdqu    %%xmm13, (%%rsp)\n\t"                   \
     6010    "vpxor      %%xmm0, %%xmm0, %%xmm0\n\t"             \
     6011    "vmovdqu    %%xmm0, 16(%%rsp)\n\t"                  \
     6012    "\n"                                                \
     6013    "51:\n\t"                                           \
     6014    "movzbl     (%[in]," VAR(KR64) ",1), %%r13d\n\t"    \
     6015    "movb       %%r13b, 16(%%rsp,%%rcx,1)\n\t"          \
     6016    "xorb       (%%rsp,%%rcx,1), %%r13b\n\t"            \
     6017    "movb       %%r13b, (%[out]," VAR(KR64) ",1)\n\t"   \
     6018    "incl       " VAR(KR) "\n\t"                        \
     6019    "incl       %%ecx\n\t"                              \
     6020    "cmpl       %%edx, " VAR(KR) "\n\t"                 \
     6021    "jl         51b\n\t"                                \
     6022    "53:\n\t"                                           \
     6023    "vmovdqu    16(%%rsp), %%xmm13\n\t"                 \
     6024    "addq       $32, %%rsp\n\t"                         \
     6025    "vpshufb    %[BSWAP_MASK], %%xmm13, %%xmm13\n\t"    \
     6026    "vpxor      %%xmm13, " VAR(XR) ", " VAR(XR) "\n\t"  \
     6027    GHASH_GFMUL_RED_AVX2(XR, HR, XR)                    \
     6028
     6029#define CALC_TAG_AVX2()                                      \
     6030    "movl       %[nbytes], %%edx\n\t"                        \
     6031    "movl       %[abytes], %%ecx\n\t"                        \
     6032    "shlq       $3, %%rdx\n\t"                               \
     6033    "shlq       $3, %%rcx\n\t"                               \
     6034    "vpinsrq    $0, %%rdx, %%xmm0, %%xmm0\n\t"               \
     6035    "vpinsrq    $1, %%rcx, %%xmm0, %%xmm0\n\t"               \
     6036    "vpxor      %%xmm0, " VAR(XR) ", " VAR(XR) "\n\t"        \
     6037    GHASH_GFMUL_RED_AVX2(XR, HR, XR)                         \
     6038    "vpshufb    %[BSWAP_MASK], " VAR(XR) ", " VAR(XR) "\n\t" \
     6039    "vpxor      " VAR(TR) ", " VAR(XR) ", %%xmm0\n\t"        \
     6040
     6041
     6042static void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
     6043                                 const unsigned char* addt,
     6044                                 const unsigned char* ivec, unsigned char *tag,
     6045                                 unsigned int nbytes, unsigned int abytes,
     6046                                 unsigned int ibytes, unsigned int tbytes,
     6047                                 const unsigned char* key, int nr)
     6048{
     6049    register const unsigned char* iv asm("rax") = ivec;
     6050    register unsigned int ivLen asm("ebx") = ibytes;
     6051
     6052    __asm__ __volatile__ (
     6053        "subq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6054        /* Counter is xmm13 */
     6055        "vpxor          %%xmm13, %%xmm13, %%xmm13\n\t"
     6056        "vpxor          " VAR(XR) ", " VAR(XR) ", " VAR(XR) "\n\t"
     6057        "movl           %[ibytes], %%edx\n\t"
     6058        "cmpl           $12, %%edx\n\t"
     6059        "jne            35f\n\t"
     6060        CALC_IV_12_AVX2()
     6061        "jmp            39f\n\t"
     6062        "\n"
     6063        "35:\n\t"
     6064        CALC_IV_AVX2()
     6065        "\n"
     6066        "39:\n\t"
     6067
     6068        CALC_AAD_AVX2()
     6069
     6070        "# Calculate counter and H\n\t"
     6071        "vpsrlq         $63, " VAR(HR) ", %%xmm5\n\t"
     6072        "vpsllq         $1, " VAR(HR) ", %%xmm4\n\t"
     6073        "vpslldq        $8, %%xmm5, %%xmm5\n\t"
     6074        "vpor           %%xmm5, %%xmm4, %%xmm4\n\t"
     6075        "vpshufd        $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     6076        "vpsrad         $31, " VAR(HR) ", " VAR(HR) "\n\t"
     6077        "vpshufb        %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"
     6078        "vpand          %[MOD2_128], " VAR(HR) ", " VAR(HR) "\n\t"
     6079        "vpaddd         %[ONE], %%xmm13, %%xmm13\n\t"
     6080        "vpxor          %%xmm4, " VAR(HR) ", " VAR(HR) "\n\t"
     6081        "vmovdqu        %%xmm13, " VAR(CTR1) "\n\t"
     6082
     6083        "xorl           " VAR(KR) ", " VAR(KR) "\n\t"
     6084
     6085#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
     6086        "cmpl   $128, %[nbytes]\n\t"
     6087        "movl   %[nbytes], %%r13d\n\t"
     6088        "jl     5f\n\t"
     6089        "andl   $0xffffff80, %%r13d\n\t"
     6090
     6091        CALC_HT_8_AVX2()
     6092
     6093        "# First 128 bytes of input\n\t"
     6094        VAESENC_128()
     6095
     6096        "cmpl   $128, %%r13d\n\t"
     6097        "movl   $128, " VAR(KR) "\n\t"
     6098        "jle    2f\n\t"
     6099
     6100        "# More 128 bytes of input\n\t"
     6101            "\n"
     6102    "3:\n\t"
     6103        VAESENC_128_GHASH_AVX2(%%rdx, 0)
     6104        "addl   $128, " VAR(KR) "\n\t"
     6105        "cmpl   %%r13d, " VAR(KR) "\n\t"
     6106        "jl     3b\n\t"
     6107        "\n"
     6108    "2:\n\t"
     6109        "vmovdqa        %[BSWAP_MASK], %%xmm13\n\t"
     6110        "vpshufb        %%xmm13, %%xmm4, %%xmm4\n\t"
     6111        "vpshufb        %%xmm13, %%xmm5, %%xmm5\n\t"
     6112        "vpshufb        %%xmm13, %%xmm6, %%xmm6\n\t"
     6113        "vpshufb        %%xmm13, %%xmm7, %%xmm7\n\t"
     6114        "vpshufb        %%xmm13, %%xmm8, %%xmm8\n\t"
     6115        "vpshufb        %%xmm13, %%xmm9, %%xmm9\n\t"
     6116        "vpshufb        %%xmm13, %%xmm10, %%xmm10\n\t"
     6117        "vpshufb        %%xmm13, %%xmm11, %%xmm11\n\t"
     6118        "vpxor          %%xmm2, %%xmm4, %%xmm4\n\t"
     6119
     6120        GHASH_GFMUL_RED_8_AVX2()
     6121
     6122        "vmovdqu        0(" VAR(HTR) "), " VAR(HR) "\n\t"
     6123        "\n"
     6124    "5:\n\t"
     6125        "movl           %[nbytes], %%edx\n\t"
     6126        "cmpl           %%edx, " VAR(KR) "\n\t"
     6127        "jge            55f\n\t"
     6128#endif
     6129
     6130        "movl           %[nbytes], %%r13d\n\t"
     6131        "andl           $0xfffffff0, %%r13d\n\t"
     6132        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6133        "jge            14f\n\t"
     6134
     6135        VAESENC_BLOCK_AVX2()
     6136        "addl           $16, " VAR(KR) "\n\t"
     6137        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6138        "jge            13f\n\t"
     6139                "vmovdqa        %[MOD2_128], %%xmm0\n\t"
     6140        "\n"
     6141        "12:\n\t"
     6142        "vmovdqu        (%[in]," VAR(KR64) ",1), %%xmm9\n\t"
     6143        "vmovdqu        " VAR(CTR1) ", %%xmm5\n\t"
     6144        "vpshufb        %[BSWAP_EPI64], %%xmm5, %%xmm4\n\t"
     6145        "vpaddd         %[ONE], %%xmm5, %%xmm5\n\t"
     6146        "vmovdqu        %%xmm5, " VAR(CTR1) "\n\t"
     6147        VAESENC_GFMUL_SB_AVX2(%%xmm9, HR, XR, CTR1)
     6148        "vmovdqu        %%xmm4, (%[out]," VAR(KR64) ",1)\n\t"
     6149        "vpshufb        %[BSWAP_MASK], %%xmm4, %%xmm4\n\t"
     6150        "addl           $16, " VAR(KR) "\n\t"
     6151        "vpxor          %%xmm4, " VAR(XR) ", " VAR(XR) "\n\t"
     6152        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6153        "jl             12b\n\t"
     6154        "\n"
     6155        "13:\n\t"
     6156        GHASH_GFMUL_RED_AVX2(XR, HR, XR)
     6157        "\n"
     6158        "14:\n\t"
     6159
     6160        AESENC_LAST15_ENC_AVX2()
     6161        "\n"
     6162        "55:\n\t"
     6163
     6164        CALC_TAG_AVX2()
     6165        STORE_TAG_AVX()
     6166        "addq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6167        "vzeroupper\n\t"
     6168
     6169        :
     6170        : [KEY] "r" (key),
     6171          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     6172          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     6173          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tbytes),
     6174          [tag] "r" (tag),
     6175              [BSWAP_MASK] "m" (BSWAP_MASK),
     6176              [BSWAP_EPI64] "m" (BSWAP_EPI64),
     6177          [ONE] "m" (ONE),
     6178#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
     6179          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     6180          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     6181          [EIGHT] "m" (EIGHT),
     6182#endif
     6183              [MOD2_128] "m" (MOD2_128)
     6184            : "xmm15", "xmm14", "xmm13", "xmm12",
     6185          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     6186          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     6187          "rcx", "rdx", "r13"
     6188            );
     6189        }
     6190#endif /* HAVE_INTEL_AVX2 */
     6191#endif /* HAVE_INTEL_AVX1 */
     6192
     6193#ifdef HAVE_AES_DECRYPT
     6194/* Figure 10. AES-GCM – Decrypt With Single Block Ghash at a Time */
     6195
     6196static void AES_GCM_decrypt(const unsigned char *in, unsigned char *out,
     6197                            const unsigned char* addt,
     6198                            const unsigned char* ivec, const unsigned char *tag,
     6199                            int nbytes, int abytes, int ibytes, int tbytes,
     6200                            const unsigned char* key, int nr, int* res)
     6201{
     6202    register const unsigned char* iv asm("rax") = ivec;
     6203    register int ivLen asm("ebx") = ibytes;
     6204    register int tagLen asm("edx") = tbytes;
     6205
     6206        __asm__ __volatile__ (
     6207        "pushq          %%rdx\n\t"
     6208        "subq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6209        /* Counter is xmm13 */
     6210        "pxor           %%xmm13, %%xmm13\n\t"
     6211        "pxor           %%xmm15, %%xmm15\n\t"
     6212        "movl           %[ibytes], %%edx\n\t"
     6213        "cmpl           $12, %%edx\n\t"
     6214        "jne            35f\n\t"
     6215        CALC_IV_12()
     6216        "\n"
     6217        "35:\n\t"
     6218        CALC_IV()
     6219        "\n"
     6220        "39:\n\t"
     6221
     6222        CALC_AAD()
     6223
     6224        "# Calculate counter and H\n\t"
     6225        "pshufb         %[BSWAP_EPI64], %%xmm13\n\t"
     6226        "movdqa         " VAR(HR) ", %%xmm5\n\t"
     6227        "paddd          %[ONE], %%xmm13\n\t"
     6228        "movdqa         " VAR(HR) ", %%xmm4\n\t"
     6229        "movdqu         %%xmm13, " VAR(CTR1) "\n\t"
     6230        "psrlq          $63, %%xmm5\n\t"
     6231        "psllq          $1, %%xmm4\n\t"
     6232        "pslldq         $8, %%xmm5\n\t"
     6233        "por            %%xmm5, %%xmm4\n\t"
     6234        "pshufd         $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     6235        "psrad          $31, " VAR(HR) "\n\t"
     6236        "pand           %[MOD2_128], " VAR(HR) "\n\t"
     6237        "pxor           %%xmm4, " VAR(HR) "\n\t"
     6238
     6239        "xorl           " VAR(KR) ", " VAR(KR) "\n\t"
     6240
     6241#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     6242        "cmpl           $128, %[nbytes]\n\t"
     6243        "jl             5f\n\t"
     6244
     6245        CALC_HT_8_AVX()
     6246
     6247        "movl           %[nbytes], %%r13d\n\t"
     6248        "andl           $0xffffff80, %%r13d\n\t"
     6249        "\n"
     6250        "2:\n\t"
     6251        AESENC_128_GHASH_AVX(%%rcx, 128)
     6252        "addl           $128, " VAR(KR) "\n\t"
     6253        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6254        "jl             2b\n\t"
     6255
     6256        "movdqa         %%xmm2, " VAR(XR) "\n\t"
     6257        "movdqu         (%%rsp), " VAR(HR) "\n\t"
     6258    "5:\n\t"
     6259        "movl           %[nbytes], %%edx\n\t"
     6260        "cmpl           %%edx, " VAR(KR) "\n\t"
     6261        "jge            55f\n\t"
     6262#endif
     6263        "movl           %[nbytes], %%r13d\n\t"
     6264        "andl           $0xfffffff0, %%r13d\n\t"
     6265        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6266        "jge            13f\n\t"
     6267
     6268        "\n"
     6269        "12:\n\t"
     6270        "leaq           (%[in]," VAR(KR64) ",1), %%rcx\n\t"
     6271        "leaq           (%[out]," VAR(KR64) ",1), %%rdx\n\t"
     6272        "movdqu         (%%rcx), %%xmm1\n\t"
     6273        "movdqa         " VAR(HR) ", %%xmm0\n\t"
     6274        "pshufb         %[BSWAP_MASK], %%xmm1\n\t"
     6275        "pxor           " VAR(XR) ", %%xmm1\n\t"
     6276        AESENC_GFMUL(%%rcx, %%rdx, %%xmm0, %%xmm1)
     6277        "addl           $16, " VAR(KR) "\n\t"
     6278        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6279        "jl             12b\n\t"
     6280        "\n"
     6281        "13:\n\t"
     6282
     6283        AESENC_LAST15_DEC_AVX()
     6284        "\n"
     6285        "55:\n\t"
     6286
     6287        CALC_TAG()
     6288        "addq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6289        "popq           %%rdx\n\t"
     6290        CMP_TAG()
     6291
     6292        :
     6293        : [KEY] "r" (key),
     6294          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     6295          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     6296          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tagLen),
     6297          [tag] "r" (tag), [res] "r" (res),
     6298          [BSWAP_MASK] "m" (BSWAP_MASK),
     6299          [BSWAP_EPI64] "m" (BSWAP_EPI64),
     6300          [ONE] "m" (ONE),
     6301#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     6302          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     6303          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     6304          [EIGHT] "m" (EIGHT),
     6305#endif
     6306          [MOD2_128] "m" (MOD2_128)
     6307        : "xmm15", "xmm14", "xmm13", "xmm12",
     6308          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     6309          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     6310          "rcx", "r13"
     6311        );
     6312    }
     6313
     6314#ifdef HAVE_INTEL_AVX1
     6315static void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
     6316                                 const unsigned char* addt,
     6317                                 const unsigned char* ivec,
     6318                                 const unsigned char *tag, int nbytes,
     6319                                 int abytes, int ibytes, int tbytes,
     6320                                 const unsigned char* key, int nr, int* res)
     6321{
     6322    register const unsigned char* iv asm("rax") = ivec;
     6323    register int ivLen asm("ebx") = ibytes;
     6324    register int tagLen asm("edx") = tbytes;
     6325
     6326        __asm__ __volatile__ (
     6327        "pushq          %%rdx\n\t"
     6328        "subq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6329        /* Counter is xmm13 */
     6330        "vpxor          %%xmm13, %%xmm13, %%xmm13\n\t"
     6331        "vpxor          %%xmm15, %%xmm15, %%xmm15\n\t"
     6332        "movl           %[ibytes], %%edx\n\t"
     6333        "cmpl           $12, %%edx\n\t"
     6334        "jne            35f\n\t"
     6335        CALC_IV_12_AVX1()
     6336        "\n"
     6337        "35:\n\t"
     6338        CALC_IV_AVX1()
     6339        "\n"
     6340        "39:\n\t"
     6341
     6342        CALC_AAD_AVX1()
     6343
     6344        "# Calculate counter and H\n\t"
     6345        "vpsrlq         $63, " VAR(HR) ", %%xmm5\n\t"
     6346        "vpsllq         $1, " VAR(HR) ", %%xmm4\n\t"
     6347        "vpslldq        $8, %%xmm5, %%xmm5\n\t"
     6348        "vpor           %%xmm5, %%xmm4, %%xmm4\n\t"
     6349        "vpshufd        $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     6350        "vpsrad         $31, " VAR(HR) ", " VAR(HR) "\n\t"
     6351        "vpshufb        %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"
     6352        "vpand          %[MOD2_128], " VAR(HR) ", " VAR(HR) "\n\t"
     6353        "vpaddd         %[ONE], %%xmm13, %%xmm13\n\t"
     6354        "vpxor          %%xmm4, " VAR(HR) ", " VAR(HR) "\n\t"
     6355        "vmovdqu        %%xmm13, " VAR(CTR1) "\n\t"
     6356
     6357        "xorl           " VAR(KR) ", " VAR(KR) "\n\t"
     6358
     6359#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     6360        "cmpl           $128, %[nbytes]\n\t"
     6361        "jl             5f\n\t"
     6362
     6363        CALC_HT_8_AVX1()
     6364
     6365        "movl           %[nbytes], %%r13d\n\t"
     6366        "andl           $0xffffff80, %%r13d\n\t"
     6367        "\n"
     6368        "2:\n\t"
     6369        VAESENC_128_GHASH_AVX1(%%rcx, 128)
     6370        "addl           $128, " VAR(KR) "\n\t"
     6371        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6372        "jl             2b\n\t"
     6373
     6374        "vmovdqa        %%xmm2, " VAR(XR) "\n\t"
     6375        "vmovdqu        (%%rsp), " VAR(HR) "\n\t"
     6376    "5:\n\t"
     6377        "movl           %[nbytes], %%edx\n\t"
     6378        "cmpl           %%edx, " VAR(KR) "\n\t"
     6379        "jge            55f\n\t"
     6380#endif
     6381        "movl           %[nbytes], %%r13d\n\t"
     6382        "andl           $0xfffffff0, %%r13d\n\t"
     6383        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6384        "jge            13f\n\t"
     6385
     6386        "\n"
     6387        "12:\n\t"
     6388        "vmovdqu        (%[in]," VAR(KR64) ",1), %%xmm9\n\t"
     6389        "vmovdqa        " VAR(HR) ", %%xmm0\n\t"
     6390        "vpshufb        %[BSWAP_MASK], %%xmm9, %%xmm1\n\t"
     6391        "vpxor          " VAR(XR) ", %%xmm1, %%xmm1\n\t"
     6392        VAESENC_GFMUL(%%xmm9, %%xmm0, %%xmm1)
     6393        "addl           $16, " VAR(KR) "\n\t"
     6394        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6395        "jl             12b\n\t"
     6396        "\n"
     6397        "13:\n\t"
     6398
     6399        AESENC_LAST15_DEC_AVX1()
     6400        "\n"
     6401        "55:\n\t"
     6402
     6403        CALC_TAG_AVX1()
     6404        "addq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6405        "popq           %%rdx\n\t"
     6406        CMP_TAG_AVX()
     6407        "vzeroupper\n\t"
     6408
     6409        :
     6410        : [KEY] "r" (key),
     6411          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     6412          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     6413          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tagLen),
     6414          [tag] "r" (tag), [res] "r" (res),
     6415          [BSWAP_MASK] "m" (BSWAP_MASK),
     6416          [BSWAP_EPI64] "m" (BSWAP_EPI64),
     6417          [ONE] "m" (ONE),
     6418#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX1_NO_UNROLL)
     6419          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     6420          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     6421          [EIGHT] "m" (EIGHT),
     6422#endif
     6423          [MOD2_128] "m" (MOD2_128)
     6424        : "xmm15", "xmm14", "xmm13", "xmm12",
     6425          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     6426          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     6427          "rcx", "r13"
     6428        );
     6429    }
     6430
     6431#ifdef HAVE_INTEL_AVX2
     6432static void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
     6433                                 const unsigned char* addt,
     6434                                 const unsigned char* ivec,
     6435                                 const unsigned char *tag, int nbytes,
     6436                                 int abytes, int ibytes, int tbytes,
     6437                                 const unsigned char* key, int nr, int* res)
     6438{
     6439    register const unsigned char* iv asm("rax") = ivec;
     6440    register int ivLen asm("ebx") = ibytes;
     6441    register int tagLen asm("edx") = tbytes;
     6442
     6443        __asm__ __volatile__ (
     6444        "pushq          %%rdx\n\t"
     6445        "subq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6446        /* Counter is xmm13 */
     6447        "vpxor          %%xmm13, %%xmm13, %%xmm13\n\t"
     6448        "vpxor          %%xmm15, %%xmm15, %%xmm15\n\t"
     6449        "movl           %[ibytes], %%edx\n\t"
     6450        "cmpl           $12, %%edx\n\t"
     6451        "jne            35f\n\t"
     6452        CALC_IV_12_AVX2()
     6453        "jmp            39f\n\t"
     6454        "\n"
     6455        "35:\n\t"
     6456        CALC_IV_AVX2()
     6457        "\n"
     6458        "39:\n\t"
     6459
     6460        CALC_AAD_AVX2()
     6461
     6462        "# Calculate counter and H\n\t"
     6463        "vpsrlq         $63, " VAR(HR) ", %%xmm5\n\t"
     6464        "vpsllq         $1, " VAR(HR) ", %%xmm4\n\t"
     6465        "vpslldq        $8, %%xmm5, %%xmm5\n\t"
     6466        "vpor           %%xmm5, %%xmm4, %%xmm4\n\t"
     6467        "vpshufd        $0xff, " VAR(HR) ", " VAR(HR) "\n\t"
     6468        "vpsrad         $31, " VAR(HR) ", " VAR(HR) "\n\t"
     6469        "vpshufb        %[BSWAP_EPI64], %%xmm13, %%xmm13\n\t"
     6470        "vpand          %[MOD2_128], " VAR(HR) ", " VAR(HR) "\n\t"
     6471        "vpaddd         %[ONE], %%xmm13, %%xmm13\n\t"
     6472        "vpxor          %%xmm4, " VAR(HR) ", " VAR(HR) "\n\t"
     6473        "vmovdqu        %%xmm13, " VAR(CTR1) "\n\t"
     6474
     6475        "xorl           " VAR(KR) ", " VAR(KR) "\n\t"
     6476
     6477#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
     6478        "cmpl           $128, %[nbytes]\n\t"
     6479        "jl             5f\n\t"
     6480
     6481        CALC_HT_8_AVX2()
     6482
     6483        "movl           %[nbytes], %%r13d\n\t"
     6484        "andl           $0xffffff80, %%r13d\n\t"
     6485        "\n"
     6486        "2:\n\t"
     6487        VAESENC_128_GHASH_AVX2(%%rcx, 128)
     6488        "addl           $128, " VAR(KR) "\n\t"
     6489        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6490        "jl             2b\n\t"
     6491
     6492        "vmovdqa        %%xmm2, " VAR(XR) "\n\t"
     6493        "vmovdqu        (%%rsp), " VAR(HR) "\n\t"
     6494    "5:\n\t"
     6495        "movl           %[nbytes], %%edx\n\t"
     6496        "cmpl           %%edx, " VAR(KR) "\n\t"
     6497        "jge            55f\n\t"
     6498#endif
     6499        "movl           %[nbytes], %%r13d\n\t"
     6500        "andl           $0xfffffff0, %%r13d\n\t"
     6501        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6502        "jge            13f\n\t"
     6503
     6504            "vmovdqa            %[MOD2_128], %%xmm0\n\t"
     6505        "\n"
     6506        "12:\n\t"
     6507        "vmovdqu        (%[in]," VAR(KR64) ",1), %%xmm9\n\t"
     6508        "vmovdqu        " VAR(CTR1) ", %%xmm5\n\t"
     6509        "vpshufb        %[BSWAP_MASK], %%xmm9, %%xmm1\n\t"
     6510        "vpshufb        %[BSWAP_EPI64], %%xmm5, %%xmm4\n\t"
     6511        "vpaddd         %[ONE], %%xmm5, %%xmm5\n\t"
     6512        "vpxor          " VAR(XR) ", %%xmm1, %%xmm1\n\t"
     6513        "vmovdqu        %%xmm5, " VAR(CTR1) "\n\t"
     6514        VAESENC_GFMUL_SB_AVX2(%%xmm9, HR, %%xmm1, CTR1)
     6515        "vmovdqu        %%xmm4, (%[out]," VAR(KR64) ",1)\n\t"
     6516        "addl           $16, " VAR(KR) "\n\t"
     6517        "cmpl           %%r13d, " VAR(KR) "\n\t"
     6518        "jl             12b\n\t"
     6519        "\n"
     6520        "13:\n\t"
     6521
     6522        AESENC_LAST15_DEC_AVX2()
     6523        "\n"
     6524        "55:\n\t"
     6525
     6526        CALC_TAG_AVX2()
     6527        "addq           $" VAR(STACK_OFFSET) ", %%rsp\n\t"
     6528        "popq           %%rdx\n\t"
     6529        CMP_TAG_AVX()
     6530        "vzeroupper\n\t"
     6531
     6532        :
     6533        : [KEY] "r" (key),
     6534          [in] "r" (in), [out] "r" (out), [nr] "r" (nr),
     6535          [nbytes] "r" (nbytes), [abytes] "r" (abytes), [addt] "r" (addt),
     6536          [ivec] "r" (iv), [ibytes] "r" (ivLen), [tbytes] "r" (tagLen),
     6537          [tag] "r" (tag), [res] "r" (res),
     6538          [BSWAP_MASK] "m" (BSWAP_MASK),
     6539          [BSWAP_EPI64] "m" (BSWAP_EPI64),
     6540          [ONE] "m" (ONE),
     6541#if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
     6542          [TWO] "m" (TWO), [THREE] "m" (THREE), [FOUR] "m" (FOUR),
     6543          [FIVE] "m" (FIVE), [SIX] "m" (SIX), [SEVEN] "m" (SEVEN),
     6544          [EIGHT] "m" (EIGHT),
     6545#endif
     6546          [MOD2_128] "m" (MOD2_128)
     6547        : "xmm15", "xmm14", "xmm13", "xmm12",
     6548          "xmm0", "xmm1", "xmm2", "xmm3", "memory",
     6549          "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11",
     6550          "rcx", "r13"
     6551        );
     6552    }
     6553#endif /* HAVE_INTEL_AVX2 */
     6554#endif /* HAVE_INTEL_AVX1 */
     6555#endif /* HAVE_AES_DECRYPT */
     6556
     6557#else /* _MSC_VER */
     6558/* The following are for MSC based builds which do not allow
     6559 * inline assembly. Intrinsic functions are used instead. */
     6560
     6561#define aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T)         \
     6562do                                                         \
     6563{                                                          \
     6564    word32 iv12[4];                                        \
     6565    iv12[0] = *(word32*)&ivec[0];                          \
     6566    iv12[1] = *(word32*)&ivec[4];                          \
     6567    iv12[2] = *(word32*)&ivec[8];                          \
     6568    iv12[3] = 0x01000000;                                  \
     6569    Y = _mm_loadu_si128((__m128i*)iv12);                   \
     6570                                                           \
     6571    /* (Compute E[ZERO, KS] and E[Y0, KS] together */      \
     6572    tmp1 = _mm_load_si128(&KEY[0]);                        \
     6573    tmp2 = _mm_xor_si128(Y, KEY[0]);                       \
     6574    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                 \
     6575    tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);                 \
     6576    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                 \
     6577    tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);                 \
     6578    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                 \
     6579    tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);                 \
     6580    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                 \
     6581    tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);                 \
     6582    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                 \
     6583    tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);                 \
     6584    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                 \
     6585    tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);                 \
     6586    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                 \
     6587    tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);                 \
     6588    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                 \
     6589    tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);                 \
     6590    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                 \
     6591    tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);                 \
     6592    lastKey = KEY[10];                                     \
     6593    if (nr > 10) {                                         \
     6594        tmp1 = _mm_aesenc_si128(tmp1, lastKey);            \
     6595        tmp2 = _mm_aesenc_si128(tmp2, lastKey);            \
     6596        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);            \
     6597        tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);            \
     6598        lastKey = KEY[12];                                 \
     6599        if (nr > 12) {                                     \
     6600            tmp1 = _mm_aesenc_si128(tmp1, lastKey);        \
     6601            tmp2 = _mm_aesenc_si128(tmp2, lastKey);        \
     6602            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);        \
     6603            tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);        \
     6604            lastKey = KEY[14];                             \
     6605        }                                                  \
     6606    }                                                      \
     6607    H = _mm_aesenclast_si128(tmp1, lastKey);               \
     6608    T = _mm_aesenclast_si128(tmp2, lastKey);               \
     6609    H = _mm_shuffle_epi8(H, BSWAP_MASK);                   \
     6610}                                                          \
     6611while (0)
     6612
     6613#define aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T)         \
     6614do                                                              \
     6615{                                                               \
     6616    if (ibytes % 16) {                                          \
     6617        i = ibytes / 16;                                        \
     6618        for (j=0; j < (int)(ibytes%16); j++)                    \
     6619            ((unsigned char*)&last_block)[j] = ivec[i*16+j];    \
     6620    }                                                           \
     6621    tmp1 = _mm_load_si128(&KEY[0]);                             \
     6622    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
     6623    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
     6624    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
     6625    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
     6626    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
     6627    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
     6628    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
     6629    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
     6630    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
     6631    lastKey = KEY[10];                                          \
     6632    if (nr > 10) {                                              \
     6633        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
     6634        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
     6635        lastKey = KEY[12];                                      \
     6636        if (nr > 12) {                                          \
     6637            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
     6638            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
     6639            lastKey = KEY[14];                                  \
     6640        }                                                       \
     6641    }                                                           \
     6642    H = _mm_aesenclast_si128(tmp1, lastKey);                    \
     6643    H = _mm_shuffle_epi8(H, BSWAP_MASK);                        \
     6644    Y = _mm_setzero_si128();                                    \
     6645    for (i=0; i < (int)(ibytes/16); i++) {                      \
     6646        tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);           \
     6647        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
     6648        Y = _mm_xor_si128(Y, tmp1);                             \
     6649        Y = gfmul_sw(Y, H);                                     \
     6650    }                                                           \
     6651    if (ibytes % 16) {                                          \
     6652        tmp1 = last_block;                                      \
     6653        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \
     6654        Y = _mm_xor_si128(Y, tmp1);                             \
     6655        Y = gfmul_sw(Y, H);                                     \
     6656    }                                                           \
     6657    tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);                 \
     6658    tmp1 = _mm_insert_epi64(tmp1, 0, 1);                        \
     6659    Y = _mm_xor_si128(Y, tmp1);                                 \
     6660    Y = gfmul_sw(Y, H);                                         \
     6661    Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */ \
     6662    tmp1 = _mm_xor_si128(Y, KEY[0]);                            \
     6663    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \
     6664    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \
     6665    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \
     6666    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \
     6667    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \
     6668    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \
     6669    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \
     6670    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \
     6671    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \
     6672    lastKey = KEY[10];                                          \
     6673    if (nr > 10) {                                              \
     6674        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \
     6675        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \
     6676        lastKey = KEY[12];                                      \
     6677        if (nr > 12) {                                          \
     6678            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \
     6679            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \
     6680            lastKey = KEY[14];                                  \
     6681        }                                                       \
     6682    }                                                           \
     6683    T = _mm_aesenclast_si128(tmp1, lastKey);                    \
     6684}                                                               \
     6685while (0)
     6686
     6687#define AES_ENC_8(j)                       \
     6688    tmp1 = _mm_aesenc_si128(tmp1, KEY[j]); \
     6689    tmp2 = _mm_aesenc_si128(tmp2, KEY[j]); \
     6690    tmp3 = _mm_aesenc_si128(tmp3, KEY[j]); \
     6691    tmp4 = _mm_aesenc_si128(tmp4, KEY[j]); \
     6692    tmp5 = _mm_aesenc_si128(tmp5, KEY[j]); \
     6693    tmp6 = _mm_aesenc_si128(tmp6, KEY[j]); \
     6694    tmp7 = _mm_aesenc_si128(tmp7, KEY[j]); \
     6695    tmp8 = _mm_aesenc_si128(tmp8, KEY[j]);
     6696
     6697#define AES_ENC_LAST_8()                                                  \
     6698    tmp1 =_mm_aesenclast_si128(tmp1, lastKey);                            \
     6699    tmp2 =_mm_aesenclast_si128(tmp2, lastKey);                            \
     6700    tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));  \
     6701    tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));  \
     6702    _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);                      \
     6703    _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);                      \
     6704    tmp3 =_mm_aesenclast_si128(tmp3, lastKey);                            \
     6705    tmp4 =_mm_aesenclast_si128(tmp4, lastKey);                            \
     6706    tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));  \
     6707    tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));  \
     6708    _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);                      \
     6709    _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);                      \
     6710    tmp5 =_mm_aesenclast_si128(tmp5, lastKey);                            \
     6711    tmp6 =_mm_aesenclast_si128(tmp6, lastKey);                            \
     6712    tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));  \
     6713    tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));  \
     6714    _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);                      \
     6715    _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);                      \
     6716    tmp7 =_mm_aesenclast_si128(tmp7, lastKey);                            \
     6717    tmp8 =_mm_aesenclast_si128(tmp8, lastKey);                            \
     6718    tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));  \
     6719    tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));  \
     6720    _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);                      \
     6721    _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);
     6722
    34196723
    34206724static __m128i gfmul_sw(__m128i a, __m128i b)
    34216725{
    34226726    __m128i r, t1, t2, t3, t4, t5, t6, t7;
    3423 #ifndef WOLFSSL_AES_GCM_SLOW_CLMUL
    3424     /* 128 x 128 Carryless Multiply */
    3425     t3 = _mm_clmulepi64_si128(a, b, 0x10);
    3426     t2 = _mm_clmulepi64_si128(a, b, 0x01);
    3427     t1 = _mm_clmulepi64_si128(a, b, 0x00);
    3428     t4 = _mm_clmulepi64_si128(a, b, 0x11);
    3429     t3 = _mm_xor_si128(t3, t2);
    3430     t2 = _mm_slli_si128(t3, 8);
    3431     t3 = _mm_srli_si128(t3, 8);
    3432     t1 = _mm_xor_si128(t1, t2);
    3433     t4 = _mm_xor_si128(t4, t3);
    3434 
    3435     /* shift left 1 bit - bits reversed */
    3436     t5 = _mm_srli_epi32(t1, 31);
    3437     t6 = _mm_srli_epi32(t4, 31);
    3438     t1 = _mm_slli_epi32(t1, 1);
    3439     t4 = _mm_slli_epi32(t4, 1);
    3440     t7 = _mm_srli_si128(t5, 12);
    3441     t5 = _mm_slli_si128(t5, 4);
    3442     t6 = _mm_slli_si128(t6, 4);
    3443     t4 = _mm_or_si128(t4, t7);
    3444     t1 = _mm_or_si128(t1, t5);
    3445     t4 = _mm_or_si128(t4, t6);
    3446 
    3447     /* Reduction */
    3448     t2 = _mm_clmulepi64_si128(t1, MOD2_128, 0x10);
    3449     t3 = _mm_shuffle_epi32(t1, 78);
    3450     t3 = _mm_xor_si128(t3, t2);
    3451     t2 = _mm_clmulepi64_si128(t3, MOD2_128, 0x10);
    3452     t3 = _mm_shuffle_epi32(t3, 78);
    3453     t3 = _mm_xor_si128(t3, t2);
    3454     r = _mm_xor_si128(t4, t3);
    3455 #else
    34566727    t2 = _mm_shuffle_epi32(b, 78);
    34576728    t3 = _mm_shuffle_epi32(a, 78);
     
    34976768    t7 = _mm_xor_si128(t7, t1);
    34986769    r = _mm_xor_si128(t4, t7);
    3499 #endif
    35006770
    35016771    return r;
    3502 }
     6772        }
    35036773
    35046774static void gfmul_only(__m128i a, __m128i b, __m128i* r0, __m128i* r1)
     
    35076777
    35086778    /* 128 x 128 Carryless Multiply */
    3509 #ifndef WOLFSSL_AES_GCM_SLOW_CLMUL
    3510     t3 = _mm_clmulepi64_si128(a, b, 0x10);
    3511     t2 = _mm_clmulepi64_si128(a, b, 0x01);
    3512     t1 = _mm_clmulepi64_si128(a, b, 0x00);
    3513     t4 = _mm_clmulepi64_si128(a, b, 0x11);
    3514     t3 = _mm_xor_si128(t3, t2);
    3515     t2 = _mm_slli_si128(t3, 8);
    3516     t3 = _mm_srli_si128(t3, 8);
    3517     t1 = _mm_xor_si128(t1, t2);
    3518     t4 = _mm_xor_si128(t4, t3);
    3519 #else
    35206779    t2 = _mm_shuffle_epi32(b, 78);
    35216780    t3 = _mm_shuffle_epi32(a, 78);
     
    35316790    t1 = _mm_xor_si128(t1, t3);
    35326791    t4 = _mm_xor_si128(t4, t2);
    3533 #endif
    35346792    *r0 = _mm_xor_si128(t1, *r0);
    35356793    *r1 = _mm_xor_si128(t4, *r1);
    3536 }
     6794            }
    35376795
    35386796static __m128i gfmul_shl1(__m128i a)
     
    35496807    t1 = _mm_xor_si128(t1, a);
    35506808    return t1;
    3551 }
     6809        }
    35526810
    35536811static __m128i ghash_red(__m128i r0, __m128i r1)
    35546812{
    35556813    __m128i t2, t3;
    3556 #ifndef WOLFSSL_AES_GCM_SLOW_CLMUL
    3557     t2 = _mm_clmulepi64_si128(r0, MOD2_128, 0x10);
    3558     t3 = _mm_shuffle_epi32(r0, 78);
    3559     t3 = _mm_xor_si128(t3, t2);
    3560     t2 = _mm_clmulepi64_si128(t3, MOD2_128, 0x10);
    3561     t3 = _mm_shuffle_epi32(t3, 78);
    3562     t3 = _mm_xor_si128(t3, t2);
    3563     return _mm_xor_si128(r1, t3);
    3564 #else
    35656814    __m128i t5, t6, t7;
    35666815
     
    35836832    t7 = _mm_xor_si128(t7, r0);
    35846833    return _mm_xor_si128(r1, t7);
    3585 #endif
    3586 }
     6834            }
    35876835
    35886836static __m128i gfmul_shifted(__m128i a, __m128i b)
     
    35916839    gfmul_only(a, b, &t0, &t1);
    35926840    return ghash_red(t0, t1);
    3593 }
     6841        }
    35946842
    35956843#ifndef AES_GCM_AESNI_NO_UNROLL
     
    36096857    gfmul_only(a8, b1, &t0, &t1);
    36106858    return ghash_red(t0, t1);
    3611 }
     6859    }
    36126860#endif
    36136861
    3614 /* See Intel® Carry-Less Multiplication Instruction
    3615  * and its Usage for Computing the GCM Mode White Paper
    3616  * by Shay Gueron, Intel Mobility Group, Israel Development Center;
    3617  * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */
    3618 
    3619 
    3620 /* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */
    3621 
    3622 static const __m128i ONE   = M128_INIT(0x0, 0x1);
    3623 #ifndef AES_GCM_AESNI_NO_UNROLL
    3624 static const __m128i TWO   = M128_INIT(0x0, 0x2);
    3625 static const __m128i THREE = M128_INIT(0x0, 0x3);
    3626 static const __m128i FOUR  = M128_INIT(0x0, 0x4);
    3627 static const __m128i FIVE  = M128_INIT(0x0, 0x5);
    3628 static const __m128i SIX   = M128_INIT(0x0, 0x6);
    3629 static const __m128i SEVEN = M128_INIT(0x0, 0x7);
    3630 static const __m128i EIGHT = M128_INIT(0x0, 0x8);
    3631 #endif
    3632 static const __m128i BSWAP_EPI64 = M128_INIT(0x0001020304050607, 0x08090a0b0c0d0e0f);
    3633 static const __m128i BSWAP_MASK  = M128_INIT(0x08090a0b0c0d0e0f, 0x0001020304050607);
    3634 
    3635 static void AES_GCM_encrypt(const unsigned char *in, unsigned char *out,
    3636                             const unsigned char* addt,
    3637                             const unsigned char* ivec,
    3638                             unsigned char *tag, unsigned int nbytes,
    3639                             unsigned int abytes, unsigned int ibytes,
    3640                             const unsigned char* key, int nr)
     6862
     6863static void AES_GCM_encrypt(const unsigned char *in,
     6864                              unsigned char *out,
     6865                              const unsigned char* addt,
     6866                              const unsigned char* ivec,
     6867                              unsigned char *tag, unsigned int nbytes,
     6868                              unsigned int abytes, unsigned int ibytes,
     6869                              unsigned int tbytes,
     6870                              const unsigned char* key, int nr)
    36416871{
    36426872    int i, j ,k;
     
    36546884#endif
    36556885
    3656     if (ibytes == 12) {
    3657         Y = _mm_setzero_si128();
    3658         for (j=0; j < 12; j++)
    3659             ((unsigned char*)&Y)[j] = ivec[j];
    3660         Y = _mm_insert_epi32(Y, 0x1000000, 3);
    3661             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
    3662         tmp1 = _mm_xor_si128(X, KEY[0]);
    3663         tmp2 = _mm_xor_si128(Y, KEY[0]);
    3664         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    3665         tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
    3666         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    3667         tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
    3668         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    3669         tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
    3670         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    3671         tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
    3672         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    3673         tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
    3674         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    3675         tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
    3676         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    3677         tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
    3678         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    3679         tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
    3680         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    3681         tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
    3682         lastKey = KEY[10];
    3683         if (nr > 10) {
    3684             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3685             tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    3686             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    3687             tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
    3688             lastKey = KEY[12];
    3689             if (nr > 12) {
    3690                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3691                 tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    3692                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    3693                 tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
    3694                 lastKey = KEY[14];
    3695             }
    3696         }
    3697         H = _mm_aesenclast_si128(tmp1, lastKey);
    3698         T = _mm_aesenclast_si128(tmp2, lastKey);
    3699         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    3700     }
    3701     else {
    3702         if (ibytes % 16) {
    3703             i = ibytes / 16;
    3704             for (j=0; j < (int)(ibytes%16); j++)
    3705                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
    3706         }
    3707         tmp1 = _mm_xor_si128(X, KEY[0]);
    3708         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    3709         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    3710         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    3711         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    3712         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    3713         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    3714         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    3715         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    3716         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    3717         lastKey = KEY[10];
    3718         if (nr > 10) {
    3719             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3720             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    3721             lastKey = KEY[12];
    3722             if (nr > 12) {
    3723                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3724                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    3725                 lastKey = KEY[14];
    3726             }
    3727         }
    3728         H = _mm_aesenclast_si128(tmp1, lastKey);
    3729         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    3730         Y = _mm_setzero_si128();
    3731         for (i=0; i < (int)(ibytes/16); i++) {
    3732             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
    3733             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    3734             Y = _mm_xor_si128(Y, tmp1);
    3735             Y = gfmul_sw(Y, H);
    3736         }
    3737         if (ibytes % 16) {
    3738             tmp1 = last_block;
    3739             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    3740             Y = _mm_xor_si128(Y, tmp1);
    3741             Y = gfmul_sw(Y, H);
    3742         }
    3743         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
    3744         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
    3745         Y = _mm_xor_si128(Y, tmp1);
    3746         Y = gfmul_sw(Y, H);
    3747         Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */
    3748         tmp1 = _mm_xor_si128(Y, KEY[0]);
    3749         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    3750         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    3751         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    3752         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    3753         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    3754         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    3755         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    3756         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    3757         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    3758         lastKey = KEY[10];
    3759         if (nr > 10) {
    3760             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3761             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    3762             lastKey = KEY[12];
    3763             if (nr > 12) {
    3764                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    3765                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    3766                 lastKey = KEY[14];
    3767             }
    3768         }
    3769         T = _mm_aesenclast_si128(tmp1, lastKey);
    3770     }
     6886    if (ibytes == 12)
     6887        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
     6888    else
     6889        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
    37716890
    37726891    for (i=0; i < (int)(abytes/16); i++) {
     
    37856904        X = gfmul_sw(X, H);
    37866905    }
    3787 
    37886906    tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
    37896907    ctr1 = _mm_add_epi32(tmp1, ONE);
     
    38266944        tmp7 =_mm_xor_si128(tmp7, KEY[0]);
    38276945        tmp8 =_mm_xor_si128(tmp8, KEY[0]);
    3828         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    3829         tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
    3830         tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);
    3831         tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);
    3832         tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);
    3833         tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);
    3834         tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);
    3835         tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);
    3836         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    3837         tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
    3838         tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);
    3839         tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);
    3840         tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);
    3841         tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);
    3842         tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);
    3843         tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);
    3844         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    3845         tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
    3846         tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);
    3847         tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);
    3848         tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);
    3849         tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);
    3850         tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);
    3851         tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);
    3852         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    3853         tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
    3854         tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);
    3855         tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);
    3856         tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);
    3857         tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);
    3858         tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);
    3859         tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);
    3860         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    3861         tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
    3862         tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);
    3863         tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);
    3864         tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);
    3865         tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);
    3866         tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);
    3867         tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);
    3868         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    3869         tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
    3870         tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);
    3871         tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);
    3872         tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);
    3873         tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);
    3874         tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);
    3875         tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);
    3876         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    3877         tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
    3878         tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);
    3879         tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);
    3880         tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);
    3881         tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);
    3882         tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);
    3883         tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);
    3884         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    3885         tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
    3886         tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);
    3887         tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);
    3888         tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);
    3889         tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);
    3890         tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);
    3891         tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);
    3892         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    3893         tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
    3894         tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);
    3895         tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);
    3896         tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);
    3897         tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);
    3898         tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);
    3899         tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);
     6946        AES_ENC_8(1);
     6947        AES_ENC_8(2);
     6948        AES_ENC_8(3);
     6949        AES_ENC_8(4);
     6950        AES_ENC_8(5);
     6951        AES_ENC_8(6);
     6952        AES_ENC_8(7);
     6953        AES_ENC_8(8);
     6954        AES_ENC_8(9);
    39006955        lastKey = KEY[10];
    39016956        if (nr > 10) {
    3902             tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);
    3903             tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);
    3904             tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);
    3905             tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);
    3906             tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);
    3907             tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);
    3908             tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);
    3909             tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);
    3910             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    3911             tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
    3912             tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);
    3913             tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);
    3914             tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);
    3915             tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);
    3916             tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);
    3917             tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);
     6957            AES_ENC_8(10);
     6958            AES_ENC_8(11);
    39186959            lastKey = KEY[12];
    39196960            if (nr > 12) {
    3920                 tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);
    3921                 tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);
    3922                 tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);
    3923                 tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);
    3924                 tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);
    3925                 tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);
    3926                 tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);
    3927                 tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);
    3928                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    3929                 tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
    3930                 tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);
    3931                 tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);
    3932                 tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);
    3933                 tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);
    3934                 tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);
    3935                 tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
     6961                AES_ENC_8(12);
     6962                AES_ENC_8(13);
    39366963                lastKey = KEY[14];
    39376964            }
    39386965        }
    3939         tmp1 =_mm_aesenclast_si128(tmp1, lastKey);
    3940         tmp2 =_mm_aesenclast_si128(tmp2, lastKey);
    3941         tmp3 =_mm_aesenclast_si128(tmp3, lastKey);
    3942         tmp4 =_mm_aesenclast_si128(tmp4, lastKey);
    3943         tmp5 =_mm_aesenclast_si128(tmp5, lastKey);
    3944         tmp6 =_mm_aesenclast_si128(tmp6, lastKey);
    3945         tmp7 =_mm_aesenclast_si128(tmp7, lastKey);
    3946         tmp8 =_mm_aesenclast_si128(tmp8, lastKey);
    3947         tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[0]));
    3948         tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[1]));
    3949         tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[2]));
    3950         tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[3]));
    3951         tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[4]));
    3952         tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[5]));
    3953         tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[6]));
    3954         tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[7]));
    3955         _mm_storeu_si128(&((__m128i*)out)[0], tmp1);
    3956         _mm_storeu_si128(&((__m128i*)out)[1], tmp2);
    3957         _mm_storeu_si128(&((__m128i*)out)[2], tmp3);
    3958         _mm_storeu_si128(&((__m128i*)out)[3], tmp4);
    3959         _mm_storeu_si128(&((__m128i*)out)[4], tmp5);
    3960         _mm_storeu_si128(&((__m128i*)out)[5], tmp6);
    3961         _mm_storeu_si128(&((__m128i*)out)[6], tmp7);
    3962         _mm_storeu_si128(&((__m128i*)out)[7], tmp8);
     6966        AES_ENC_LAST_8();
    39636967
    39646968        for (i=1; i < (int)(nbytes/16/8); i++) {
     
    41357139                }
    41367140            }
    4137             tmp1 =_mm_aesenclast_si128(tmp1, lastKey);
    4138             tmp2 =_mm_aesenclast_si128(tmp2, lastKey);
    4139             tmp3 =_mm_aesenclast_si128(tmp3, lastKey);
    4140             tmp4 =_mm_aesenclast_si128(tmp4, lastKey);
    4141             tmp5 =_mm_aesenclast_si128(tmp5, lastKey);
    4142             tmp6 =_mm_aesenclast_si128(tmp6, lastKey);
    4143             tmp7 =_mm_aesenclast_si128(tmp7, lastKey);
    4144             tmp8 =_mm_aesenclast_si128(tmp8, lastKey);
    4145             tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));
    4146             tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));
    4147             tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));
    4148             tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));
    4149             tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));
    4150             tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));
    4151             tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));
    4152             tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));
    4153             _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);
    4154             _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);
    4155             _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);
    4156             _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);
    4157             _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);
    4158             _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);
    4159             _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);
    4160             _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);
     7141            AES_ENC_LAST_8();
    41617142        }
    41627143
     
    42047185        X = gfmul_shifted(X, H);
    42057186    }
    4206 #else
     7187#else /* AES_GCM_AESNI_NO_UNROLL */
    42077188    for (k = 0; k < (int)(nbytes/16) && k < 1; k++) {
    42087189        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
     
    42337214        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
    42347215        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4235         X =_mm_xor_si128(X, tmp1);
    4236     }
     7216    X = _mm_xor_si128(X, tmp1);
     7217        }
    42377218    for (; k < (int)(nbytes/16); k++) {
    42387219        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
     
    42637244        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));
    42647245        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);
    4265         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
     7246            tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    42667247        X =_mm_xor_si128(X, tmp1);
    4267     }
     7248        }
    42687249    if (k > 0) {
    42697250        X = gfmul_shifted(X, H);
    4270     }
    4271 #endif
     7251        }
     7252#endif /* AES_GCM_AESNI_NO_UNROLL */
     7253
    42727254    /* If one partial block remains */
    42737255    if (nbytes % 16) {
     
    43137295    X = _mm_shuffle_epi8(X, BSWAP_MASK);
    43147296    T = _mm_xor_si128(X, T);
    4315     _mm_storeu_si128((__m128i*)tag, T);
    4316 }
    4317 
    4318 #ifdef HAVE_INTEL_AVX2
    4319 /* Encrypt with key in xmm12. */
    4320 #define VAESENC()                                       \
    4321             "vaesenc    %%xmm12, %[tmp1], %[tmp1]\n\t"  \
    4322             "vaesenc    %%xmm12, %[tmp2], %[tmp2]\n\t"  \
    4323             "vaesenc    %%xmm12, %[tmp3], %[tmp3]\n\t"  \
    4324             "vaesenc    %%xmm12, %[tmp4], %[tmp4]\n\t"  \
    4325             "vaesenc    %%xmm12, %[tmp5], %[tmp5]\n\t"  \
    4326             "vaesenc    %%xmm12, %[tmp6], %[tmp6]\n\t"  \
    4327             "vaesenc    %%xmm12, %[tmp7], %[tmp7]\n\t"  \
    4328             "vaesenc    %%xmm12, %[tmp8], %[tmp8]\n\t"
    4329 
    4330 
    4331 /* Encrypt and GCM mul with the nth round key. */
    4332 #define VAESENC_PCLMUL_N(o1, o2, o3)                                \
    4333                 "vmovaps        "#o1"(%[KEY]), %%xmm12\n\t"         \
    4334                 "vmovdqu        "#o2"(%[out]), %%xmm1\n\t"          \
    4335                 "vaesenc        %%xmm12, %[tmp1], %[tmp1]\n\t"      \
    4336                 "vmovaps        "#o3"(%[HT]), %%xmm0\n\t"           \
    4337                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"  \
    4338                 "vaesenc        %%xmm12, %[tmp2], %[tmp2]\n\t"      \
    4339                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"   \
    4340                 "vaesenc        %%xmm12, %[tmp3], %[tmp3]\n\t"      \
    4341                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"    \
    4342                 "vaesenc        %%xmm12, %[tmp4], %[tmp4]\n\t"      \
    4343                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"    \
    4344                 "vaesenc        %%xmm12, %[tmp5], %[tmp5]\n\t"      \
    4345                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"    \
    4346                 "vaesenc        %%xmm12, %[tmp6], %[tmp6]\n\t"      \
    4347                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"      \
    4348                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"           \
    4349                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"           \
    4350                 "vaesenc        %%xmm12, %[tmp7], %[tmp7]\n\t"      \
    4351                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"        \
    4352                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"         \
    4353                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"        \
    4354                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"        \
    4355                 "vaesenc        %%xmm12, %[tmp8], %[tmp8]\n\t"
    4356 
    4357 static void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
    4358                                  const unsigned char* addt,
    4359                                  const unsigned char* ivec,
    4360                                  unsigned char *tag, unsigned int nbytes,
    4361                                  unsigned int abytes, unsigned int ibytes,
    4362                                  const unsigned char* key, int nr)
    4363 {
    4364     int i, j ,k;
    4365     __m128i ctr1;
    4366     __m128i H, Y, T;
    4367     __m128i X = _mm_setzero_si128();
    4368     __m128i *KEY = (__m128i*)key, lastKey;
    4369     __m128i last_block = _mm_setzero_si128();
    4370 #if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
    4371     __m128i HT[8];
    4372     register __m128i tmp1 asm("xmm4");
    4373     register __m128i tmp2 asm("xmm5");
    4374     register __m128i tmp3 asm("xmm6");
    4375     register __m128i tmp4 asm("xmm7");
    4376     register __m128i tmp5 asm("xmm8");
    4377     register __m128i tmp6 asm("xmm9");
    4378     register __m128i tmp7 asm("xmm10");
    4379     register __m128i tmp8 asm("xmm11");
    4380     __m128i pctr1[1];
    4381     register __m128i XV asm("xmm2");
    4382 #else
    4383     __m128i tmp1, tmp2;
    4384 #endif
    4385 
    4386     if (ibytes == 12) {
    4387         Y = _mm_setzero_si128();
    4388         for (j=0; j < 12; j++)
    4389             ((unsigned char*)&Y)[j] = ivec[j];
    4390         Y = _mm_insert_epi32(Y, 0x1000000, 3);
    4391             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
    4392         tmp1 = _mm_xor_si128(X, KEY[0]);
    4393         tmp2 = _mm_xor_si128(Y, KEY[0]);
    4394         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    4395         tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
    4396         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    4397         tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
    4398         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    4399         tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
    4400         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    4401         tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
    4402         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    4403         tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
    4404         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    4405         tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
    4406         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    4407         tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
    4408         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    4409         tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
    4410         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    4411         tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
    4412         lastKey = KEY[10];
    4413         if (nr > 10) {
    4414             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4415             tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    4416             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    4417             tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
    4418             lastKey = KEY[12];
    4419             if (nr > 12) {
    4420                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4421                 tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    4422                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    4423                 tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
    4424                 lastKey = KEY[14];
    4425             }
    4426         }
    4427         H = _mm_aesenclast_si128(tmp1, lastKey);
    4428         T = _mm_aesenclast_si128(tmp2, lastKey);
    4429         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    4430     }
    4431     else {
    4432         if (ibytes % 16) {
    4433             i = ibytes / 16;
    4434             for (j=0; j < (int)(ibytes%16); j++)
    4435                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
    4436         }
    4437         tmp1 = _mm_xor_si128(X, KEY[0]);
    4438         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    4439         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    4440         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    4441         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    4442         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    4443         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    4444         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    4445         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    4446         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    4447         lastKey = KEY[10];
    4448         if (nr > 10) {
    4449             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4450             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    4451             lastKey = KEY[12];
    4452             if (nr > 12) {
    4453                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4454                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    4455                 lastKey = KEY[14];
    4456             }
    4457         }
    4458         H = _mm_aesenclast_si128(tmp1, lastKey);
    4459         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    4460         Y = _mm_setzero_si128();
    4461         for (i=0; i < (int)(ibytes/16); i++) {
    4462             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
    4463             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4464             Y = _mm_xor_si128(Y, tmp1);
    4465             Y = gfmul_sw(Y, H);
    4466         }
    4467         if (ibytes % 16) {
    4468             tmp1 = last_block;
    4469             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4470             Y = _mm_xor_si128(Y, tmp1);
    4471             Y = gfmul_sw(Y, H);
    4472         }
    4473         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
    4474         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
    4475         Y = _mm_xor_si128(Y, tmp1);
    4476         Y = gfmul_sw(Y, H);
    4477         Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */
    4478         tmp1 = _mm_xor_si128(Y, KEY[0]);
    4479         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    4480         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    4481         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    4482         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    4483         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    4484         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    4485         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    4486         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    4487         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    4488         lastKey = KEY[10];
    4489         if (nr > 10) {
    4490             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4491             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    4492             lastKey = KEY[12];
    4493             if (nr > 12) {
    4494                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4495                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    4496                 lastKey = KEY[14];
    4497             }
    4498         }
    4499         T = _mm_aesenclast_si128(tmp1, lastKey);
    4500     }
    4501 
    4502     for (i=0; i < (int)(abytes/16); i++) {
    4503         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
    4504         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4505         X = _mm_xor_si128(X, tmp1);
    4506         X = gfmul_sw(X, H);
    4507     }
    4508     if (abytes%16) {
    4509         last_block = _mm_setzero_si128();
    4510         for (j=0; j < (int)(abytes%16); j++)
    4511             ((unsigned char*)&last_block)[j] = addt[i*16+j];
    4512         tmp1 = last_block;
    4513         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4514         X = _mm_xor_si128(X, tmp1);
    4515         X = gfmul_sw(X, H);
    4516     }
    4517 
    4518     tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
    4519     ctr1 = _mm_add_epi32(tmp1, ONE);
    4520     H = gfmul_shl1(H);
    4521 
    4522 #if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
    4523     i = 0;
    4524     if (nbytes >= 16*8) {
    4525         HT[0] = H;
    4526         HT[1] = gfmul_shifted(H, H);
    4527         HT[2] = gfmul_shifted(H, HT[1]);
    4528         HT[3] = gfmul_shifted(HT[1], HT[1]);
    4529         HT[4] = gfmul_shifted(HT[1], HT[2]);
    4530         HT[5] = gfmul_shifted(HT[2], HT[2]);
    4531         HT[6] = gfmul_shifted(HT[2], HT[3]);
    4532         HT[7] = gfmul_shifted(HT[3], HT[3]);
    4533 
    4534         pctr1[0] = ctr1;
    4535         __asm__ __volatile__ (
    4536             "vmovaps    (%[pctr1]), %%xmm0\n\t"
    4537             "vmovaps    %[BSWAP_EPI64], %%xmm1\n\t"
    4538             "vpshufb    %%xmm1, %%xmm0, %[tmp1]\n\t"
    4539             "vpaddd     %[ONE], %%xmm0, %[tmp2]\n\t"
    4540             "vpshufb    %%xmm1, %[tmp2], %[tmp2]\n\t"
    4541             "vpaddd     %[TWO], %%xmm0, %[tmp3]\n\t"
    4542             "vpshufb    %%xmm1, %[tmp3], %[tmp3]\n\t"
    4543             "vpaddd     %[THREE], %%xmm0, %[tmp4]\n\t"
    4544             "vpshufb    %%xmm1, %[tmp4], %[tmp4]\n\t"
    4545             "vpaddd     %[FOUR], %%xmm0, %[tmp5]\n\t"
    4546             "vpshufb    %%xmm1, %[tmp5], %[tmp5]\n\t"
    4547             "vpaddd     %[FIVE], %%xmm0, %[tmp6]\n\t"
    4548             "vpshufb    %%xmm1, %[tmp6], %[tmp6]\n\t"
    4549             "vpaddd     %[SIX], %%xmm0, %[tmp7]\n\t"
    4550             "vpshufb    %%xmm1, %[tmp7], %[tmp7]\n\t"
    4551             "vpaddd     %[SEVEN], %%xmm0, %[tmp8]\n\t"
    4552             "vpshufb    %%xmm1, %[tmp8], %[tmp8]\n\t"
    4553             "vpaddd     %[EIGHT], %%xmm0, %%xmm0\n\t"
    4554 
    4555             "vmovaps    (%[KEY]), %%xmm1\n\t"
    4556             "vmovaps    %%xmm0, (%[pctr1])\n\t"
    4557             "vpxor      %%xmm1, %[tmp1], %[tmp1]\n\t"
    4558             "vpxor      %%xmm1, %[tmp2], %[tmp2]\n\t"
    4559             "vpxor      %%xmm1, %[tmp3], %[tmp3]\n\t"
    4560             "vpxor      %%xmm1, %[tmp4], %[tmp4]\n\t"
    4561             "vpxor      %%xmm1, %[tmp5], %[tmp5]\n\t"
    4562             "vpxor      %%xmm1, %[tmp6], %[tmp6]\n\t"
    4563             "vpxor      %%xmm1, %[tmp7], %[tmp7]\n\t"
    4564             "vpxor      %%xmm1, %[tmp8], %[tmp8]\n\t"
    4565 
    4566             "vmovaps    16(%[KEY]), %%xmm12\n\t"
    4567             VAESENC()
    4568             "vmovaps    32(%[KEY]), %%xmm12\n\t"
    4569             VAESENC()
    4570             "vmovaps    48(%[KEY]), %%xmm12\n\t"
    4571             VAESENC()
    4572             "vmovaps    64(%[KEY]), %%xmm12\n\t"
    4573             VAESENC()
    4574             "vmovaps    80(%[KEY]), %%xmm12\n\t"
    4575             VAESENC()
    4576             "vmovaps    96(%[KEY]), %%xmm12\n\t"
    4577             VAESENC()
    4578             "vmovaps    112(%[KEY]), %%xmm12\n\t"
    4579             VAESENC()
    4580             "vmovaps    128(%[KEY]), %%xmm12\n\t"
    4581             VAESENC()
    4582             "vmovaps    144(%[KEY]), %%xmm12\n\t"
    4583             VAESENC()
    4584             "cmpl       $11, %[nr]\n\t"
    4585             "vmovaps    160(%[KEY]), %%xmm12\n\t"
    4586             "jl         L_enc128_enclast\n\t"
    4587 
    4588             VAESENC()
    4589             "vmovaps    176(%[KEY]), %%xmm12\n\t"
    4590             VAESENC()
    4591             "cmpl       $13, %[nr]\n\t"
    4592             "vmovaps    192(%[KEY]), %%xmm12\n\t"
    4593             "jl         L_enc128_enclast\n\t"
    4594 
    4595             VAESENC()
    4596             "vmovaps    208(%[KEY]), %%xmm12\n\t"
    4597             VAESENC()
    4598             "vmovaps    224(%[KEY]), %%xmm12\n\t"
    4599             "\n"
    4600         "L_enc128_enclast:\n\t"
    4601             "vaesenclast        %%xmm12, %[tmp1], %[tmp1]\n\t"
    4602             "vaesenclast        %%xmm12, %[tmp2], %[tmp2]\n\t"
    4603             "vpxor              (%[in]), %[tmp1], %[tmp1]\n\t"
    4604             "vpxor              16(%[in]), %[tmp2], %[tmp2]\n\t"
    4605             "vmovdqu    %[tmp1], (%[out])\n\t"
    4606             "vmovdqu    %[tmp2], 16(%[out])\n\t"
    4607             "vaesenclast        %%xmm12, %[tmp3], %[tmp3]\n\t"
    4608             "vaesenclast        %%xmm12, %[tmp4], %[tmp4]\n\t"
    4609             "vpxor              32(%[in]), %[tmp3], %[tmp3]\n\t"
    4610             "vpxor              48(%[in]), %[tmp4], %[tmp4]\n\t"
    4611             "vmovdqu    %[tmp3], 32(%[out])\n\t"
    4612             "vmovdqu    %[tmp4], 48(%[out])\n\t"
    4613             "vaesenclast        %%xmm12, %[tmp5], %[tmp5]\n\t"
    4614             "vaesenclast        %%xmm12, %[tmp6], %[tmp6]\n\t"
    4615             "vpxor              64(%[in]), %[tmp5], %[tmp5]\n\t"
    4616             "vpxor              80(%[in]), %[tmp6], %[tmp6]\n\t"
    4617             "vmovdqu    %[tmp5], 64(%[out])\n\t"
    4618             "vmovdqu    %[tmp6], 80(%[out])\n\t"
    4619             "vaesenclast        %%xmm12, %[tmp7], %[tmp7]\n\t"
    4620             "vaesenclast        %%xmm12, %[tmp8], %[tmp8]\n\t"
    4621             "vpxor              96(%[in]), %[tmp7], %[tmp7]\n\t"
    4622             "vpxor              112(%[in]), %[tmp8], %[tmp8]\n\t"
    4623             "vmovdqu    %[tmp7], 96(%[out])\n\t"
    4624             "vmovdqu    %[tmp8], 112(%[out])\n\t"
    4625 
    4626         : [tmp1] "=xr" (tmp1), [tmp2] "=xr" (tmp2), [tmp3] "=xr" (tmp3),
    4627           [tmp4] "=xr" (tmp4), [tmp5] "=xr" (tmp5), [tmp6] "=xr" (tmp6),
    4628           [tmp7] "=xr" (tmp7), [tmp8] "=xr" (tmp8)
    4629         : [KEY] "r" (KEY), [pctr1] "r" (pctr1),
    4630           [in] "r" (&in[i*16*8]), [out] "r" (&out[i*16*8]), [nr] "r" (nr),
    4631           [BSWAP_EPI64] "m" (BSWAP_EPI64),
    4632           [ONE] "m" (ONE), [TWO] "m" (TWO),
    4633           [THREE] "m" (THREE), [FOUR] "m" (FOUR),
    4634           [FIVE] "m" (FIVE), [SIX] "m" (SIX),
    4635           [SEVEN] "m" (SEVEN), [EIGHT] "m" (EIGHT)
    4636         : "xmm15", "xmm14", "xmm13", "xmm12",
    4637           "xmm0", "xmm1", "xmm3", "memory"
    4638         );
    4639 
    4640         XV = X;
    4641         for (i=1; i < (int)(nbytes/16/8); i++) {
    4642             __asm__ __volatile__ (
    4643                 "vmovaps        (%[pctr1]), %%xmm0\n\t"
    4644                 "vmovaps        %[BSWAP_EPI64], %%xmm1\n\t"
    4645                 "vpshufb        %%xmm1, %%xmm0, %[tmp1]\n\t"
    4646                 "vpaddd         %[ONE], %%xmm0, %[tmp2]\n\t"
    4647                 "vpshufb        %%xmm1, %[tmp2], %[tmp2]\n\t"
    4648                 "vpaddd         %[TWO], %%xmm0, %[tmp3]\n\t"
    4649                 "vpshufb        %%xmm1, %[tmp3], %[tmp3]\n\t"
    4650                 "vpaddd         %[THREE], %%xmm0, %[tmp4]\n\t"
    4651                 "vpshufb        %%xmm1, %[tmp4], %[tmp4]\n\t"
    4652                 "vpaddd         %[FOUR], %%xmm0, %[tmp5]\n\t"
    4653                 "vpshufb        %%xmm1, %[tmp5], %[tmp5]\n\t"
    4654                 "vpaddd         %[FIVE], %%xmm0, %[tmp6]\n\t"
    4655                 "vpshufb        %%xmm1, %[tmp6], %[tmp6]\n\t"
    4656                 "vpaddd         %[SIX], %%xmm0, %[tmp7]\n\t"
    4657                 "vpshufb        %%xmm1, %[tmp7], %[tmp7]\n\t"
    4658                 "vpaddd         %[SEVEN], %%xmm0, %[tmp8]\n\t"
    4659                 "vpshufb        %%xmm1, %[tmp8], %[tmp8]\n\t"
    4660                 "vpaddd         %[EIGHT], %%xmm0, %%xmm0\n\t"
    4661 
    4662                 "vmovaps        (%[KEY]), %%xmm1\n\t"
    4663                 "vmovaps        %%xmm0, (%[pctr1])\n\t"
    4664                 "vpxor          %%xmm1, %[tmp1], %[tmp1]\n\t"
    4665                 "vpxor          %%xmm1, %[tmp2], %[tmp2]\n\t"
    4666                 "vpxor          %%xmm1, %[tmp3], %[tmp3]\n\t"
    4667                 "vpxor          %%xmm1, %[tmp4], %[tmp4]\n\t"
    4668                 "vpxor          %%xmm1, %[tmp5], %[tmp5]\n\t"
    4669                 "vpxor          %%xmm1, %[tmp6], %[tmp6]\n\t"
    4670                 "vpxor          %%xmm1, %[tmp7], %[tmp7]\n\t"
    4671                 "vpxor          %%xmm1, %[tmp8], %[tmp8]\n\t"
    4672 
    4673                 "vmovaps        16(%[KEY]), %%xmm12\n\t"
    4674                 "vmovdqu        -128(%[out]), %%xmm1\n\t"
    4675                 "vaesenc        %%xmm12, %[tmp1], %[tmp1]\n\t"
    4676                 "vmovaps        112(%[HT]), %%xmm0\n\t"
    4677                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    4678                 "vpxor          %[XV], %%xmm1, %%xmm1\n\t"
    4679                 "vaesenc        %%xmm12, %[tmp2], %[tmp2]\n\t"
    4680                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    4681                 "vaesenc        %%xmm12, %[tmp3], %[tmp3]\n\t"
    4682                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    4683                 "vaesenc        %%xmm12, %[tmp4], %[tmp4]\n\t"
    4684                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    4685                 "vaesenc        %%xmm12, %[tmp5], %[tmp5]\n\t"
    4686                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    4687                 "vaesenc        %%xmm12, %[tmp6], %[tmp6]\n\t"
    4688                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    4689                 "vpslldq        $8, %%xmm13, %%xmm2\n\t"
    4690                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    4691                 "vaesenc        %%xmm12, %[tmp7], %[tmp7]\n\t"
    4692                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    4693                 "vpxor          %%xmm13, %%xmm1, %%xmm3\n\t"
    4694                 "vaesenc        %%xmm12, %[tmp8], %[tmp8]\n\t"
    4695 
    4696                 VAESENC_PCLMUL_N( 32, -112, 96)
    4697                 VAESENC_PCLMUL_N( 48,  -96, 80)
    4698                 VAESENC_PCLMUL_N( 64,  -80, 64)
    4699                 VAESENC_PCLMUL_N( 80,  -64, 48)
    4700                 VAESENC_PCLMUL_N( 96,  -48, 32)
    4701                 VAESENC_PCLMUL_N(112,  -32, 16)
    4702                 VAESENC_PCLMUL_N(128,  -16,  0)
    4703 
    4704                 "vmovaps        144(%[KEY]), %%xmm12\n\t"
    4705                 "vaesenc        %%xmm12, %[tmp1], %[tmp1]\n\t"
    4706                 "vmovdqa        %[MOD2_128], %%xmm0\n\t"
    4707                 "vaesenc        %%xmm12, %[tmp2], %[tmp2]\n\t"
    4708                 "vpclmulqdq     $16, %%xmm0, %%xmm2, %%xmm14\n\t"
    4709                 "vaesenc        %%xmm12, %[tmp3], %[tmp3]\n\t"
    4710                 "vpshufd        $78, %%xmm2, %%xmm13\n\t"
    4711                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    4712                 "vaesenc        %%xmm12, %[tmp4], %[tmp4]\n\t"
    4713                 "vpclmulqdq     $16, %%xmm0, %%xmm13, %%xmm14\n\t"
    4714                 "vaesenc        %%xmm12, %[tmp5], %[tmp5]\n\t"
    4715                 "vpshufd        $78, %%xmm13, %%xmm13\n\t"
    4716                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    4717                 "vpxor          %%xmm3, %%xmm13, %%xmm13\n\t"
    4718                 "vaesenc        %%xmm12, %[tmp6], %[tmp6]\n\t"
    4719                 "vmovdqa        %%xmm13, %%xmm2\n\t"
    4720                 "vaesenc        %%xmm12, %[tmp7], %[tmp7]\n\t"
    4721                 "vaesenc        %%xmm12, %[tmp8], %[tmp8]\n\t"
    4722                 "cmpl           $11, %[nr]\n\t"
    4723                 "vmovaps        160(%[KEY]), %%xmm12\n\t"
    4724                 "jl             %=f\n\t"
    4725 
    4726                 VAESENC()
    4727                 "vmovaps        176(%[KEY]), %%xmm12\n\t"
    4728                 VAESENC()
    4729                 "cmpl           $13, %[nr]\n\t"
    4730                 "vmovaps        192(%[KEY]), %%xmm12\n\t"
    4731                 "jl             %=f\n\t"
    4732 
    4733                 VAESENC()
    4734                 "vmovaps        208(%[KEY]), %%xmm12\n\t"
    4735                 VAESENC()
    4736                 "vmovaps        224(%[KEY]), %%xmm12\n\t"
    4737 
    4738                 "%=:\n\t"
    4739                 "vaesenclast    %%xmm12, %[tmp1], %[tmp1]\n\t"
    4740                 "vaesenclast    %%xmm12, %[tmp2], %[tmp2]\n\t"
    4741                 "vpxor          (%[in]), %[tmp1], %[tmp1]\n\t"
    4742                 "vpxor          16(%[in]), %[tmp2], %[tmp2]\n\t"
    4743                 "vmovdqu        %[tmp1], (%[out])\n\t"
    4744                 "vmovdqu        %[tmp2], 16(%[out])\n\t"
    4745                 "vaesenclast    %%xmm12, %[tmp3], %[tmp3]\n\t"
    4746                 "vaesenclast    %%xmm12, %[tmp4], %[tmp4]\n\t"
    4747                 "vpxor          32(%[in]), %[tmp3], %[tmp3]\n\t"
    4748                 "vpxor          48(%[in]), %[tmp4], %[tmp4]\n\t"
    4749                 "vmovdqu        %[tmp3], 32(%[out])\n\t"
    4750                 "vmovdqu        %[tmp4], 48(%[out])\n\t"
    4751                 "vaesenclast    %%xmm12, %[tmp5], %[tmp5]\n\t"
    4752                 "vaesenclast    %%xmm12, %[tmp6], %[tmp6]\n\t"
    4753                 "vpxor          64(%[in]), %[tmp5], %[tmp5]\n\t"
    4754                 "vpxor          80(%[in]), %[tmp6], %[tmp6]\n\t"
    4755                 "vmovdqu        %[tmp5], 64(%[out])\n\t"
    4756                 "vmovdqu        %[tmp6], 80(%[out])\n\t"
    4757                 "vaesenclast    %%xmm12, %[tmp7], %[tmp7]\n\t"
    4758                 "vaesenclast    %%xmm12, %[tmp8], %[tmp8]\n\t"
    4759                 "vpxor          96(%[in]), %[tmp7], %[tmp7]\n\t"
    4760                 "vpxor          112(%[in]), %[tmp8], %[tmp8]\n\t"
    4761                 "vmovdqu        %[tmp7], 96(%[out])\n\t"
    4762                 "vmovdqu        %[tmp8], 112(%[out])\n\t"
    4763 
    4764             : [tmp1] "=xr" (tmp1), [tmp2] "=xr" (tmp2), [tmp3] "=xr" (tmp3),
    4765               [tmp4] "=xr" (tmp4), [tmp5] "=xr" (tmp5), [tmp6] "=xr" (tmp6),
    4766               [tmp7] "=xr" (tmp7), [tmp8] "=xr" (tmp8),
    4767               [XV] "+xr" (XV)
    4768             : [KEY] "r" (KEY), [HT] "r" (HT), [pctr1] "r" (pctr1),
    4769               [in] "r" (&in[i*16*8]), [out] "r" (&out[i*16*8]), [nr] "r" (nr),
    4770               [BSWAP_MASK] "m" (BSWAP_MASK),
    4771               [BSWAP_EPI64] "m" (BSWAP_EPI64),
    4772               [ONE] "m" (ONE), [TWO] "m" (TWO),
    4773               [THREE] "m" (THREE), [FOUR] "m" (FOUR),
    4774               [FIVE] "m" (FIVE), [SIX] "m" (SIX),
    4775               [SEVEN] "m" (SEVEN), [EIGHT] "m" (EIGHT),
    4776               [MOD2_128] "m" (MOD2_128)
    4777             : "xmm15", "xmm14", "xmm13", "xmm12",
    4778               "xmm0", "xmm1", "xmm3", "memory"
    4779             );
    4780         }
    4781         X = XV;
    4782         ctr1 = pctr1[0];
    4783         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    4784         tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);
    4785         tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);
    4786         tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);
    4787         tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_MASK);
    4788         tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_MASK);
    4789         tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_MASK);
    4790         tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_MASK);
    4791         tmp1 = _mm_xor_si128(X, tmp1);
    4792         X = gfmul8(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8,
    4793                    HT[0], HT[1], HT[2], HT[3], HT[4], HT[5], HT[6], HT[7]);
    4794     }
    4795     for (k = i*8; k < (int)(nbytes/16); k++) {
    4796         __asm__ __volatile__ (
    4797             "vpshufb            %[BSWAP_EPI64], %[ctr1], %[tmp1]\n\t"
    4798             "vpaddd             %[ONE], %[ctr1], %[ctr1]\n\t"
    4799             "vpxor              (%[KEY]), %[tmp1], %[tmp1]\n\t"
    4800             "vaesenc            16(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4801             "vaesenc            32(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4802             "vaesenc            48(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4803             "vaesenc            64(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4804             "vaesenc            80(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4805             "vaesenc            96(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4806             "vaesenc            112(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4807             "vaesenc            128(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4808             "vaesenc            144(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4809             "cmpl               $11, %[nr]\n\t"
    4810             "vmovaps            160(%[KEY]), %[tmp2]\n\t"
    4811             "jl                 %=f\n\t"
    4812             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4813             "vaesenc            176(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4814             "cmpl               $13, %[nr]\n\t"
    4815             "vmovaps            192(%[KEY]), %[tmp2]\n\t"
    4816             "jl                 %=f\n\t"
    4817             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4818             "vaesenc            208(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4819             "vmovaps            224(%[KEY]), %[tmp2]\n\t"
    4820             "%=:\n\t"
    4821             "vaesenclast        %[tmp2], %[tmp1], %[tmp1]\n\t"
    4822             "vpxor              (%[in]), %[tmp1], %[tmp1]\n\t"
    4823             "vmovdqu            %[tmp1], (%[out])\n\t"
    4824             "vpshufb            %[BSWAP_MASK], %[tmp1], %[tmp1]\n\t"
    4825 
    4826             "vpxor              %[tmp1], %[X], %[X]\n\t"
    4827             "# Carryless Multiply X by H (128 x 128)\n\t"
    4828             "vpclmulqdq         $16, %[H], %[X], %%xmm13\n\t"
    4829             "vpclmulqdq         $1, %[H], %[X], %%xmm14\n\t"
    4830             "vpclmulqdq         $0, %[H], %[X], %%xmm15\n\t"
    4831             "vpclmulqdq         $17, %[H], %[X], %%xmm1\n\t"
    4832             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4833             "vpslldq            $8, %%xmm13, %%xmm2\n\t"
    4834             "vpsrldq            $8, %%xmm13, %%xmm13\n\t"
    4835             "vpxor              %%xmm15, %%xmm2, %%xmm2\n\t"
    4836             "vpxor              %%xmm13, %%xmm1, %%xmm3\n\t"
    4837             "# Reduce\n\t"
    4838             "vmovdqa            %[MOD2_128], %%xmm0\n\t"
    4839             "vpclmulqdq         $16, %%xmm0, %%xmm2, %%xmm14\n\t"
    4840             "vpshufd            $78, %%xmm2, %%xmm13\n\t"
    4841             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4842             "vpclmulqdq         $16, %%xmm0, %%xmm13, %%xmm14\n\t"
    4843             "vpshufd            $78, %%xmm13, %%xmm13\n\t"
    4844             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4845             "vpxor              %%xmm3, %%xmm13, %%xmm13\n\t"
    4846             "vmovdqa            %%xmm13, %[X]\n\t"
    4847             "# End Reduce\n\t"
    4848 
    4849         : [tmp1] "+xr" (tmp1), [tmp2] "=xr" (tmp2),
    4850           [H] "+xr" (H), [X] "+xr" (X), [ctr1] "+xr" (ctr1)
    4851         : [KEY] "r" (KEY),
    4852           [in] "r" (&in[k*16]), [out] "r" (&out[k*16]), [nr] "r" (nr),
    4853           [BSWAP_MASK] "m" (BSWAP_MASK),
    4854           [BSWAP_EPI64] "m" (BSWAP_EPI64),
    4855           [ONE] "m" (ONE),
    4856           [MOD2_128] "m" (MOD2_128)
    4857         : "xmm15", "xmm14", "xmm13",
    4858           "xmm0", "xmm1", "xmm2", "xmm3", "memory"
    4859         );
    4860     }
    4861 #else
    4862     for (k = 0; k < (int)(nbytes/16) && k < 1; k++) {
    4863         __asm__ __volatile__ (
    4864             "vpshufb            %[BSWAP_EPI64], %[ctr1], %[tmp1]\n\t"
    4865             "vpaddd             %[ONE], %[ctr1], %[ctr1]\n\t"
    4866             "vpxor              (%[KEY]), %[tmp1], %[tmp1]\n\t"
    4867             "vaesenc            16(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4868             "vaesenc            32(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4869             "vaesenc            48(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4870             "vaesenc            64(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4871             "vaesenc            80(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4872             "vaesenc            96(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4873             "vaesenc            112(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4874             "vaesenc            128(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4875             "vaesenc            144(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4876             "cmpl               $11, %[nr]\n\t"
    4877             "vmovaps            160(%[KEY]), %[tmp2]\n\t"
    4878             "jl                 %=f\n\t"
    4879             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4880             "vaesenc            176(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4881             "cmpl               $13, %[nr]\n\t"
    4882             "vmovaps            192(%[KEY]), %[tmp2]\n\t"
    4883             "jl                 %=f\n\t"
    4884             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4885             "vaesenc            208(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4886             "vmovaps            224(%[KEY]), %[tmp2]\n\t"
    4887             "%=:\n\t"
    4888             "vaesenclast        %[tmp2], %[tmp1], %[tmp1]\n\t"
    4889             "vpxor              (%[in]), %[tmp1], %[tmp1]\n\t"
    4890             "vmovdqu            %[tmp1], (%[out])\n\t"
    4891             "vpshufb            %[BSWAP_MASK], %[tmp1], %[tmp1]\n\t"
    4892             "vpxor              %[tmp1], %[X], %[X]\n\t"
    4893 
    4894         : [tmp1] "+xr" (tmp1), [tmp2] "=xr" (tmp2),
    4895           [H] "+xr" (H), [X] "+xr" (X), [ctr1] "+xr" (ctr1)
    4896         : [KEY] "r" (KEY),
    4897           [in] "r" (&in[k*16]), [out] "r" (&out[k*16]), [nr] "r" (nr),
    4898           [BSWAP_MASK] "m" (BSWAP_MASK),
    4899           [BSWAP_EPI64] "m" (BSWAP_EPI64),
    4900           [ONE] "m" (ONE),
    4901           [MOD2_128] "m" (MOD2_128)
    4902         : "memory"
    4903         );
    4904     }
    4905     for (; k < (int)(nbytes/16); k++) {
    4906         __asm__ __volatile__ (
    4907             "vpshufb            %[BSWAP_EPI64], %[ctr1], %[tmp1]\n\t"
    4908             "vpaddd             %[ONE], %[ctr1], %[ctr1]\n\t"
    4909             "vpxor              (%[KEY]), %[tmp1], %[tmp1]\n\t"
    4910             "vaesenc            16(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4911             "vpclmulqdq         $16, %[H], %[X], %%xmm13\n\t"
    4912             "vaesenc            32(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4913             "vpclmulqdq         $1, %[H], %[X], %%xmm14\n\t"
    4914             "vaesenc            48(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4915             "vpclmulqdq         $0, %[H], %[X], %%xmm15\n\t"
    4916             "vaesenc            64(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4917             "vpclmulqdq         $17, %[H], %[X], %%xmm1\n\t"
    4918             "vaesenc            80(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4919             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4920             "vpslldq            $8, %%xmm13, %%xmm2\n\t"
    4921             "vpsrldq            $8, %%xmm13, %%xmm13\n\t"
    4922             "vaesenc            96(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4923             "vpxor              %%xmm15, %%xmm2, %%xmm2\n\t"
    4924             "vpxor              %%xmm13, %%xmm1, %%xmm3\n\t"
    4925             "vmovdqa            %[MOD2_128], %%xmm0\n\t"
    4926             "vpclmulqdq         $16, %%xmm0, %%xmm2, %%xmm14\n\t"
    4927             "vaesenc            112(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4928             "vpshufd            $78, %%xmm2, %%xmm13\n\t"
    4929             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4930             "vpclmulqdq         $16, %%xmm0, %%xmm13, %%xmm14\n\t"
    4931             "vaesenc            128(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4932             "vpshufd            $78, %%xmm13, %%xmm13\n\t"
    4933             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    4934             "vpxor              %%xmm3, %%xmm13, %%xmm13\n\t"
    4935             "vaesenc            144(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4936             "vmovdqa            %%xmm13, %[X]\n\t"
    4937             "cmpl               $11, %[nr]\n\t"
    4938             "vmovaps            160(%[KEY]), %[tmp2]\n\t"
    4939             "jl                 %=f\n\t"
    4940             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4941             "vaesenc            176(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4942             "cmpl               $13, %[nr]\n\t"
    4943             "vmovaps            192(%[KEY]), %[tmp2]\n\t"
    4944             "jl                 %=f\n\t"
    4945             "vaesenc            %[tmp2], %[tmp1], %[tmp1]\n\t"
    4946             "vaesenc            208(%[KEY]), %[tmp1], %[tmp1]\n\t"
    4947             "vmovaps            224(%[KEY]), %[tmp2]\n\t"
    4948             "%=:\n\t"
    4949             "vaesenclast        %[tmp2], %[tmp1], %[tmp1]\n\t"
    4950             "vpxor              (%[in]), %[tmp1], %[tmp1]\n\t"
    4951             "vmovdqu            %[tmp1], (%[out])\n\t"
    4952             "vpshufb            %[BSWAP_MASK], %[tmp1], %[tmp1]\n\t"
    4953             "vpxor              %[tmp1], %[X], %[X]\n\t"
    4954 
    4955         : [tmp1] "+xr" (tmp1), [tmp2] "=xr" (tmp2),
    4956           [H] "+xr" (H), [X] "+xr" (X), [ctr1] "+xr" (ctr1)
    4957         : [KEY] "r" (KEY),
    4958           [in] "r" (&in[k*16]), [out] "r" (&out[k*16]), [nr] "r" (nr),
    4959           [BSWAP_MASK] "m" (BSWAP_MASK),
    4960           [BSWAP_EPI64] "m" (BSWAP_EPI64),
    4961           [ONE] "m" (ONE),
    4962           [MOD2_128] "m" (MOD2_128)
    4963         : "xmm15", "xmm14", "xmm13",
    4964           "xmm0", "xmm1", "xmm2", "xmm3", "memory"
    4965         );
    4966     }
    4967     if (k > 0) {
    4968         X = gfmul_shifted(X, H);
    4969     }
    4970 #endif
    4971     /* If one partial block remains */
    4972     if (nbytes % 16) {
    4973         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
    4974         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
    4975         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    4976         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    4977         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    4978         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    4979         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    4980         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    4981         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    4982         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    4983         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    4984         lastKey = KEY[10];
    4985         if (nr > 10) {
    4986             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4987             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    4988             lastKey = KEY[12];
    4989             if (nr > 12) {
    4990                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    4991                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    4992                 lastKey = KEY[14];
    4993             }
    4994         }
    4995         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
    4996         last_block = tmp1;
    4997         for (j=0; j < (int)(nbytes%16); j++)
    4998             ((unsigned char*)&last_block)[j] = in[k*16+j];
    4999         tmp1 = _mm_xor_si128(tmp1, last_block);
    5000         last_block = tmp1;
    5001         for (j=0; j < (int)(nbytes%16); j++)
    5002             out[k*16+j] = ((unsigned char*)&last_block)[j];
    5003         tmp1 = last_block;
    5004         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5005         X =_mm_xor_si128(X, tmp1);
    5006         X = gfmul_shifted(X, H);
    5007     }
    5008     tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
    5009     tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
    5010     X = _mm_xor_si128(X, tmp1);
    5011     X = gfmul_shifted(X, H);
    5012     X = _mm_shuffle_epi8(X, BSWAP_MASK);
    5013     T = _mm_xor_si128(X, T);
    5014     _mm_storeu_si128((__m128i*)tag, T);
    5015 }
    5016 #endif /* HAVE_INTEL_AVX2 */
     7297    /*_mm_storeu_si128((__m128i*)tag, T);*/
     7298    XMEMCPY(tag, &T, tbytes);
     7299    }
    50177300
    50187301#ifdef HAVE_AES_DECRYPT
    5019 /* Figure 10. AES-GCM – Decrypt With Single Block Ghash at a Time */
    5020 
    5021 static int AES_GCM_decrypt(const unsigned char *in, unsigned char *out,
    5022                            const unsigned char* addt, const unsigned char* ivec,
     7302
     7303static void AES_GCM_decrypt(const unsigned char *in,
     7304                           unsigned char *out,
     7305                           const unsigned char* addt,
     7306                           const unsigned char* ivec,
    50237307                           const unsigned char *tag, int nbytes, int abytes,
    5024                            int ibytes, const unsigned char* key, int nr)
     7308                           int ibytes, word32 tbytes, const unsigned char* key,
     7309                           int nr, int* res)
    50257310{
    50267311    int i, j ,k;
     
    50357320    __m128i r0, r1;
    50367321    __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
    5037 #endif
    5038 
    5039     if (ibytes == 12) {
    5040         Y = _mm_setzero_si128();
    5041         for (j=0; j < 12; j++)
    5042             ((unsigned char*)&Y)[j] = ivec[j];
    5043         Y = _mm_insert_epi32(Y, 0x1000000, 3);
    5044             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
    5045         tmp1 = _mm_xor_si128(X, KEY[0]);
    5046         tmp2 = _mm_xor_si128(Y, KEY[0]);
    5047         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5048         tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
    5049         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5050         tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
    5051         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5052         tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
    5053         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5054         tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
    5055         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5056         tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
    5057         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5058         tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
    5059         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5060         tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
    5061         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5062         tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
    5063         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5064         tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
    5065         lastKey = KEY[10];
    5066         if (nr > 10) {
    5067             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5068             tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    5069             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5070             tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
    5071             lastKey = KEY[12];
    5072             if (nr > 12) {
    5073                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5074                 tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    5075                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5076                 tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
    5077                 lastKey = KEY[14];
    5078             }
    5079         }
    5080         H = _mm_aesenclast_si128(tmp1, lastKey);
    5081         T = _mm_aesenclast_si128(tmp2, lastKey);
    5082         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    5083     }
    5084     else {
    5085         if (ibytes % 16) {
    5086             i = ibytes / 16;
    5087             for (j=0; j < ibytes%16; j++)
    5088                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
    5089         }
    5090         tmp1 = _mm_xor_si128(X, KEY[0]);
    5091         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5092         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5093         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5094         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5095         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5096         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5097         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5098         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5099         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5100         lastKey = KEY[10];
    5101         if (nr > 10) {
    5102             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5103             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5104             lastKey = KEY[12];
    5105             if (nr > 12) {
    5106                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5107                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5108                 lastKey = KEY[14];
    5109             }
    5110         }
    5111         H = _mm_aesenclast_si128(tmp1, lastKey);
    5112         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    5113 
    5114         Y = _mm_setzero_si128();
    5115         for (i=0; i < ibytes/16; i++) {
    5116             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
    5117             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5118             Y = _mm_xor_si128(Y, tmp1);
    5119             Y = gfmul_sw(Y, H);
    5120         }
    5121         if (ibytes % 16) {
    5122             tmp1 = last_block;
    5123             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5124             Y = _mm_xor_si128(Y, tmp1);
    5125             Y = gfmul_sw(Y, H);
    5126         }
    5127         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
    5128         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
    5129         Y = _mm_xor_si128(Y, tmp1);
    5130         Y = gfmul_sw(Y, H);
    5131         Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */
    5132         tmp1 = _mm_xor_si128(Y, KEY[0]);
    5133         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5134         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5135         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5136         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5137         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5138         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5139         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5140         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5141         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5142         lastKey = KEY[10];
    5143         if (nr > 10) {
    5144             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5145             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5146             lastKey = KEY[12];
    5147             if (nr > 12) {
    5148                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5149                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5150                 lastKey = KEY[14];
    5151             }
    5152         }
    5153         T = _mm_aesenclast_si128(tmp1, lastKey);
    5154     }
     7322#endif /* AES_GCM_AESNI_NO_UNROLL */
     7323
     7324    if (ibytes == 12)
     7325        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);
     7326    else
     7327        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);
    51557328
    51567329    for (i=0; i<abytes/16; i++) {
     
    53597532                    tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);
    53607533                    lastKey = KEY[14];
    5361                 }
    5362             }
    5363             tmp1 =_mm_aesenclast_si128(tmp1, lastKey);
    5364             tmp2 =_mm_aesenclast_si128(tmp2, lastKey);
    5365             tmp3 =_mm_aesenclast_si128(tmp3, lastKey);
    5366             tmp4 =_mm_aesenclast_si128(tmp4, lastKey);
    5367             tmp5 =_mm_aesenclast_si128(tmp5, lastKey);
    5368             tmp6 =_mm_aesenclast_si128(tmp6, lastKey);
    5369             tmp7 =_mm_aesenclast_si128(tmp7, lastKey);
    5370             tmp8 =_mm_aesenclast_si128(tmp8, lastKey);
    5371             tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));
    5372             tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));
    5373             tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));
    5374             tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));
    5375             tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));
    5376             tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));
    5377             tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));
    5378             tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));
    5379             _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);
    5380             _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);
    5381             _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);
    5382             _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);
    5383             _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);
    5384             _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);
    5385             _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);
    5386             _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);
    5387         }
    5388     }
    5389 #endif
     7534        }
     7535    }
     7536            AES_ENC_LAST_8();
     7537        }
     7538    }
     7539
     7540#endif /* AES_GCM_AESNI_NO_UNROLL */
     7541
    53907542    for (k = i*8; k < nbytes/16; k++) {
    53917543        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
     
    54697621    T = _mm_xor_si128(X, T);
    54707622
    5471     if (0xffff !=
    5472            _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag))))
    5473         return 0; /* in case the authentication failed */
    5474 
    5475     return 1; /* when successful returns 1 */
     7623/*    if (0xffff !=
     7624           _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag)))) */
     7625    if (XMEMCMP(tag, &T, tbytes) != 0)
     7626        *res = 0; /* in case the authentication failed */
     7627    else
     7628        *res = 1; /* when successful returns 1 */
    54767629}
    54777630
    5478 #ifdef HAVE_INTEL_AVX2
    5479 static int AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
    5480                                 const unsigned char* addt,
    5481                                 const unsigned char* ivec,
    5482                                 const unsigned char *tag, int nbytes,
    5483                                 int abytes, int ibytes,
    5484                                 const unsigned char* key, int nr)
    5485 {
    5486     int i, j ,k;
    5487     __m128i H, Y, T;
    5488     __m128i *KEY = (__m128i*)key, lastKey;
    5489     __m128i ctr1;
    5490     __m128i last_block = _mm_setzero_si128();
    5491     __m128i X = _mm_setzero_si128();
    5492     __m128i tmp1, tmp2;
    5493 #if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
    5494     __m128i HT[8];
    5495     __m128i pctr1[1];
    5496     register __m128i XV asm("xmm2");
    5497 #else
    5498     __m128i XV;
    5499 #endif
    5500 
    5501     if (ibytes == 12) {
    5502         Y = _mm_setzero_si128();
    5503         for (j=0; j < 12; j++)
    5504             ((unsigned char*)&Y)[j] = ivec[j];
    5505         Y = _mm_insert_epi32(Y, 0x1000000, 3);
    5506             /* (Compute E[ZERO, KS] and E[Y0, KS] together */
    5507         tmp1 = _mm_xor_si128(X, KEY[0]);
    5508         tmp2 = _mm_xor_si128(Y, KEY[0]);
    5509         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5510         tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);
    5511         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5512         tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);
    5513         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5514         tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);
    5515         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5516         tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);
    5517         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5518         tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);
    5519         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5520         tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);
    5521         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5522         tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);
    5523         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5524         tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);
    5525         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5526         tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);
    5527         lastKey = KEY[10];
    5528         if (nr > 10) {
    5529             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5530             tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    5531             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5532             tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);
    5533             lastKey = KEY[12];
    5534             if (nr > 12) {
    5535                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5536                 tmp2 = _mm_aesenc_si128(tmp2, lastKey);
    5537                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5538                 tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);
    5539                 lastKey = KEY[14];
    5540             }
    5541         }
    5542         H = _mm_aesenclast_si128(tmp1, lastKey);
    5543         T = _mm_aesenclast_si128(tmp2, lastKey);
    5544         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    5545     }
    5546     else {
    5547         if (ibytes % 16) {
    5548             i = ibytes / 16;
    5549             for (j=0; j < ibytes%16; j++)
    5550                 ((unsigned char*)&last_block)[j] = ivec[i*16+j];
    5551         }
    5552         tmp1 = _mm_xor_si128(X, KEY[0]);
    5553         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5554         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5555         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5556         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5557         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5558         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5559         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5560         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5561         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5562         lastKey = KEY[10];
    5563         if (nr > 10) {
    5564             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5565             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5566             lastKey = KEY[12];
    5567             if (nr > 12) {
    5568                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5569                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5570                 lastKey = KEY[14];
    5571             }
    5572         }
    5573         H = _mm_aesenclast_si128(tmp1, lastKey);
    5574         H = _mm_shuffle_epi8(H, BSWAP_MASK);
    5575 
    5576         Y = _mm_setzero_si128();
    5577         for (i=0; i < ibytes/16; i++) {
    5578             tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);
    5579             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5580             Y = _mm_xor_si128(Y, tmp1);
    5581             Y = gfmul_sw(Y, H);
    5582         }
    5583         if (ibytes % 16) {
    5584             tmp1 = last_block;
    5585             tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5586             Y = _mm_xor_si128(Y, tmp1);
    5587             Y = gfmul_sw(Y, H);
    5588         }
    5589         tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);
    5590         tmp1 = _mm_insert_epi64(tmp1, 0, 1);
    5591         Y = _mm_xor_si128(Y, tmp1);
    5592         Y = gfmul_sw(Y, H);
    5593         Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */
    5594         tmp1 = _mm_xor_si128(Y, KEY[0]);
    5595         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    5596         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    5597         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    5598         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    5599         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    5600         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    5601         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    5602         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    5603         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    5604         lastKey = KEY[10];
    5605         if (nr > 10) {
    5606             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5607             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    5608             lastKey = KEY[12];
    5609             if (nr > 12) {
    5610                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    5611                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    5612                 lastKey = KEY[14];
    5613             }
    5614         }
    5615         T = _mm_aesenclast_si128(tmp1, lastKey);
    5616     }
    5617 
    5618     for (i=0; i<abytes/16; i++) {
    5619         tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);
    5620         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5621         X = _mm_xor_si128(X, tmp1);
    5622         X = gfmul_sw(X, H);
    5623     }
    5624     if (abytes%16) {
    5625         last_block = _mm_setzero_si128();
    5626         for (j=0; j<abytes%16; j++)
    5627             ((unsigned char*)&last_block)[j] = addt[i*16+j];
    5628         tmp1 = last_block;
    5629         tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);
    5630         X = _mm_xor_si128(X, tmp1);
    5631         X = gfmul_sw(X, H);
    5632     }
    5633 
    5634     tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);
    5635     ctr1 = _mm_add_epi32(tmp1, ONE);
    5636     H = gfmul_shl1(H);
    5637     i = 0;
    5638 
    5639 #if !defined(AES_GCM_AESNI_NO_UNROLL) && !defined(AES_GCM_AVX2_NO_UNROLL)
    5640 
    5641     if (0 < nbytes/16/8) {
    5642         HT[0] = H;
    5643         HT[1] = gfmul_shifted(H, H);
    5644         HT[2] = gfmul_shifted(H, HT[1]);
    5645         HT[3] = gfmul_shifted(HT[1], HT[1]);
    5646         HT[4] = gfmul_shifted(HT[1], HT[2]);
    5647         HT[5] = gfmul_shifted(HT[2], HT[2]);
    5648         HT[6] = gfmul_shifted(HT[2], HT[3]);
    5649         HT[7] = gfmul_shifted(HT[3], HT[3]);
    5650 
    5651         pctr1[0] = ctr1;
    5652         XV = X;
    5653         for (; i < nbytes/16/8; i++) {
    5654             __asm__ __volatile__ (
    5655                 "vmovaps        (%[pctr1]), %%xmm0\n\t"
    5656                 "vmovaps        %[BSWAP_EPI64], %%xmm1\n\t"
    5657                 "vpshufb        %%xmm1, %%xmm0, %%xmm4\n\t"
    5658                 "vpaddd         %[ONE], %%xmm0, %%xmm5\n\t"
    5659                 "vpshufb        %%xmm1, %%xmm5, %%xmm5\n\t"
    5660                 "vpaddd         %[TWO], %%xmm0, %%xmm6\n\t"
    5661                 "vpshufb        %%xmm1, %%xmm6, %%xmm6\n\t"
    5662                 "vpaddd         %[THREE], %%xmm0, %%xmm7\n\t"
    5663                 "vpshufb        %%xmm1, %%xmm7, %%xmm7\n\t"
    5664                 "vpaddd         %[FOUR], %%xmm0, %%xmm8\n\t"
    5665                 "vpshufb        %%xmm1, %%xmm8, %%xmm8\n\t"
    5666                 "vpaddd         %[FIVE], %%xmm0, %%xmm9\n\t"
    5667                 "vpshufb        %%xmm1, %%xmm9, %%xmm9\n\t"
    5668                 "vpaddd         %[SIX], %%xmm0, %%xmm10\n\t"
    5669                 "vpshufb        %%xmm1, %%xmm10, %%xmm10\n\t"
    5670                 "vpaddd         %[SEVEN], %%xmm0, %%xmm11\n\t"
    5671                 "vpshufb        %%xmm1, %%xmm11, %%xmm11\n\t"
    5672                 "vpaddd         %[EIGHT], %%xmm0, %%xmm0\n\t"
    5673 
    5674                 "vmovaps        (%[KEY]), %%xmm1\n\t"
    5675                 "vmovaps        %%xmm0, (%[pctr1])\n\t"
    5676                 "vpxor          %%xmm1, %%xmm4, %%xmm4\n\t"
    5677                 "vpxor          %%xmm1, %%xmm5, %%xmm5\n\t"
    5678                 "vpxor          %%xmm1, %%xmm6, %%xmm6\n\t"
    5679                 "vpxor          %%xmm1, %%xmm7, %%xmm7\n\t"
    5680                 "vpxor          %%xmm1, %%xmm8, %%xmm8\n\t"
    5681                 "vpxor          %%xmm1, %%xmm9, %%xmm9\n\t"
    5682                 "vpxor          %%xmm1, %%xmm10, %%xmm10\n\t"
    5683                 "vpxor          %%xmm1, %%xmm11, %%xmm11\n\t"
    5684 
    5685                 "vmovaps        16(%[KEY]), %%xmm12\n\t"
    5686                 "vmovdqu        (%[in]), %%xmm1\n\t"
    5687                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5688                 "vmovaps        112(%[HT]), %%xmm0\n\t"
    5689                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5690                 "vpxor          %[XV], %%xmm1, %%xmm1\n\t"
    5691                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5692                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5693                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5694                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5695                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5696                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5697                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5698                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5699                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5700                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5701                 "vpslldq        $8, %%xmm13, %%xmm2\n\t"
    5702                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5703                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5704                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5705                 "vpxor          %%xmm13, %%xmm1, %%xmm3\n\t"
    5706                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5707 
    5708                 "vmovaps        32(%[KEY]), %%xmm12\n\t"
    5709                 "vmovdqu        16(%[in]), %%xmm1\n\t"
    5710                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5711                 "vmovaps        96(%[HT]), %%xmm0\n\t"
    5712                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5713                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5714                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5715                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5716                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5717                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5718                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5719                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5720                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5721                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5722                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5723                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5724                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5725                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5726                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5727                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5728                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5729                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5730                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5731 
    5732                 "vmovaps        48(%[KEY]), %%xmm12\n\t"
    5733                 "vmovdqu        32(%[in]), %%xmm1\n\t"
    5734                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5735                 "vmovaps        80(%[HT]), %%xmm0\n\t"
    5736                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5737                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5738                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5739                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5740                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5741                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5742                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5743                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5744                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5745                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5746                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5747                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5748                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5749                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5750                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5751                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5752                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5753                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5754                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5755 
    5756                 "vmovaps        64(%[KEY]), %%xmm12\n\t"
    5757                 "vmovdqu        48(%[in]), %%xmm1\n\t"
    5758                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5759                 "vmovaps        64(%[HT]), %%xmm0\n\t"
    5760                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5761                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5762                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5763                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5764                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5765                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5766                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5767                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5768                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5769                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5770                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5771                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5772                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5773                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5774                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5775                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5776                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5777                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5778                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5779 
    5780                 "vmovaps        80(%[KEY]), %%xmm12\n\t"
    5781                 "vmovdqu        64(%[in]), %%xmm1\n\t"
    5782                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5783                 "vmovaps        48(%[HT]), %%xmm0\n\t"
    5784                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5785                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5786                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5787                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5788                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5789                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5790                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5791                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5792                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5793                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5794                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5795                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5796                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5797                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5798                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5799                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5800                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5801                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5802                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5803 
    5804                 "vmovaps        96(%[KEY]), %%xmm12\n\t"
    5805                 "vmovdqu        80(%[in]), %%xmm1\n\t"
    5806                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5807                 "vmovaps        32(%[HT]), %%xmm0\n\t"
    5808                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5809                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5810                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5811                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5812                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5813                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5814                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5815                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5816                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5817                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5818                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5819                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5820                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5821                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5822                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5823                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5824                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5825                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5826                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5827 
    5828                 "vmovaps        112(%[KEY]), %%xmm12\n\t"
    5829                 "vmovdqu        96(%[in]), %%xmm1\n\t"
    5830                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5831                 "vmovaps        16(%[HT]), %%xmm0\n\t"
    5832                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5833                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5834                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5835                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5836                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5837                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5838                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5839                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5840                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5841                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5842                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5843                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5844                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5845                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5846                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5847                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5848                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5849                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5850                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5851 
    5852                 "vmovaps        128(%[KEY]), %%xmm12\n\t"
    5853                 "vmovdqu        112(%[in]), %%xmm1\n\t"
    5854                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5855                 "vmovaps        (%[HT]), %%xmm0\n\t"
    5856                 "vpshufb        %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5857                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5858                 "vpclmulqdq     $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5859                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5860                 "vpclmulqdq     $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5861                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5862                 "vpclmulqdq     $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    5863                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5864                 "vpclmulqdq     $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    5865                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5866                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5867                 "vpslldq        $8, %%xmm13, %%xmm14\n\t"
    5868                 "vpsrldq        $8, %%xmm13, %%xmm13\n\t"
    5869                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5870                 "vpxor          %%xmm15, %%xmm2, %%xmm2\n\t"
    5871                 "vpxor          %%xmm1, %%xmm3, %%xmm3\n\t"
    5872                 "vpxor          %%xmm14, %%xmm2, %%xmm2\n\t"
    5873                 "vpxor          %%xmm13, %%xmm3, %%xmm3\n\t"
    5874                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5875 
    5876                 "vmovaps        144(%[KEY]), %%xmm12\n\t"
    5877                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5878                 "vmovdqa        %[MOD2_128], %%xmm0\n\t"
    5879                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5880                 "vpclmulqdq     $16, %%xmm0, %%xmm2, %%xmm14\n\t"
    5881                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5882                 "vpshufd        $78, %%xmm2, %%xmm13\n\t"
    5883                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5884                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5885                 "vpclmulqdq     $16, %%xmm0, %%xmm13, %%xmm14\n\t"
    5886                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5887                 "vpshufd        $78, %%xmm13, %%xmm13\n\t"
    5888                 "vpxor          %%xmm14, %%xmm13, %%xmm13\n\t"
    5889                 "vpxor          %%xmm3, %%xmm13, %%xmm13\n\t"
    5890                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5891                 "vmovdqa        %%xmm13, %%xmm2\n\t"
    5892                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5893                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5894                 "cmpl           $11, %[nr]\n\t"
    5895                 "vmovaps        160(%[KEY]), %%xmm12\n\t"
    5896                 "jl             %=f\n\t"
    5897 
    5898                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5899                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5900                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5901                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5902                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5903                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5904                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5905                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5906                 "vmovaps        176(%[KEY]), %%xmm12\n\t"
    5907                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5908                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5909                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5910                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5911                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5912                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5913                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5914                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5915                 "cmpl           $13, %[nr]\n\t"
    5916                 "vmovaps        192(%[KEY]), %%xmm12\n\t"
    5917                 "jl             %=f\n\t"
    5918 
    5919                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5920                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5921                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5922                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5923                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5924                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5925                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5926                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5927                 "vmovaps        208(%[KEY]), %%xmm12\n\t"
    5928                 "vaesenc        %%xmm12, %%xmm4, %%xmm4\n\t"
    5929                 "vaesenc        %%xmm12, %%xmm5, %%xmm5\n\t"
    5930                 "vaesenc        %%xmm12, %%xmm6, %%xmm6\n\t"
    5931                 "vaesenc        %%xmm12, %%xmm7, %%xmm7\n\t"
    5932                 "vaesenc        %%xmm12, %%xmm8, %%xmm8\n\t"
    5933                 "vaesenc        %%xmm12, %%xmm9, %%xmm9\n\t"
    5934                 "vaesenc        %%xmm12, %%xmm10, %%xmm10\n\t"
    5935                 "vaesenc        %%xmm12, %%xmm11, %%xmm11\n\t"
    5936                 "vmovaps        224(%[KEY]), %%xmm12\n\t"
    5937 
    5938                 "%=:\n\t"
    5939                 "vaesenclast    %%xmm12, %%xmm4, %%xmm4\n\t"
    5940                 "vaesenclast    %%xmm12, %%xmm5, %%xmm5\n\t"
    5941                 "vpxor          (%[in]), %%xmm4, %%xmm4\n\t"
    5942                 "vpxor          16(%[in]), %%xmm5, %%xmm5\n\t"
    5943                 "vmovdqu        %%xmm4, (%[out])\n\t"
    5944                 "vmovdqu        %%xmm5, 16(%[out])\n\t"
    5945                 "vaesenclast    %%xmm12, %%xmm6, %%xmm6\n\t"
    5946                 "vaesenclast    %%xmm12, %%xmm7, %%xmm7\n\t"
    5947                 "vpxor          32(%[in]), %%xmm6, %%xmm6\n\t"
    5948                 "vpxor          48(%[in]), %%xmm7, %%xmm7\n\t"
    5949                 "vmovdqu        %%xmm6, 32(%[out])\n\t"
    5950                 "vmovdqu        %%xmm7, 48(%[out])\n\t"
    5951                 "vaesenclast    %%xmm12, %%xmm8, %%xmm8\n\t"
    5952                 "vaesenclast    %%xmm12, %%xmm9, %%xmm9\n\t"
    5953                 "vpxor          64(%[in]), %%xmm8, %%xmm8\n\t"
    5954                 "vpxor          80(%[in]), %%xmm9, %%xmm9\n\t"
    5955                 "vmovdqu        %%xmm8, 64(%[out])\n\t"
    5956                 "vmovdqu        %%xmm9, 80(%[out])\n\t"
    5957                 "vaesenclast    %%xmm12, %%xmm10, %%xmm10\n\t"
    5958                 "vaesenclast    %%xmm12, %%xmm11, %%xmm11\n\t"
    5959                 "vpxor          96(%[in]), %%xmm10, %%xmm10\n\t"
    5960                 "vpxor          112(%[in]), %%xmm11, %%xmm11\n\t"
    5961                 "vmovdqu        %%xmm10, 96(%[out])\n\t"
    5962                 "vmovdqu        %%xmm11, 112(%[out])\n\t"
    5963 
    5964             : [XV] "+xr" (XV)
    5965             : [KEY] "r" (KEY), [HT] "r" (HT), [pctr1] "r" (pctr1),
    5966               [in] "r" (&in[i*16*8]), [out] "r" (&out[i*16*8]), [nr] "r" (nr),
    5967               [BSWAP_MASK] "m" (BSWAP_MASK),
    5968               [BSWAP_EPI64] "m" (BSWAP_EPI64),
    5969               [ONE] "m" (ONE), [TWO] "m" (TWO),
    5970               [THREE] "m" (THREE), [FOUR] "m" (FOUR),
    5971               [FIVE] "m" (FIVE), [SIX] "m" (SIX),
    5972               [SEVEN] "m" (SEVEN), [EIGHT] "m" (EIGHT),
    5973               [MOD2_128] "m" (MOD2_128)
    5974             : "xmm15", "xmm14", "xmm13", "xmm12",
    5975               "xmm11", "xmm10", "xmm9", "xmm8",
    5976               "xmm7", "xmm6", "xmm5", "xmm4",
    5977               "xmm0", "xmm1", "xmm3", "memory"
    5978             );
    5979         }
    5980         X = XV;
    5981         ctr1 = pctr1[0];
    5982     }
    5983 #endif
    5984     for (k = i*8; k < nbytes/16; k++) {
    5985         __asm__ __volatile__ (
    5986             "vpshufb    %[BSWAP_EPI64], %[ctr1], %%xmm4\n\t"
    5987             "vpaddd             %[ONE], %[ctr1], %[ctr1]\n\t"
    5988             "vpxor              (%[KEY]), %%xmm4, %%xmm4\n\t"
    5989             "vaesenc    16(%[KEY]), %%xmm4, %%xmm4\n\t"
    5990             "vmovaps    %[H], %%xmm0\n\t"
    5991             "vmovdqu    (%[in]), %%xmm1\n\t"
    5992             "vaesenc    32(%[KEY]), %%xmm4, %%xmm4\n\t"
    5993             "vpshufb    %[BSWAP_MASK], %%xmm1, %%xmm1\n\t"
    5994             "vpxor              %[X], %%xmm1, %%xmm1\n\t"
    5995             "vaesenc    48(%[KEY]), %%xmm4, %%xmm4\n\t"
    5996             "vpclmulqdq $16, %%xmm1, %%xmm0, %%xmm13\n\t"
    5997             "vaesenc    64(%[KEY]), %%xmm4, %%xmm4\n\t"
    5998             "vpclmulqdq $1, %%xmm1, %%xmm0, %%xmm14\n\t"
    5999             "vaesenc    80(%[KEY]), %%xmm4, %%xmm4\n\t"
    6000             "vpclmulqdq $0, %%xmm1, %%xmm0, %%xmm15\n\t"
    6001             "vaesenc    96(%[KEY]), %%xmm4, %%xmm4\n\t"
    6002             "vpclmulqdq $17, %%xmm1, %%xmm0, %%xmm1\n\t"
    6003             "vaesenc    112(%[KEY]), %%xmm4, %%xmm4\n\t"
    6004             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    6005             "vpslldq    $8, %%xmm13, %%xmm2\n\t"
    6006             "vpsrldq    $8, %%xmm13, %%xmm13\n\t"
    6007             "vaesenc    128(%[KEY]), %%xmm4, %%xmm4\n\t"
    6008             "vpxor              %%xmm15, %%xmm2, %%xmm2\n\t"
    6009             "vpxor              %%xmm13, %%xmm1, %%xmm3\n\t"
    6010             "vaesenc    144(%[KEY]), %%xmm4, %%xmm4\n\t"
    6011             "# Reduce\n\t"
    6012             "vmovdqa    %[MOD2_128], %%xmm0\n\t"
    6013             "vpclmulqdq $16, %%xmm0, %%xmm2, %%xmm14\n\t"
    6014             "vpshufd    $78, %%xmm2, %%xmm13\n\t"
    6015             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    6016             "vpclmulqdq $16, %%xmm0, %%xmm13, %%xmm14\n\t"
    6017             "vpshufd    $78, %%xmm13, %%xmm13\n\t"
    6018             "vpxor              %%xmm14, %%xmm13, %%xmm13\n\t"
    6019             "vpxor              %%xmm3, %%xmm13, %%xmm13\n\t"
    6020             "vmovdqa    %%xmm13, %[X]\n\t"
    6021             "# End Reduce\n\t"
    6022             "cmpl               $11, %[nr]\n\t"
    6023             "vmovaps    160(%[KEY]), %%xmm5\n\t"
    6024             "jl             %=f\n\t"
    6025             "vaesenc    %%xmm5, %%xmm4, %%xmm4\n\t"
    6026             "vaesenc    176(%[KEY]), %%xmm4, %%xmm4\n\t"
    6027             "cmpl               $13, %[nr]\n\t"
    6028             "vmovaps    192(%[KEY]), %%xmm5\n\t"
    6029             "jl             %=f\n\t"
    6030             "vaesenc    %%xmm5, %%xmm4, %%xmm4\n\t"
    6031             "vaesenc    208(%[KEY]), %%xmm4, %%xmm4\n\t"
    6032             "vmovaps    224(%[KEY]), %%xmm5\n\t"
    6033             "%=:\n\t"
    6034             "vaesenclast        %%xmm5, %%xmm4, %%xmm4\n\t"
    6035             "vpxor              (%[in]), %%xmm4, %%xmm4\n\t"
    6036             "vmovdqu    %%xmm4, (%[out])\n\t"
    6037 
    6038         : [H] "+xr" (H), [X] "+xr" (X),
    6039           [ctr1] "+xr" (ctr1)
    6040         : [KEY] "r" (KEY),
    6041           [in] "r" (&in[k*16]), [out] "r" (&out[k*16]), [nr] "r" (nr),
    6042           [BSWAP_MASK] "m" (BSWAP_MASK),
    6043           [BSWAP_EPI64] "m" (BSWAP_EPI64),
    6044           [ONE] "m" (ONE),
    6045           [MOD2_128] "m" (MOD2_128)
    6046         : "xmm15", "xmm14", "xmm13", "xmm4", "xmm5",
    6047           "xmm0", "xmm1", "xmm2", "xmm3", "memory"
    6048         );
    6049     }
    6050 
    6051     /* If one partial block remains */
    6052     if (nbytes % 16) {
    6053         tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);
    6054         tmp1 = _mm_xor_si128(tmp1, KEY[0]);
    6055         tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);
    6056         tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);
    6057         tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);
    6058         tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);
    6059         tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);
    6060         tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);
    6061         tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);
    6062         tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);
    6063         tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);
    6064         lastKey = KEY[10];
    6065         if (nr > 10) {
    6066             tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    6067             tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);
    6068             lastKey = KEY[12];
    6069             if (nr > 12) {
    6070                 tmp1 = _mm_aesenc_si128(tmp1, lastKey);
    6071                 tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);
    6072                 lastKey = KEY[14];
    6073             }
    6074         }
    6075         tmp1 = _mm_aesenclast_si128(tmp1, lastKey);
    6076         last_block = _mm_setzero_si128();
    6077         for (j=0; j < nbytes%16; j++)
    6078             ((unsigned char*)&last_block)[j] = in[k*16+j];
    6079         XV = last_block;
    6080         tmp1 = _mm_xor_si128(tmp1, last_block);
    6081         last_block = tmp1;
    6082         for (j=0; j < nbytes%16; j++)
    6083             out[k*16+j] = ((unsigned char*)&last_block)[j];
    6084         XV = _mm_shuffle_epi8(XV, BSWAP_MASK);
    6085         XV = _mm_xor_si128(XV, X);
    6086         X = gfmul_shifted(XV, H);
    6087     }
    6088 
    6089     tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);
    6090     tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);
    6091     /* 128 x 128 Carryless Multiply */
    6092     X = _mm_xor_si128(X, tmp1);
    6093     X = gfmul_shifted(X, H);
    6094     X = _mm_shuffle_epi8(X, BSWAP_MASK);
    6095     T = _mm_xor_si128(X, T);
    6096 
    6097     if (0xffff !=
    6098            _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag))))
    6099         return 0; /* in case the authentication failed */
    6100 
    6101     return 1; /* when successful returns 1 */
    6102 }
    6103 #endif /* HAVE_INTEL_AVX2 */
    61047631#endif /* HAVE_AES_DECRYPT */
     7632#endif /* _MSC_VER */
    61057633#endif /* WOLFSSL_AESNI */
    61067634
     
    64838011                Z[2] ^= V[2];
    64848012                Z[3] ^= V[3];
    6485             }
     8013        }
    64868014
    64878015            if (V[3] & 0x00000001) {
     
    65028030                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
    65038031                V[0] >>= 1;
    6504             }
     8032    }
    65058033            y <<= 1;
    65068034        }
     
    66138141
    66148142#if !defined(WOLFSSL_XILINX_CRYPT)
     8143#ifdef FREESCALE_LTC_AES_GCM
    66158144int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
    66168145                   const byte* iv, word32 ivSz,
    66178146                   byte* authTag, word32 authTagSz,
    66188147                   const byte* authIn, word32 authInSz)
     8148    {
     8149    status_t status;
     8150    word32 keySize;
     8151
     8152    /* argument checks */
     8153    if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {
     8154        return BAD_FUNC_ARG;
     8155    }
     8156
     8157    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
     8158        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
     8159        return BAD_FUNC_ARG;
     8160    }
     8161
     8162    status = wc_AesGetKeySize(aes, &keySize);
     8163    if (status)
     8164        return status;
     8165
     8166    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
     8167        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
     8168
     8169    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
     8170}
     8171#else
     8172#if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || \
     8173                              defined(WOLFSSL_STM32F7) || \
     8174                              defined(WOLFSSL_STM32L4))
     8175
     8176static WC_INLINE int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in,
     8177                                         word32 sz, const byte* iv, word32 ivSz,
     8178                                         byte* authTag, word32 authTagSz,
     8179                                         const byte* authIn, word32 authInSz)
     8180        {
     8181    int ret;
     8182#ifdef WOLFSSL_STM32_CUBEMX
     8183    CRYP_HandleTypeDef hcryp;
     8184#else
     8185    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
     8186#endif
     8187    word32 keySize;
     8188    int status = 0;
     8189    int outPadSz, authPadSz;
     8190    word32 tag[AES_BLOCK_SIZE/sizeof(word32)];
     8191    word32 initialCounter[AES_BLOCK_SIZE/sizeof(word32)];
     8192    byte* outPadded = NULL;
     8193    byte* authInPadded = NULL;
     8194
     8195    ret = wc_AesGetKeySize(aes, &keySize);
     8196    if (ret != 0)
     8197        return ret;
     8198
     8199#ifdef WOLFSSL_STM32_CUBEMX
     8200    ret = wc_Stm32_Aes_Init(aes, &hcryp);
     8201    if (ret != 0)
     8202        return ret;
     8203#endif
     8204
     8205    XMEMSET(initialCounter, 0, sizeof(initialCounter));
     8206    XMEMCPY(initialCounter, iv, ivSz);
     8207    *((byte*)initialCounter + (AES_BLOCK_SIZE - 1)) = STM32_GCM_IV_START;
     8208
     8209    /* Need to pad the AAD and input cipher text to a full block size since
     8210     * CRYP_AES_GCM will assume these are a multiple of AES_BLOCK_SIZE.
     8211     * It is okay to pad with zeros because GCM does this before GHASH already.
     8212     * See NIST SP 800-38D */
     8213    if ((sz % AES_BLOCK_SIZE) != 0 || sz == 0) {
     8214        outPadSz = ((sz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
     8215        outPadded = (byte*)XMALLOC(outPadSz, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8216        if (outPadded == NULL) {
     8217            return MEMORY_E;
     8218        }
     8219        XMEMSET(outPadded, 0, outPadSz);
     8220    }
     8221    else {
     8222        outPadSz = sz;
     8223        outPadded = out;
     8224    }
     8225    XMEMCPY(outPadded, in, sz);
     8226
     8227    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
     8228        /* Need to pad the AAD to a full block with zeros. */
     8229        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
     8230        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
     8231            DYNAMIC_TYPE_TMP_BUFFER);
     8232        if (authInPadded == NULL) {
     8233            if (outPadded != out) {
     8234                XFREE(outPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8235            }
     8236            return MEMORY_E;
     8237            }
     8238        XMEMSET(authInPadded, 0, authPadSz);
     8239        XMEMCPY(authInPadded, authIn, authInSz);
     8240    } else {
     8241        authPadSz = authInSz;
     8242        authInPadded = (byte*)authIn;
     8243    }
     8244
     8245
     8246#ifdef WOLFSSL_STM32_CUBEMX
     8247    hcryp.Init.pInitVect = (uint8_t*)initialCounter;
     8248    hcryp.Init.Header = authInPadded;
     8249    hcryp.Init.HeaderSize = authInSz;
     8250
     8251#ifdef STM32_CRYPTO_AES_ONLY
     8252    /* Set the CRYP parameters */
     8253    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
     8254    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
     8255    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
     8256    HAL_CRYP_Init(&hcryp);
     8257
     8258    /* GCM init phase */
     8259    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
     8260    if (status == HAL_OK) {
     8261        /* GCM header phase */
     8262        hcryp.Init.GCMCMACPhase  = CRYP_HEADER_PHASE;
     8263        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
     8264        if (status == HAL_OK) {
     8265            /* GCM payload phase */
     8266            hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;
     8267            status = HAL_CRYPEx_AES_Auth(&hcryp, outPadded, sz, outPadded,
     8268                STM32_HAL_TIMEOUT);
     8269            if (status == HAL_OK) {
     8270                /* GCM final phase */
     8271                hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
     8272                status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag,
     8273                    STM32_HAL_TIMEOUT);
     8274            }
     8275        }
     8276    }
     8277#else
     8278    HAL_CRYP_Init(&hcryp);
     8279
     8280    status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, outPadded, sz,
     8281                                       outPadded, STM32_HAL_TIMEOUT);
     8282    /* Compute the authTag */
     8283    if (status == HAL_OK) {
     8284        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag,
     8285            STM32_HAL_TIMEOUT);
     8286    }
     8287#endif
     8288
     8289    if (status != HAL_OK)
     8290        ret = AES_GCM_AUTH_E;
     8291    HAL_CRYP_DeInit(&hcryp);
     8292
     8293#else /* STD_PERI_LIB */
     8294    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
     8295    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)initialCounter,
     8296                         (uint8_t*)keyCopy,     keySize * 8,
     8297                         (uint8_t*)outPadded,   sz,
     8298                         (uint8_t*)authInPadded,authInSz,
     8299                         (uint8_t*)outPadded,   (byte*)tag);
     8300    if (status != SUCCESS)
     8301        ret = AES_GCM_AUTH_E;
     8302#endif /* WOLFSSL_STM32_CUBEMX */
     8303
     8304    if (ret == 0) {
     8305        /* return authTag */
     8306        XMEMCPY(authTag, tag, authTagSz);
     8307
     8308        /* return output if allocated padded used */
     8309        if (outPadded != out) {
     8310            XMEMCPY(out, outPadded, sz);
     8311            }
     8312        }
     8313
     8314    /* Free memory if not a multiple of AES_BLOCK_SZ */
     8315    if (outPadded != out) {
     8316        XFREE(outPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8317    }
     8318    if (authInPadded != authIn) {
     8319        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8320}
     8321
     8322    return ret;
     8323}
     8324#endif /* STM32_CRYPTO */
     8325
     8326#ifdef WOLFSSL_AESNI
     8327int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
     8328                      const byte* iv, word32 ivSz,
     8329                      byte* authTag, word32 authTagSz,
     8330                      const byte* authIn, word32 authInSz);
     8331#else
     8332static
     8333#endif
     8334int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
     8335                      const byte* iv, word32 ivSz,
     8336                      byte* authTag, word32 authTagSz,
     8337                      const byte* authIn, word32 authInSz)
    66198338{
    66208339    int ret = 0;
    6621     word32 keySize;
    6622 #ifdef FREESCALE_LTC_AES_GCM
    6623     status_t status;
    6624 #else
    66258340    word32 blocks = sz / AES_BLOCK_SIZE;
    66268341    word32 partial = sz % AES_BLOCK_SIZE;
     
    66318346    byte *ctr;
    66328347    byte scratch[AES_BLOCK_SIZE];
    6633 #if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || defined(WOLFSSL_STM32F7))
    6634     #ifdef WOLFSSL_STM32_CUBEMX
    6635         CRYP_HandleTypeDef hcryp;
    6636     #else
    6637         byte keyCopy[AES_BLOCK_SIZE * 2];
    6638     #endif /* WOLFSSL_STM32_CUBEMX */
    6639     int status = 0;
    6640     byte* authInPadded = NULL;
    6641     byte tag[AES_BLOCK_SIZE];
    6642     int authPadSz;
    6643 #endif /* STM32_CRYPTO */
    6644 #endif /* FREESCALE_LTC_AES_GCM */
    6645 
     8348
     8349    ctr = counter;
     8350    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
     8351    if (ivSz == GCM_NONCE_MID_SZ) {
     8352        XMEMCPY(initialCounter, iv, ivSz);
     8353        initialCounter[AES_BLOCK_SIZE - 1] = 1;
     8354    }
     8355    else {
     8356        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
     8357    }
     8358    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
     8359
     8360#ifdef WOLFSSL_PIC32MZ_CRYPT
     8361    if (blocks) {
     8362        /* use initial IV for PIC32 HW, but don't use it below */
     8363        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
     8364
     8365        ret = wc_Pic32AesCrypt(
     8366            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
     8367            out, in, (blocks * AES_BLOCK_SIZE),
     8368            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
     8369        if (ret != 0)
     8370            return ret;
     8371        }
     8372    /* process remainder using partial handling */
     8373            #endif
     8374
     8375#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
     8376    /* some hardware acceleration can gain performance from doing AES encryption
     8377     * of the whole buffer at once */
     8378    if (c != p) { /* can not handle inline encryption */
     8379        while (blocks--) {
     8380            IncrementGcmCounter(ctr);
     8381            XMEMCPY(c, ctr, AES_BLOCK_SIZE);
     8382            c += AES_BLOCK_SIZE;
     8383        }
     8384
     8385        /* reset number of blocks and then do encryption */
     8386        blocks = sz / AES_BLOCK_SIZE;
     8387        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
     8388        xorbuf(out, p, AES_BLOCK_SIZE * blocks);
     8389        p += AES_BLOCK_SIZE * blocks;
     8390    }
     8391    else
     8392#endif /* HAVE_AES_ECB */
     8393
     8394        while (blocks--) {
     8395        IncrementGcmCounter(ctr);
     8396    #ifndef WOLFSSL_PIC32MZ_CRYPT
     8397        wc_AesEncrypt(aes, ctr, scratch);
     8398        xorbuf(scratch, p, AES_BLOCK_SIZE);
     8399        XMEMCPY(c, scratch, AES_BLOCK_SIZE);
     8400            #endif
     8401        p += AES_BLOCK_SIZE;
     8402            c += AES_BLOCK_SIZE;
     8403        }
     8404
     8405        if (partial != 0) {
     8406        IncrementGcmCounter(ctr);
     8407        wc_AesEncrypt(aes, ctr, scratch);
     8408        xorbuf(scratch, p, partial);
     8409        XMEMCPY(c, scratch, partial);
     8410    }
     8411
     8412    GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
     8413    wc_AesEncrypt(aes, initialCounter, scratch);
     8414    xorbuf(authTag, scratch, authTagSz);
     8415
     8416    return ret;
     8417}
     8418
     8419/* Software AES - GCM Encrypt */
     8420int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
     8421                   const byte* iv, word32 ivSz,
     8422                   byte* authTag, word32 authTagSz,
     8423                   const byte* authIn, word32 authInSz)
     8424        {
    66468425    /* argument checks */
    66478426    if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {
    66488427        return BAD_FUNC_ARG;
    6649     }
     8428            }
    66508429
    66518430    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
    66528431        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
    66538432        return BAD_FUNC_ARG;
    6654     }
    6655 
    6656     ret = wc_AesGetKeySize(aes, &keySize);
    6657     if (ret != 0)
    6658         return ret;
    6659 
    6660 #ifdef FREESCALE_LTC_AES_GCM
    6661 
    6662     status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
    6663         authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
    6664 
    6665     ret = (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
    6666 
    6667 #else
    6668 
    6669 #if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || defined(WOLFSSL_STM32F7))
    6670 
    6671     /* additional argument checks - STM32 HW only supports 12 byte IV */
    6672     if (ivSz != NONCE_SZ) {
    6673         return BAD_FUNC_ARG;
    6674     }
    6675 
    6676     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
    6677     XMEMCPY(initialCounter, iv, ivSz);
    6678     initialCounter[AES_BLOCK_SIZE - 1] = STM32_GCM_IV_START;
    6679 
    6680     /* STM32 HW AES-GCM requires / assumes inputs are a multiple of block size.
    6681      * We can avoid this by zero padding (authIn) AAD, but zero-padded plaintext
    6682      * will be encrypted and output incorrectly, causing a bad authTag.
    6683      * We will use HW accelerated AES-GCM if plain%AES_BLOCK_SZ==0.
    6684      * Otherwise, we will use accelerated AES_CTR for encrypt, and then
    6685      * perform GHASH in software.
    6686      * See NIST SP 800-38D */
    6687 
    6688     /* Plain text is a multiple of block size, so use HW-Accelerated AES_GCM */
    6689     if (!partial) {
    6690         /* pad authIn if it is not a block multiple */
    6691         if ((authInSz % AES_BLOCK_SIZE) != 0) {
    6692             authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
    6693             /* Need to pad the AAD to a full block with zeros. */
    6694             authInPadded = XMALLOC(authPadSz, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    6695             if (authInPadded == NULL) {
    6696                 return MEMORY_E;
    6697             }
    6698             XMEMSET(authInPadded, 0, authPadSz);
    6699             XMEMCPY(authInPadded, authIn, authInSz);
    6700         } else {
    6701             authPadSz = authInSz;
    6702             authInPadded = (byte*)authIn;
    6703         }
    6704 
    6705 
    6706     #ifdef WOLFSSL_STM32_CUBEMX
    6707         XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    6708         switch (keySize) {
    6709             case 16: /* 128-bit key */
    6710                 hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    6711                 break;
    6712             case 24: /* 192-bit key */
    6713                 hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    6714                 break;
    6715             case 32: /* 256-bit key */
    6716                 hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    6717                 break;
    6718             default:
    6719                 break;
    6720         }
    6721         hcryp.Instance = CRYP;
    6722         hcryp.Init.DataType = CRYP_DATATYPE_8B;
    6723         hcryp.Init.pKey = (byte*)aes->key;
    6724         hcryp.Init.pInitVect = initialCounter;
    6725         hcryp.Init.Header = authInPadded;
    6726         hcryp.Init.HeaderSize = authInSz;
    6727 
    6728         HAL_CRYP_Init(&hcryp);
    6729         status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in, sz,
    6730                                         out, STM32_HAL_TIMEOUT);
    6731         /* Compute the authTag */
    6732         if (status == HAL_OK)
    6733             status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
    6734 
    6735         if (status != HAL_OK)
    6736             ret = AES_GCM_AUTH_E;
    6737         HAL_CRYP_DeInit(&hcryp);
    6738     #else
    6739         ByteReverseWords((word32*)keyCopy, (word32*)aes->key, keySize);
    6740         status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)initialCounter,
    6741                              (uint8_t*)keyCopy,     keySize * 8,
    6742                              (uint8_t*)in,          sz,
    6743                              (uint8_t*)authInPadded,authInSz,
    6744                              (uint8_t*)out,         tag);
    6745         if (status != SUCCESS)
    6746             ret = AES_GCM_AUTH_E;
    6747     #endif /* WOLFSSL_STM32_CUBEMX */
    6748 
    6749         /* authTag may be shorter than AES_BLOCK_SZ, store separately */
    6750         if (ret == 0)
    6751                 XMEMCPY(authTag, tag, authTagSz);
    6752 
    6753         /* We only allocate extra memory if authInPadded is not a multiple of AES_BLOCK_SZ */
    6754         if (authInPadded != NULL && authInSz != authPadSz) {
    6755             XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    6756         }
    6757 
    6758         return ret;
    6759     }
    6760 
     8433}
     8434
     8435#ifdef WOLF_CRYPTO_DEV
     8436    if (aes->devId != INVALID_DEVID) {
     8437        int ret = wc_CryptoDev_AesGcmEncrypt(aes, out, in, sz, iv, ivSz,
     8438            authTag, authTagSz, authIn, authInSz);
     8439        if (ret != NOT_COMPILED_IN)
     8440            return ret;
     8441        ret = 0; /* reset error code and try using software */
     8442    }
    67618443#endif
    67628444
    6763     /* Software AES-GCM */
     8445#if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || \
     8446                              defined(WOLFSSL_STM32F7) || \
     8447                              defined(WOLFSSL_STM32L4))
     8448
     8449    /* STM32 HW only supports 12 byte IV and 16 byte auth */
     8450    if (ivSz == GCM_NONCE_MID_SZ && authInSz == AES_BLOCK_SIZE) {
     8451        return wc_AesGcmEncrypt_STM32(aes, out, in, sz, iv, ivSz,
     8452                                      authTag, authTagSz, authIn, authInSz);
     8453    }
     8454    #endif
    67648455
    67658456#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
    67668457    /* if async and byte count above threshold */
     8458    /* only 12-byte IV is supported in HW */
    67678459    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
    6768                                                 sz >= WC_ASYNC_THRESH_AES_GCM) {
     8460                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
    67698461    #if defined(HAVE_CAVIUM)
    6770         /* Not yet supported, contact wolfSSL if interested in using */
     8462        #ifdef HAVE_CAVIUM_V
     8463        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
     8464            return NitroxAesGcmEncrypt(aes, out, in, sz,
     8465                (const byte*)aes->asyncKey, aes->keylen, iv, ivSz,
     8466                authTag, authTagSz, authIn, authInSz);
     8467        }
     8468            #endif
    67718469    #elif defined(HAVE_INTEL_QA)
    67728470        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
     
    67888486            return WC_PENDING_E;
    67898487        }
     8488            #endif
     8489    }
     8490#endif /* WOLFSSL_ASYNC_CRYPT */
     8491
     8492#ifdef WOLFSSL_AESNI
     8493    #ifdef HAVE_INTEL_AVX2
     8494    if (IS_INTEL_AVX2(intel_flags)) {
     8495        AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8496                                 authTagSz, (const byte*)aes->key, aes->rounds);
     8497        return 0;
     8498        }
     8499    else
     8500            #endif
     8501    #ifdef HAVE_INTEL_AVX1
     8502    if (IS_INTEL_AVX1(intel_flags)) {
     8503        AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8504                                 authTagSz, (const byte*)aes->key, aes->rounds);
     8505        return 0;
     8506        }
     8507    else
    67908508    #endif
    6791     }
    6792 #endif /* WOLFSSL_ASYNC_CRYPT */
    6793 
    6794 #ifdef WOLFSSL_AESNI
    67958509    if (haveAESNI) {
    6796     #ifdef HAVE_INTEL_AVX2
    6797         if (IS_INTEL_AVX2(intel_flags)) {
    6798             AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag,
    6799                         sz, authInSz, ivSz, (const byte*)aes->key, aes->rounds);
    6800         }
    6801         else
    6802     #endif
    6803             AES_GCM_encrypt(in, out, authIn, iv, authTag,
    6804                         sz, authInSz, ivSz, (const byte*)aes->key, aes->rounds);
     8510        AES_GCM_encrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8511                                 authTagSz, (const byte*)aes->key, aes->rounds);
    68058512        return 0;
    68068513    }
     8514    else
    68078515#endif
    6808 
    6809     ctr = counter;
    6810     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
    6811     if (ivSz == NONCE_SZ) {
    6812         XMEMCPY(initialCounter, iv, ivSz);
    6813         initialCounter[AES_BLOCK_SIZE - 1] = 1;
    6814     }
    6815     else {
    6816         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
    6817     }
    6818     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
    6819 
    6820 #ifdef WOLFSSL_PIC32MZ_CRYPT
    6821     if (blocks) {
    6822         /* use intitial IV for PIC32 HW, but don't use it below */
    6823         XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
    6824 
    6825         ret = wc_Pic32AesCrypt(
    6826             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
    6827             out, in, (blocks * AES_BLOCK_SIZE),
    6828             PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
    6829         if (ret != 0)
    6830             return ret;
    6831     }
    6832     /* process remainder using partial handling */
     8516    {
     8517        return AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
     8518                                                              authIn, authInSz);
     8519    }
     8520}
    68338521#endif
    6834     while (blocks--) {
    6835         IncrementGcmCounter(ctr);
    6836     #ifndef WOLFSSL_PIC32MZ_CRYPT
    6837         wc_AesEncrypt(aes, ctr, scratch);
    6838         xorbuf(scratch, p, AES_BLOCK_SIZE);
    6839         XMEMCPY(c, scratch, AES_BLOCK_SIZE);
    6840     #endif
    6841         p += AES_BLOCK_SIZE;
    6842         c += AES_BLOCK_SIZE;
    6843     }
    6844 
    6845     if (partial != 0) {
    6846         IncrementGcmCounter(ctr);
    6847         wc_AesEncrypt(aes, ctr, scratch);
    6848         xorbuf(scratch, p, partial);
    6849         XMEMCPY(c, scratch, partial);
    6850 
    6851     }
    6852 
    6853     GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
    6854     wc_AesEncrypt(aes, initialCounter, scratch);
    6855     xorbuf(authTag, scratch, authTagSz);
    6856 
    6857 #endif /* FREESCALE_LTC_AES_GCM */
    6858 
    6859     return ret;
    6860 }
    6861 
    6862 
     8522
     8523
     8524
     8525/* AES GCM Decrypt */
    68638526#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
     8527#ifdef FREESCALE_LTC_AES_GCM
    68648528int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
    68658529                   const byte* iv, word32 ivSz,
     
    68678531                   const byte* authIn, word32 authInSz)
    68688532{
     8533    int ret;
     8534    word32 keySize;
     8535    status_t status;
     8536
     8537    /* argument checks */
     8538    /* If the sz is non-zero, both in and out must be set. If sz is 0,
     8539     * in and out are don't cares, as this is is the GMAC case. */
     8540    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
     8541        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0) {
     8542
     8543        return BAD_FUNC_ARG;
     8544    }
     8545
     8546    ret = wc_AesGetKeySize(aes, &keySize);
     8547    if (ret != 0) {
     8548        return ret;
     8549    }
     8550
     8551    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
     8552        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
     8553
     8554    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
     8555}
     8556
     8557#else
     8558
     8559#if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || \
     8560                              defined(WOLFSSL_STM32F7) || \
     8561                              defined(WOLFSSL_STM32L4))
     8562static WC_INLINE int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
     8563                    const byte* in, word32 sz,
     8564                    const byte* iv, word32 ivSz,
     8565                    const byte* authTag, word32 authTagSz,
     8566                    const byte* authIn, word32 authInSz)
     8567{
     8568    int ret;
     8569#ifdef WOLFSSL_STM32_CUBEMX
     8570    CRYP_HandleTypeDef hcryp;
     8571#else
     8572    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
     8573#endif
     8574    word32 keySize;
     8575    int status;
     8576    int outPadSz, authPadSz;
     8577    word32 tag[AES_BLOCK_SIZE/sizeof(word32)];
     8578    word32 initialCounter[AES_BLOCK_SIZE/sizeof(word32)];
     8579    byte* outPadded = NULL;
     8580    byte* authInPadded = NULL;
     8581
     8582    ret = wc_AesGetKeySize(aes, &keySize);
     8583    if (ret != 0)
     8584        return ret;
     8585
     8586#ifdef WOLFSSL_STM32_CUBEMX
     8587    ret = wc_Stm32_Aes_Init(aes, &hcryp);
     8588    if (ret != 0)
     8589        return ret;
     8590#endif
     8591
     8592    XMEMSET(initialCounter, 0, sizeof(initialCounter));
     8593    XMEMCPY(initialCounter, iv, ivSz);
     8594    *((byte*)initialCounter + (AES_BLOCK_SIZE - 1)) = STM32_GCM_IV_START;
     8595
     8596    /* Need to pad the AAD and input cipher text to a full block size since
     8597     * CRYP_AES_GCM will assume these are a multiple of AES_BLOCK_SIZE.
     8598     * It is okay to pad with zeros because GCM does this before GHASH already.
     8599     * See NIST SP 800-38D */
     8600    if ((sz % AES_BLOCK_SIZE) != 0 || sz == 0) {
     8601        outPadSz = ((sz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
     8602        outPadded = (byte*)XMALLOC(outPadSz, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8603        if (outPadded == NULL) {
     8604            return MEMORY_E;
     8605        }
     8606        XMEMSET(outPadded, 0, outPadSz);
     8607    }
     8608    else {
     8609        outPadSz = sz;
     8610        outPadded = out;
     8611    }
     8612    XMEMCPY(outPadded, in, sz);
     8613
     8614    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {
     8615            /* Need to pad the AAD to a full block with zeros. */
     8616        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
     8617        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
     8618            DYNAMIC_TYPE_TMP_BUFFER);
     8619            if (authInPadded == NULL) {
     8620            if (outPadded != out) {
     8621                XFREE(outPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8622            }
     8623                return MEMORY_E;
     8624            }
     8625            XMEMSET(authInPadded, 0, authPadSz);
     8626            XMEMCPY(authInPadded, authIn, authInSz);
     8627        } else {
     8628            authPadSz = authInSz;
     8629            authInPadded = (byte*)authIn;
     8630        }
     8631
     8632    #ifdef WOLFSSL_STM32_CUBEMX
     8633    hcryp.Init.pInitVect = (uint8_t*)initialCounter;
     8634        hcryp.Init.Header = authInPadded;
     8635        hcryp.Init.HeaderSize = authInSz;
     8636
     8637#ifdef STM32_CRYPTO_AES_ONLY
     8638    /* Set the CRYP parameters */
     8639    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
     8640    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
     8641    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
     8642        HAL_CRYP_Init(&hcryp);
     8643
     8644    /* GCM init phase */
     8645    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
     8646    if (status == HAL_OK) {
     8647        /* GCM header phase */
     8648        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
     8649        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
     8650        if (status == HAL_OK) {
     8651            /* GCM payload phase */
     8652            hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
     8653            status = HAL_CRYPEx_AES_Auth(&hcryp, outPadded, sz, outPadded,
     8654                STM32_HAL_TIMEOUT);
     8655            if (status == HAL_OK) {
     8656                /* GCM final phase */
     8657                hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
     8658                status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag,
     8659                    STM32_HAL_TIMEOUT);
     8660            }
     8661        }
     8662    }
     8663#else
     8664    HAL_CRYP_Init(&hcryp);
     8665    /* Use outPadded for output buffer instead of out so that we don't overflow
     8666     * our size. */
     8667    status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, outPadded, sz, outPadded,
     8668        STM32_HAL_TIMEOUT);
     8669        /* Compute the authTag */
     8670    if (status == HAL_OK) {
     8671        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag,
     8672            STM32_HAL_TIMEOUT);
     8673    }
     8674#endif
     8675
     8676        if (status != HAL_OK)
     8677            ret = AES_GCM_AUTH_E;
     8678
     8679        HAL_CRYP_DeInit(&hcryp);
     8680
     8681#else /* STD_PERI_LIB */
     8682    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
     8683
     8684    /* Input size and auth size need to be the actual sizes, even though
     8685     * they are not block aligned, because this length (in bits) is used
     8686     * in the final GHASH. Use outPadded for output buffer instead of
     8687     * out so that we don't overflow our size.                         */
     8688    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)initialCounter,
     8689                             (uint8_t*)keyCopy,     keySize * 8,
     8690                         (uint8_t*)outPadded,   sz,
     8691                             (uint8_t*)authInPadded,authInSz,
     8692                         (uint8_t*)outPadded,   (byte*)tag);
     8693        if (status != SUCCESS)
     8694            ret = AES_GCM_AUTH_E;
     8695    #endif /* WOLFSSL_STM32_CUBEMX */
     8696
     8697    if (ConstantCompare(authTag, (byte*)tag, authTagSz) != 0) {
     8698        ret = AES_GCM_AUTH_E;
     8699        }
     8700
     8701    if (ret == 0) {
     8702        /* return output if allocated padded used */
     8703        if (outPadded != out) {
     8704            XMEMCPY(out, outPadded, sz);
     8705        }
     8706    }
     8707
     8708    /* Free memory if not a multiple of AES_BLOCK_SZ */
     8709    if (outPadded != out) {
     8710        XFREE(outPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8711        }
     8712    if (authInPadded != authIn) {
     8713        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
     8714    }
     8715
     8716    return ret;
     8717    }
     8718#endif /* STM32 */
     8719
     8720#ifdef WOLFSSL_AESNI
     8721int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
     8722                      const byte* iv, word32 ivSz,
     8723                      const byte* authTag, word32 authTagSz,
     8724                      const byte* authIn, word32 authInSz);
     8725#else
     8726static
     8727#endif
     8728int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
     8729                      const byte* iv, word32 ivSz,
     8730                      const byte* authTag, word32 authTagSz,
     8731                      const byte* authIn, word32 authInSz)
     8732{
    68698733    int ret = 0;
    6870     word32 keySize;
    6871 #ifdef FREESCALE_LTC_AES_GCM
    6872     status_t status;
    6873 #elif defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || defined(WOLFSSL_STM32F7))
    6874     #ifdef WOLFSSL_STM32_CUBEMX
    6875         CRYP_HandleTypeDef hcryp;
    6876     #else
    6877         byte keyCopy[AES_BLOCK_SIZE * 2];
    6878     #endif /* WOLFSSL_STM32_CUBEMX */
    6879     int  status;
    6880     int  inPadSz, authPadSz;
    6881     byte tag[AES_BLOCK_SIZE];
    6882     byte *inPadded = NULL;
    6883     byte *authInPadded = NULL;
    6884     byte initialCounter[AES_BLOCK_SIZE];
    6885 #else /* software AES-GCM */
    68868734    word32 blocks = sz / AES_BLOCK_SIZE;
    68878735    word32 partial = sz % AES_BLOCK_SIZE;
     
    68948742    byte Tprime[AES_BLOCK_SIZE];
    68958743    byte EKY0[AES_BLOCK_SIZE];
     8744    ctr = counter;
     8745
     8746    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
     8747    if (ivSz == GCM_NONCE_MID_SZ) {
     8748        XMEMCPY(initialCounter, iv, ivSz);
     8749        initialCounter[AES_BLOCK_SIZE - 1] = 1;
     8750    }
     8751    else {
     8752        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
     8753    }
     8754    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
     8755
     8756    /* Calc the authTag again using the received auth data and the cipher text */
     8757    GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
     8758    wc_AesEncrypt(aes, ctr, EKY0);
     8759    xorbuf(Tprime, EKY0, sizeof(Tprime));
     8760
     8761    if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
     8762        return AES_GCM_AUTH_E;
     8763    }
     8764
     8765#ifdef WOLFSSL_PIC32MZ_CRYPT
     8766    if (blocks) {
     8767        /* use initial IV for PIC32 HW, but don't use it below */
     8768        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
     8769
     8770        ret = wc_Pic32AesCrypt(
     8771            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
     8772            out, in, (blocks * AES_BLOCK_SIZE),
     8773            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
     8774        if (ret != 0)
     8775            return ret;
     8776    }
     8777    /* process remainder using partial handling */
    68968778#endif
    68978779
     8780#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
     8781    /* some hardware acceleration can gain performance from doing AES encryption
     8782     * of the whole buffer at once */
     8783    if (c != p) { /* can not handle inline decryption */
     8784        while (blocks--) {
     8785            IncrementGcmCounter(ctr);
     8786            XMEMCPY(p, ctr, AES_BLOCK_SIZE);
     8787            p += AES_BLOCK_SIZE;
     8788        }
     8789
     8790        /* reset number of blocks and then do encryption */
     8791        blocks = sz / AES_BLOCK_SIZE;
     8792        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
     8793        xorbuf(out, c, AES_BLOCK_SIZE * blocks);
     8794        c += AES_BLOCK_SIZE * blocks;
     8795    }
     8796    else
     8797#endif /* HAVE_AES_ECB */
     8798    while (blocks--) {
     8799        IncrementGcmCounter(ctr);
     8800    #ifndef WOLFSSL_PIC32MZ_CRYPT
     8801        wc_AesEncrypt(aes, ctr, scratch);
     8802        xorbuf(scratch, c, AES_BLOCK_SIZE);
     8803        XMEMCPY(p, scratch, AES_BLOCK_SIZE);
     8804    #endif
     8805        p += AES_BLOCK_SIZE;
     8806        c += AES_BLOCK_SIZE;
     8807    }
     8808
     8809    if (partial != 0) {
     8810        IncrementGcmCounter(ctr);
     8811        wc_AesEncrypt(aes, ctr, scratch);
     8812        xorbuf(scratch, c, partial);
     8813        XMEMCPY(p, scratch, partial);
     8814    }
     8815
     8816    return ret;
     8817}
     8818
     8819/* Software AES - GCM Decrypt */
     8820int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
     8821                   const byte* iv, word32 ivSz,
     8822                   const byte* authTag, word32 authTagSz,
     8823                   const byte* authIn, word32 authInSz)
     8824{
     8825#ifdef WOLFSSL_AESNI
     8826    int res = AES_GCM_AUTH_E;
     8827#endif
     8828
    68988829    /* argument checks */
    6899     if (aes == NULL || out == NULL || in == NULL || iv == NULL ||
    6900         authTag == NULL || authTagSz > AES_BLOCK_SIZE) {
     8830    /* If the sz is non-zero, both in and out must be set. If sz is 0,
     8831     * in and out are don't cares, as this is is the GMAC case. */
     8832    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
     8833        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0) {
     8834
    69018835        return BAD_FUNC_ARG;
    69028836    }
    69038837
    6904     ret = wc_AesGetKeySize(aes, &keySize);
    6905     if (ret != 0) {
    6906         return ret;
    6907     }
    6908 
    6909 #ifdef FREESCALE_LTC_AES_GCM
    6910 
    6911     status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
    6912         authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
    6913 
    6914     ret = (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
    6915 
    6916 #elif defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || defined(WOLFSSL_STM32F7))
    6917 
    6918     /* additional argument checks - STM32 HW only supports 12 byte IV */
    6919     if (ivSz != NONCE_SZ) {
    6920         return BAD_FUNC_ARG;
    6921     }
    6922 
    6923     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
    6924     XMEMCPY(initialCounter, iv, ivSz);
    6925     initialCounter[AES_BLOCK_SIZE - 1] = STM32_GCM_IV_START;
    6926 
    6927     /* Need to pad the AAD and input cipher text to a full block size since
    6928      * CRYP_AES_GCM will assume these are a multiple of AES_BLOCK_SIZE.
    6929      * It is okay to pad with zeros because GCM does this before GHASH already.
    6930      * See NIST SP 800-38D */
    6931 
    6932     if ((sz % AES_BLOCK_SIZE) > 0) {
    6933         inPadSz = ((sz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
    6934         inPadded = XMALLOC(inPadSz, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    6935         if (inPadded == NULL) {
    6936             return MEMORY_E;
    6937         }
    6938         XMEMSET(inPadded, 0, inPadSz);
    6939         XMEMCPY(inPadded, in, sz);
    6940     } else {
    6941         inPadSz = sz;
    6942         inPadded = (byte*)in;
    6943     }
    6944 
    6945     if ((authInSz % AES_BLOCK_SIZE) > 0) {
    6946         authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
    6947         authInPadded = XMALLOC(authPadSz, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    6948         if (authInPadded == NULL) {
    6949             if (inPadded != NULL && inPadSz != sz)
    6950                 XFREE(inPadded , aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    6951             return MEMORY_E;
    6952         }
    6953         XMEMSET(authInPadded, 0, authPadSz);
    6954         XMEMCPY(authInPadded, authIn, authInSz);
    6955     } else {
    6956         authPadSz = authInSz;
    6957         authInPadded = (byte*)authIn;
    6958     }
    6959 
    6960 #ifdef WOLFSSL_STM32_CUBEMX
    6961     XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
    6962     switch(keySize) {
    6963         case 16: /* 128-bit key */
    6964             hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
    6965             break;
    6966         case 24: /* 192-bit key */
    6967             hcryp.Init.KeySize = CRYP_KEYSIZE_192B;
    6968             break;
    6969         case 32: /* 256-bit key */
    6970             hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
    6971             break;
    6972         default:
    6973             break;
    6974     }
    6975     hcryp.Instance = CRYP;
    6976     hcryp.Init.DataType = CRYP_DATATYPE_8B;
    6977     hcryp.Init.pKey = (byte*)aes->key;
    6978     hcryp.Init.pInitVect = initialCounter;
    6979     hcryp.Init.Header = authInPadded;
    6980     hcryp.Init.HeaderSize = authInSz;
    6981 
    6982     HAL_CRYP_Init(&hcryp);
    6983     /* Use inPadded for output buffer instead of
    6984     * out so that we don't overflow our size. */
    6985     status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)inPadded,
    6986                                     sz, inPadded, STM32_HAL_TIMEOUT);
    6987     /* Compute the authTag */
    6988     if (status == HAL_OK)
    6989         status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);
    6990 
    6991     if (status != HAL_OK)
    6992         ret = AES_GCM_AUTH_E;
    6993 
    6994     HAL_CRYP_DeInit(&hcryp);
    6995 #else
    6996     ByteReverseWords((word32*)keyCopy, (word32*)aes->key, keySize);
    6997 
    6998     /* Input size and auth size need to be the actual sizes, even though
    6999      * they are not block aligned, because this length (in bits) is used
    7000      * in the final GHASH. Use inPadded for output buffer instead of
    7001      * out so that we don't overflow our size.                         */
    7002     status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)initialCounter,
    7003                          (uint8_t*)keyCopy,     keySize * 8,
    7004                          (uint8_t*)inPadded,    sz,
    7005                          (uint8_t*)authInPadded,authInSz,
    7006                          (uint8_t*)inPadded,    tag);
    7007     if (status != SUCCESS)
    7008         ret = AES_GCM_AUTH_E;
    7009 #endif /* WOLFSSL_STM32_CUBEMX */
    7010 
    7011     if (ret == 0 && ConstantCompare(authTag, tag, authTagSz) == 0) {
    7012         /* Only keep the decrypted data if authTag success. */
    7013         XMEMCPY(out, inPadded, sz);
    7014         ret = 0; /* success */
    7015     }
    7016 
    7017     /* only allocate padding buffers if the inputs are not a multiple of block sz */
    7018     if (inPadded != NULL && inPadSz != sz)
    7019         XFREE(inPadded , aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    7020     if (authInPadded != NULL && authPadSz != authInSz)
    7021         XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
    7022 
    7023 #else
    7024 
    7025     /* software AES GCM */
     8838#ifdef WOLF_CRYPTO_DEV
     8839    if (aes->devId != INVALID_DEVID) {
     8840        int ret = wc_CryptoDev_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
     8841            authTag, authTagSz, authIn, authInSz);
     8842        if (ret != NOT_COMPILED_IN)
     8843            return ret;
     8844    }
     8845#endif
     8846
     8847#if defined(STM32_CRYPTO) && (defined(WOLFSSL_STM32F4) || \
     8848                              defined(WOLFSSL_STM32F7) || \
     8849                              defined(WOLFSSL_STM32L4))
     8850
     8851    /* STM32 HW only supports 12 byte IV and 16 byte auth */
     8852    if (ivSz == GCM_NONCE_MID_SZ && authInSz == AES_BLOCK_SIZE) {
     8853        return wc_AesGcmDecrypt_STM32(aes, out, in, sz, iv, ivSz,
     8854                                      authTag, authTagSz, authIn, authInSz);
     8855    }
     8856#endif
    70268857
    70278858#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
    70288859    /* if async and byte count above threshold */
     8860    /* only 12-byte IV is supported in HW */
    70298861    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
    7030                                                 sz >= WC_ASYNC_THRESH_AES_GCM) {
     8862                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
    70318863    #if defined(HAVE_CAVIUM)
    7032         /* Not yet supported, contact wolfSSL if interested in using */
     8864        #ifdef HAVE_CAVIUM_V
     8865        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
     8866            return NitroxAesGcmDecrypt(aes, out, in, sz,
     8867                (const byte*)aes->asyncKey, aes->keylen, iv, ivSz,
     8868                authTag, authTagSz, authIn, authInSz);
     8869        }
     8870        #endif
    70338871    #elif defined(HAVE_INTEL_QA)
    70348872        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
     
    70558893
    70568894#ifdef WOLFSSL_AESNI
    7057     if (haveAESNI) {
    70588895    #ifdef HAVE_INTEL_AVX2
    70598896        if (IS_INTEL_AVX2(intel_flags)) {
    7060             if (AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz,
    7061                                        ivSz, (byte*)aes->key, aes->rounds) == 0)
     8897        AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8898                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
     8899        if (res == 0)
    70628900            return AES_GCM_AUTH_E;
     8901        return 0;
     8902    }
     8903    else
     8904    #endif
     8905    #ifdef HAVE_INTEL_AVX1
     8906    if (IS_INTEL_AVX1(intel_flags)) {
     8907        AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8908                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
     8909        if (res == 0)
     8910            return AES_GCM_AUTH_E;
     8911        return 0;
    70638912        }
    70648913        else
    70658914    #endif
    7066         if (AES_GCM_decrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
    7067                                              (byte*)aes->key, aes->rounds) == 0)
     8915    if (haveAESNI) {
     8916        AES_GCM_decrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
     8917                                 authTagSz, (byte*)aes->key, aes->rounds, &res);
     8918        if (res == 0)
    70688919            return AES_GCM_AUTH_E;
    70698920        return 0;
    70708921    }
     8922    else
    70718923#endif
    7072 
    7073     ctr = counter;
    7074     XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
    7075     if (ivSz == NONCE_SZ) {
    7076         XMEMCPY(initialCounter, iv, ivSz);
    7077         initialCounter[AES_BLOCK_SIZE - 1] = 1;
    7078     }
    7079     else {
    7080         GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);
    7081     }
    7082     XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);
    7083 
    7084     /* Calc the authTag again using the received auth data and the cipher text */
    7085     GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
    7086     wc_AesEncrypt(aes, ctr, EKY0);
    7087     xorbuf(Tprime, EKY0, sizeof(Tprime));
    7088 
    7089     if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {
    7090         return AES_GCM_AUTH_E;
    7091     }
    7092 
    7093 #ifdef WOLFSSL_PIC32MZ_CRYPT
    7094     if (blocks) {
    7095         /* use intitial IV for PIC32 HW, but don't use it below */
    7096         XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
    7097 
    7098         ret = wc_Pic32AesCrypt(
    7099             aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
    7100             out, in, (blocks * AES_BLOCK_SIZE),
    7101             PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
    7102         if (ret != 0)
    7103             return ret;
    7104     }
    7105     /* process remainder using partial handling */
     8924    {
     8925        return AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
     8926                                                              authIn, authInSz);
     8927    }
     8928}
    71068929#endif
    7107 
    7108     while (blocks--) {
    7109         IncrementGcmCounter(ctr);
    7110     #ifndef WOLFSSL_PIC32MZ_CRYPT
    7111         wc_AesEncrypt(aes, ctr, scratch);
    7112         xorbuf(scratch, c, AES_BLOCK_SIZE);
    7113         XMEMCPY(p, scratch, AES_BLOCK_SIZE);
    7114     #endif
    7115         p += AES_BLOCK_SIZE;
    7116         c += AES_BLOCK_SIZE;
    7117     }
    7118     if (partial != 0) {
    7119         IncrementGcmCounter(ctr);
    7120         wc_AesEncrypt(aes, ctr, scratch);
    7121         xorbuf(scratch, c, partial);
    7122         XMEMCPY(p, scratch, partial);
    7123     }
    7124 
    7125 #endif
     8930#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
     8931#endif /* WOLFSSL_XILINX_CRYPT */
     8932#endif /* end of block for AESGCM implementation selection */
     8933
     8934
     8935/* Common to all, abstract functions that build off of lower level AESGCM
     8936 * functions */
     8937#ifndef WC_NO_RNG
     8938
     8939int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
     8940{
     8941    int ret = 0;
     8942
     8943    if (aes == NULL || iv == NULL ||
     8944        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
     8945         ivSz != GCM_NONCE_MAX_SZ)) {
     8946
     8947        ret = BAD_FUNC_ARG;
     8948    }
     8949
     8950    if (ret == 0) {
     8951        XMEMCPY((byte*)aes->reg, iv, ivSz);
     8952
     8953        /* If the IV is 96, allow for a 2^64 invocation counter.
     8954         * For any other size for the nonce, limit the invocation
     8955         * counter to 32-bits. (SP 800-38D 8.3) */
     8956        aes->invokeCtr[0] = 0;
     8957        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
     8958        aes->nonceSz = ivSz;
     8959    }
    71268960
    71278961    return ret;
    71288962}
    71298963
    7130 #endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
    7131 #endif /* (WOLFSSL_XILINX_CRYPT) */
     8964
     8965int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
     8966                   const byte* ivFixed, word32 ivFixedSz,
     8967                   WC_RNG* rng)
     8968{
     8969    int ret = 0;
     8970
     8971    if (aes == NULL || rng == NULL ||
     8972        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
     8973         ivSz != GCM_NONCE_MAX_SZ) ||
     8974        (ivFixed == NULL && ivFixedSz != 0) ||
     8975        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
     8976
     8977        ret = BAD_FUNC_ARG;
     8978    }
     8979
     8980    if (ret == 0) {
     8981        byte* iv = (byte*)aes->reg;
     8982
     8983        if (ivFixedSz)
     8984            XMEMCPY(iv, ivFixed, ivFixedSz);
     8985
     8986        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
     8987    }
     8988
     8989    if (ret == 0) {
     8990        /* If the IV is 96, allow for a 2^64 invocation counter.
     8991         * For any other size for the nonce, limit the invocation
     8992         * counter to 32-bits. (SP 800-38D 8.3) */
     8993        aes->invokeCtr[0] = 0;
     8994        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
     8995        aes->nonceSz = ivSz;
     8996    }
     8997
     8998            return ret;
     8999    }
     9000
     9001
     9002int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
     9003                        byte* ivOut, word32 ivOutSz,
     9004                        byte* authTag, word32 authTagSz,
     9005                        const byte* authIn, word32 authInSz)
     9006{
     9007    int ret = 0;
     9008
     9009    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
     9010        ivOut == NULL || ivOutSz != aes->nonceSz ||
     9011        (authIn == NULL && authInSz != 0)) {
     9012
     9013        ret = BAD_FUNC_ARG;
     9014    }
     9015
     9016    if (ret == 0) {
     9017        aes->invokeCtr[0]++;
     9018        if (aes->invokeCtr[0] == 0) {
     9019            aes->invokeCtr[1]++;
     9020            if (aes->invokeCtr[1] == 0)
     9021                ret = AES_GCM_OVERFLOW_E;
     9022        }
     9023    }
     9024
     9025    if (ret == 0) {
     9026        XMEMCPY(ivOut, aes->reg, ivOutSz);
     9027        ret = wc_AesGcmEncrypt(aes, out, in, sz,
     9028                               (byte*)aes->reg, ivOutSz,
     9029                               authTag, authTagSz,
     9030                               authIn, authInSz);
     9031        IncCtr((byte*)aes->reg, ivOutSz);
     9032    }
     9033
     9034    return ret;
     9035}
     9036
     9037int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
     9038            const byte* authIn, word32 authInSz,
     9039            byte* authTag, word32 authTagSz, WC_RNG* rng)
     9040{
     9041    Aes aes;
     9042    int ret;
     9043
     9044    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
     9045        authTag == NULL || authTagSz == 0 || rng == NULL) {
     9046
     9047        return BAD_FUNC_ARG;
     9048    }
     9049
     9050    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
     9051    if (ret == 0) {
     9052        ret = wc_AesGcmSetKey(&aes, key, keySz);
     9053        if (ret == 0)
     9054            ret = wc_AesGcmSetIV(&aes, ivSz, NULL, 0, rng);
     9055        if (ret == 0)
     9056            ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
     9057                                  authTag, authTagSz, authIn, authInSz);
     9058        wc_AesFree(&aes);
     9059    }
     9060    ForceZero(&aes, sizeof(aes));
     9061
     9062    return ret;
     9063}
     9064
     9065int wc_GmacVerify(const byte* key, word32 keySz,
     9066                  const byte* iv, word32 ivSz,
     9067                  const byte* authIn, word32 authInSz,
     9068                  const byte* authTag, word32 authTagSz)
     9069{
     9070    int ret;
     9071#ifndef NO_AES_DECRYPT
     9072    Aes aes;
     9073
     9074    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
     9075        authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
     9076
     9077        return BAD_FUNC_ARG;
     9078    }
     9079
     9080    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
     9081    if (ret == 0) {
     9082        ret = wc_AesGcmSetKey(&aes, key, keySz);
     9083        if (ret == 0)
     9084            ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,
     9085                                  authTag, authTagSz, authIn, authInSz);
     9086        wc_AesFree(&aes);
     9087    }
     9088    ForceZero(&aes, sizeof(aes));
     9089#else
     9090    (void)key;
     9091    (void)keySz;
     9092    (void)iv;
     9093    (void)ivSz;
     9094    (void)authIn;
     9095    (void)authInSz;
     9096    (void)authTag;
     9097    (void)authTagSz;
     9098    ret = NOT_COMPILED_IN;
     9099#endif
     9100    return ret;
     9101}
     9102
     9103#endif /* WC_NO_RNG */
     9104
    71329105
    71339106WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
     
    71559128int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
    71569129{
     9130    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
     9131        return BAD_FUNC_ARG;
     9132
    71579133    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
    71589134}
    71599135
    7160 #if defined(HAVE_COLDFIRE_SEC)
     9136#ifdef WOLFSSL_ARMASM
     9137    /* implementation located in wolfcrypt/src/port/arm/armv8-aes.c */
     9138
     9139#elif defined(HAVE_COLDFIRE_SEC)
    71619140    #error "Coldfire SEC doesn't currently support AES-CCM mode"
     9141
     9142#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     9143    /* implemented in wolfcrypt/src/port/caam_aes.c */
    71629144
    71639145#elif defined(FREESCALE_LTC)
     
    72269208#endif /* HAVE_AES_DECRYPT */
    72279209
    7228 
    7229 /* software AES CCM */
    72309210#else
    72319211
     9212/* Software CCM */
    72329213static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)
    72339214{
     
    72939274
    72949275
    7295 static INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
     9276static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
    72969277{
    72979278    word32 i;
     
    73029283}
    73039284
     9285/* Software AES - CCM Encrypt */
    73049286/* return 0 on success */
    73059287int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
     
    73179299    /* sanity check on arguments */
    73189300    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
    7319             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
     9301            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
     9302            authTagSz > AES_BLOCK_SIZE)
    73209303        return BAD_FUNC_ARG;
    73219304
     
    73699352
    73709353#ifdef HAVE_AES_DECRYPT
     9354/* Software AES - CCM Decrypt */
    73719355int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
    73729356                   const byte* nonce, word32 nonceSz,
     
    73859369    /* sanity check on arguments */
    73869370    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
    7387             || authTag == NULL || nonceSz < 7 || nonceSz > 13)
     9371            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
     9372            authTagSz > AES_BLOCK_SIZE)
    73889373        return BAD_FUNC_ARG;
    73899374
     
    74579442    return result;
    74589443}
     9444
    74599445#endif /* HAVE_AES_DECRYPT */
    7460 #endif /* software AES CCM */
     9446#endif /* software CCM */
     9447
     9448/* abstract functions that call lower level AESCCM functions */
     9449#ifndef WC_NO_RNG
     9450
     9451int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
     9452{
     9453    int ret = 0;
     9454
     9455    if (aes == NULL || nonce == NULL ||
     9456        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
     9457
     9458        ret = BAD_FUNC_ARG;
     9459    }
     9460
     9461    if (ret == 0) {
     9462        XMEMCPY(aes->reg, nonce, nonceSz);
     9463        aes->nonceSz = nonceSz;
     9464
     9465        /* Invocation counter should be 2^61 */
     9466        aes->invokeCtr[0] = 0;
     9467        aes->invokeCtr[1] = 0xE0000000;
     9468    }
     9469
     9470    return ret;
     9471}
     9472
     9473
     9474int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
     9475                        byte* ivOut, word32 ivOutSz,
     9476                        byte* authTag, word32 authTagSz,
     9477                        const byte* authIn, word32 authInSz)
     9478{
     9479    int ret = 0;
     9480
     9481    if (aes == NULL || out == NULL ||
     9482        (in == NULL && sz != 0) ||
     9483        ivOut == NULL ||
     9484        (authIn == NULL && authInSz != 0) ||
     9485        (ivOutSz != aes->nonceSz)) {
     9486
     9487        ret = BAD_FUNC_ARG;
     9488    }
     9489
     9490    if (ret == 0) {
     9491        aes->invokeCtr[0]++;
     9492        if (aes->invokeCtr[0] == 0) {
     9493            aes->invokeCtr[1]++;
     9494            if (aes->invokeCtr[1] == 0)
     9495                ret = AES_CCM_OVERFLOW_E;
     9496        }
     9497    }
     9498
     9499    if (ret == 0) {
     9500        ret = wc_AesCcmEncrypt(aes, out, in, sz,
     9501                               (byte*)aes->reg, aes->nonceSz,
     9502                               authTag, authTagSz,
     9503                               authIn, authInSz);
     9504        XMEMCPY(ivOut, aes->reg, aes->nonceSz);
     9505        IncCtr((byte*)aes->reg, aes->nonceSz);
     9506    }
     9507
     9508    return ret;
     9509}
     9510
     9511#endif /* WC_NO_RNG */
    74619512
    74629513#endif /* HAVE_AESCCM */
     
    74739524    aes->heap = heap;
    74749525
     9526#ifdef WOLF_CRYPTO_DEV
     9527    aes->devId = devId;
     9528#else
     9529    (void)devId;
     9530#endif
    74759531#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
    74769532    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
    74779533                                                        aes->heap, devId);
    7478 #else
    7479     (void)devId;
    74809534#endif /* WOLFSSL_ASYNC_CRYPT */
     9535
     9536#ifdef WOLFSSL_AFALG
     9537    aes->alFd = -1;
     9538    aes->rdFd = -1;
     9539#endif
     9540#if defined(WOLFSSL_DEVCRYPTO) && \
     9541   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
     9542    aes->ctx.cfd = -1;
     9543#endif
    74819544
    74829545    return ret;
    74839546}
     9547
     9548#ifdef HAVE_PKCS11
     9549int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
     9550{
     9551    int ret = 0;
     9552
     9553    if (aes == NULL)
     9554        ret = BAD_FUNC_ARG;
     9555    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
     9556        ret = BUFFER_E;
     9557
     9558    if (ret == 0)
     9559        ret  = wc_AesInit(aes, heap, devId);
     9560    if (ret == 0) {
     9561        XMEMCPY(aes->id, id, len);
     9562        aes->idLen = len;
     9563    }
     9564
     9565    return ret;
     9566}
     9567#endif
    74849568
    74859569/* Free Aes from use with async hardware */
     
    74929576    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
    74939577#endif /* WOLFSSL_ASYNC_CRYPT */
     9578#ifdef WOLFSSL_AFALG
     9579    if (aes->rdFd > 0) { /* negative is error case */
     9580        close(aes->rdFd);
     9581    }
     9582    if (aes->alFd > 0) {
     9583        close(aes->alFd);
     9584    }
     9585#endif /* WOLFSSL_AFALG */
     9586#if defined(WOLFSSL_DEVCRYPTO) && \
     9587    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
     9588    wc_DevCryptoFree(&aes->ctx);
     9589    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
     9590#endif
    74949591}
    74959592
     
    75049601
    75059602    switch (aes->rounds) {
     9603#ifdef WOLFSSL_AES_128
    75069604    case 10:
    75079605        *keySize = 16;
    75089606        break;
     9607#endif
     9608#ifdef WOLFSSL_AES_192
    75099609    case 12:
    75109610        *keySize = 24;
    75119611        break;
     9612#endif
     9613#ifdef WOLFSSL_AES_256
    75129614    case 14:
    75139615        *keySize = 32;
    75149616        break;
     9617#endif
    75159618    default:
    75169619        *keySize = 0;
     
    75219624}
    75229625
    7523 #endif /* !WOLFSSL_ARMASM */
    75249626#endif /* !WOLFSSL_TI_CRYPT */
    75259627
     9628#ifdef HAVE_AES_ECB
     9629#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
     9630    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
     9631
     9632#elif defined(WOLFSSL_AFALG)
     9633    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
     9634
     9635#elif defined(WOLFSSL_DEVCRYPTO_AES)
     9636    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
     9637
     9638#else
     9639
     9640/* Software AES - ECB */
     9641int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
     9642{
     9643    word32 blocks = sz / AES_BLOCK_SIZE;
     9644
     9645    if ((in == NULL) || (out == NULL) || (aes == NULL))
     9646      return BAD_FUNC_ARG;
     9647    while (blocks>0) {
     9648      wc_AesEncryptDirect(aes, out, in);
     9649      out += AES_BLOCK_SIZE;
     9650      in  += AES_BLOCK_SIZE;
     9651      sz  -= AES_BLOCK_SIZE;
     9652      blocks--;
     9653    }
     9654    return 0;
     9655}
     9656
     9657
     9658int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
     9659{
     9660    word32 blocks = sz / AES_BLOCK_SIZE;
     9661
     9662    if ((in == NULL) || (out == NULL) || (aes == NULL))
     9663      return BAD_FUNC_ARG;
     9664    while (blocks>0) {
     9665      wc_AesDecryptDirect(aes, out, in);
     9666      out += AES_BLOCK_SIZE;
     9667      in  += AES_BLOCK_SIZE;
     9668      sz  -= AES_BLOCK_SIZE;
     9669      blocks--;
     9670    }
     9671    return 0;
     9672}
     9673#endif
     9674#endif /* HAVE_AES_ECB */
     9675
     9676#ifdef WOLFSSL_AES_CFB
     9677/* CFB 128
     9678 *
     9679 * aes structure holding key to use for encryption
     9680 * out buffer to hold result of encryption (must be at least as large as input
     9681 *     buffer)
     9682 * in  buffer to encrypt
     9683 * sz  size of input buffer
     9684 *
     9685 * returns 0 on success and negative error values on failure
     9686 */
     9687/* Software AES - CFB Encrypt */
     9688int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
     9689{
     9690    byte*  tmp = NULL;
     9691    byte*  reg = NULL;
     9692
     9693    WOLFSSL_ENTER("wc_AesCfbEncrypt");
     9694
     9695    if (aes == NULL || out == NULL || in == NULL) {
     9696        return BAD_FUNC_ARG;
     9697    }
     9698
     9699    if (aes->left && sz) {
     9700        reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left;
     9701    }
     9702
     9703    /* consume any unused bytes left in aes->tmp */
     9704    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
     9705    while (aes->left && sz) {
     9706        *(out++) = *(reg++) = *(in++) ^ *(tmp++);
     9707        aes->left--;
     9708        sz--;
     9709    }
     9710
     9711    while (sz >= AES_BLOCK_SIZE) {
     9712        wc_AesEncryptDirect(aes, out, (byte*)aes->reg);
     9713        xorbuf(out, in, AES_BLOCK_SIZE);
     9714        XMEMCPY(aes->reg, out, AES_BLOCK_SIZE);
     9715        out += AES_BLOCK_SIZE;
     9716        in  += AES_BLOCK_SIZE;
     9717        sz  -= AES_BLOCK_SIZE;
     9718        aes->left = 0;
     9719    }
     9720
     9721    /* encrypt left over data */
     9722    if (sz) {
     9723        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
     9724        aes->left = AES_BLOCK_SIZE;
     9725        tmp = (byte*)aes->tmp;
     9726        reg = (byte*)aes->reg;
     9727
     9728        while (sz--) {
     9729            *(out++) = *(reg++) = *(in++) ^ *(tmp++);
     9730            aes->left--;
     9731        }
     9732    }
     9733
     9734    return 0;
     9735}
     9736
     9737
     9738#ifdef HAVE_AES_DECRYPT
     9739/* CFB 128
     9740 *
     9741 * aes structure holding key to use for decryption
     9742 * out buffer to hold result of decryption (must be at least as large as input
     9743 *     buffer)
     9744 * in  buffer to decrypt
     9745 * sz  size of input buffer
     9746 *
     9747 * returns 0 on success and negative error values on failure
     9748 */
     9749/* Software AES - CFB Decrypt */
     9750int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
     9751{
     9752    byte*  tmp;
     9753
     9754    WOLFSSL_ENTER("wc_AesCfbDecrypt");
     9755
     9756    if (aes == NULL || out == NULL || in == NULL) {
     9757        return BAD_FUNC_ARG;
     9758    }
     9759
     9760    /* check if more input needs copied over to aes->reg */
     9761    if (aes->left && sz) {
     9762        int size = min(aes->left, sz);
     9763        XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size);
     9764    }
     9765
     9766    /* consume any unused bytes left in aes->tmp */
     9767    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
     9768    while (aes->left && sz) {
     9769        *(out++) = *(in++) ^ *(tmp++);
     9770        aes->left--;
     9771        sz--;
     9772    }
     9773
     9774    while (sz > AES_BLOCK_SIZE) {
     9775        wc_AesEncryptDirect(aes, out, (byte*)aes->reg);
     9776        xorbuf(out, in, AES_BLOCK_SIZE);
     9777        XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
     9778        out += AES_BLOCK_SIZE;
     9779        in  += AES_BLOCK_SIZE;
     9780        sz  -= AES_BLOCK_SIZE;
     9781        aes->left = 0;
     9782    }
     9783
     9784    /* decrypt left over data */
     9785    if (sz) {
     9786        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
     9787        XMEMCPY(aes->reg, in, sz);
     9788        aes->left = AES_BLOCK_SIZE;
     9789        tmp = (byte*)aes->tmp;
     9790
     9791        while (sz--) {
     9792            *(out++) = *(in++) ^ *(tmp++);
     9793            aes->left--;
     9794        }
     9795    }
     9796
     9797    return 0;
     9798}
     9799#endif /* HAVE_AES_DECRYPT */
     9800#endif /* WOLFSSL_AES_CFB */
     9801
    75269802
    75279803#ifdef HAVE_AES_KEYWRAP
    75289804
    75299805/* Initialize key wrap counter with value */
    7530 static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
     9806static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
    75319807{
    75329808    int i;
     
    75419817
    75429818/* Increment key wrap counter */
    7543 static INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
     9819static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
    75449820{
    75459821    int i;
     
    75539829
    75549830/* Decrement key wrap counter */
    7555 static INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
     9831static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
    75569832{
    75579833    int i;
     
    783610112}
    783710113
     10114#ifdef HAVE_AES_ECB
     10115/* helper function for encrypting / decrypting full buffer at once */
     10116static int _AesXtsHelper(Aes* aes, byte* out, const byte* in, word32 sz, int dir)
     10117{
     10118    word32 outSz   = sz;
     10119    word32 totalSz = (sz / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; /* total bytes */
     10120    byte*  pt      = out;
     10121
     10122    outSz -= AES_BLOCK_SIZE;
     10123
     10124    while (outSz > 0) {
     10125        word32 j;
     10126        byte carry = 0;
     10127
     10128        /* multiply by shift left and propagate carry */
     10129        for (j = 0; j < AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
     10130            byte tmpC;
     10131
     10132            tmpC   = (pt[j] >> 7) & 0x01;
     10133            pt[j+AES_BLOCK_SIZE] = ((pt[j] << 1) + carry) & 0xFF;
     10134            carry  = tmpC;
     10135        }
     10136        if (carry) {
     10137            pt[AES_BLOCK_SIZE] ^= GF_XTS;
     10138        }
     10139
     10140        pt += AES_BLOCK_SIZE;
     10141    }
     10142
     10143    xorbuf(out, in, totalSz);
     10144    if (dir == AES_ENCRYPTION) {
     10145        return wc_AesEcbEncrypt(aes, out, out, totalSz);
     10146    }
     10147    else {
     10148        return wc_AesEcbDecrypt(aes, out, out, totalSz);
     10149    }
     10150}
     10151#endif /* HAVE_AES_ECB */
     10152
    783810153
    783910154/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
     
    784910164 * returns 0 on success
    785010165 */
     10166/* Software AES - XTS Encrypt  */
    785110167int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
    785210168        const byte* i, word32 iSz)
     
    785610172    Aes *aes, *tweak;
    785710173
    7858     if (xaes == NULL || out == NULL) {
     10174    if (xaes == NULL || out == NULL || in == NULL) {
    785910175        return BAD_FUNC_ARG;
    786010176    }
     
    786710183    }
    786810184
    7869     if (in == NULL && sz > 0) {
    7870         return BAD_FUNC_ARG;
    7871     }
    7872 
    787310185    if (blocks > 0) {
    787410186        byte tmp[AES_BLOCK_SIZE];
    787510187
     10188        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
     10189                                          * key setup passed to encrypt direct*/
     10190
    787610191        wc_AesEncryptDirect(tweak, tmp, i);
     10192
     10193    #ifdef HAVE_AES_ECB
     10194        /* encrypt all of buffer at once when possible */
     10195        if (in != out) { /* can not handle inline */
     10196            XMEMCPY(out, tmp, AES_BLOCK_SIZE);
     10197            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0) {
     10198                return ret;
     10199            }
     10200        }
     10201    #endif
    787710202
    787810203        while (blocks > 0) {
     
    788110206            byte buf[AES_BLOCK_SIZE];
    788210207
     10208    #ifdef HAVE_AES_ECB
     10209            if (in == out) { /* check for if inline */
     10210    #endif
    788310211            XMEMCPY(buf, in, AES_BLOCK_SIZE);
    788410212            xorbuf(buf, tmp, AES_BLOCK_SIZE);
    788510213            wc_AesEncryptDirect(aes, out, buf);
     10214    #ifdef HAVE_AES_ECB
     10215            }
     10216    #endif
    788610217            xorbuf(out, tmp, AES_BLOCK_SIZE);
    788710218
    7888             /* multiply by shift left and propogate carry */
     10219            /* multiply by shift left and propagate carry */
    788910220            for (j = 0; j < AES_BLOCK_SIZE; j++) {
    789010221                byte tmpC;
     
    789710228                tmp[0] ^= GF_XTS;
    789810229            }
    7899             carry = 0;
    790010230
    790110231            in  += AES_BLOCK_SIZE;
     
    794210272 * returns 0 on success
    794310273 */
     10274/* Software AES - XTS Decrypt */
    794410275int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
    794510276        const byte* i, word32 iSz)
     
    794910280    Aes *aes, *tweak;
    795010281
    7951     if (xaes == NULL || out == NULL) {
     10282    if (xaes == NULL || out == NULL || in == NULL) {
    795210283        return BAD_FUNC_ARG;
    795310284    }
     
    795710288
    795810289    if (iSz < AES_BLOCK_SIZE) {
    7959         return BAD_FUNC_ARG;
    7960     }
    7961 
    7962     if (in == NULL && sz > 0) {
    796310290        return BAD_FUNC_ARG;
    796410291    }
     
    797010297        byte stl = (sz % AES_BLOCK_SIZE);
    797110298
     10299        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
     10300                                          * key setup passed to decrypt direct*/
     10301
    797210302        wc_AesEncryptDirect(tweak, tmp, i);
    797310303
     
    797810308        }
    797910309
     10310    #ifdef HAVE_AES_ECB
     10311        /* decrypt all of buffer at once when possible */
     10312        if (in != out) { /* can not handle inline */
     10313            XMEMCPY(out, tmp, AES_BLOCK_SIZE);
     10314            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0) {
     10315                return ret;
     10316            }
     10317        }
     10318    #endif
     10319
    798010320        while (blocks > 0) {
    798110321            byte buf[AES_BLOCK_SIZE];
    798210322
     10323    #ifdef HAVE_AES_ECB
     10324            if (in == out) { /* check for if inline */
     10325    #endif
    798310326            XMEMCPY(buf, in, AES_BLOCK_SIZE);
    798410327            xorbuf(buf, tmp, AES_BLOCK_SIZE);
    798510328            wc_AesDecryptDirect(aes, out, buf);
     10329    #ifdef HAVE_AES_ECB
     10330            }
     10331    #endif
    798610332            xorbuf(out, tmp, AES_BLOCK_SIZE);
    798710333
    7988             /* multiply by shift left and propogate carry */
     10334            /* multiply by shift left and propagate carry */
    798910335            for (j = 0; j < AES_BLOCK_SIZE; j++) {
    799010336                byte tmpC;
     
    801010356            byte tmp2[AES_BLOCK_SIZE];
    801110357
    8012             /* multiply by shift left and propogate carry */
     10358            /* multiply by shift left and propagate carry */
    801310359            for (j = 0; j < AES_BLOCK_SIZE; j++) {
    801410360                byte tmpC;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/arc4.c

    r352 r372  
    7171
    7272
    73 static INLINE byte MakeByte(word32* x, word32* y, byte* s)
     73static WC_INLINE byte MakeByte(word32* x, word32* y, byte* s)
    7474{
    7575    word32 a = s[*x], b;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/asn.c

    r352 r372  
    3535 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
    3636 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
     37 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
     38    restore 3.13.0 behavior.
    3739 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
    3840    must still be trusted)
     
    4547 * WOLFSSL_ALT_CERT_CHAINS: Allows matching multiple CA's to validate
    4648    chain based on issuer and public key (includes signature confirmation)
     49 * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
     50    DecodedCert. Doubles up on some code but allows smaller dynamic memory
     51    usage.
    4752*/
    4853
    4954#ifndef NO_ASN
    50 
    51 #ifdef HAVE_RTP_SYS
    52     #include "os.h"           /* dc_rtc_api needs    */
    53     #include "dc_rtc_api.h"   /* to get current time */
    54 #endif
    5555
    5656#include <wolfssl/wolfcrypt/asn.h>
     
    6161#include <wolfssl/wolfcrypt/pwdbased.h>
    6262#include <wolfssl/wolfcrypt/des3.h>
     63#include <wolfssl/wolfcrypt/aes.h>
     64#include <wolfssl/wolfcrypt/wc_encrypt.h>
    6365#include <wolfssl/wolfcrypt/logging.h>
    6466
     
    7274#endif
    7375
     76#ifndef NO_PWDBASED
     77    #include <wolfssl/wolfcrypt/aes.h>
     78#endif
    7479#ifndef NO_RC4
    7580    #include <wolfssl/wolfcrypt/arc4.h>
     
    112117#endif
    113118
     119
    114120#ifdef _MSC_VER
    115121    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
     
    119125#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
    120126
    121 #ifndef NO_ASN_TIME
    122 #if defined(USER_TIME)
    123     /* Use our gmtime and time_t/struct tm types.
    124        Only needs seconds since EPOCH using XTIME function.
    125        time_t XTIME(time_t * timer) {}
    126     */
    127     #define WOLFSSL_GMTIME
    128     #define USE_WOLF_TM
    129     #define USE_WOLF_TIME_T
    130 
    131 #elif defined(TIME_OVERRIDES)
    132     /* Override XTIME() and XGMTIME() functionality.
    133        Requires user to provide these functions:
    134         time_t XTIME(time_t * timer) {}
    135         struct tm* XGMTIME(const time_t* timer, struct tm* tmp) {}
    136     */
    137     #ifndef HAVE_TIME_T_TYPE
    138         #define USE_WOLF_TIME_T
    139     #endif
    140     #ifndef HAVE_TM_TYPE
    141         #define USE_WOLF_TM
    142     #endif
    143     #define NEED_TMP_TIME
    144 
    145 #elif defined(HAVE_RTP_SYS)
    146     /* uses parital <time.h> structures */
    147     #define XTIME(tl)       (0)
    148     #define XGMTIME(c, t)   rtpsys_gmtime((c))
    149 
    150 #elif defined(MICRIUM)
    151     #include <clk.h>
    152     #include <time.h>
    153     #define XTIME(t1)       micrium_time((t1))
    154     #define WOLFSSL_GMTIME
    155 
    156 #elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
    157     #include <time.h>
    158     #define XTIME(t1)       pic32_time((t1))
    159     #define XGMTIME(c, t)   gmtime((c))
    160 
    161 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    162     #define XTIME(t1)       mqx_time((t1))
    163     #define HAVE_GMTIME_R
    164 
    165 #elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || \
    166         defined(FREESCALE_KSDK_FREERTOS)
    167     #include <time.h>
    168     #ifndef XTIME
    169         /*extern time_t ksdk_time(time_t* timer);*/
    170         #define XTIME(t1)   ksdk_time((t1))
    171     #endif
    172     #define XGMTIME(c, t)   gmtime((c))
    173 
    174 #elif defined(WOLFSSL_ATMEL)
    175     #define XTIME(t1)       atmel_get_curr_time_and_date((t1))
    176     #define WOLFSSL_GMTIME
    177     #define USE_WOLF_TM
    178     #define USE_WOLF_TIME_T
    179 
    180 #elif defined(IDIRECT_DEV_TIME)
    181     /*Gets the timestamp from cloak software owned by VT iDirect
    182     in place of time() from <time.h> */
    183     #include <time.h>
    184     #define XTIME(t1)       idirect_time((t1))
    185     #define XGMTIME(c, t)   gmtime((c))
    186 
    187 #elif defined(_WIN32_WCE)
    188     #include <windows.h>
    189     #define XTIME(t1)       windows_time((t1))
    190     #define WOLFSSL_GMTIME
    191 #else
    192 
    193     /* default */
    194     /* uses complete <time.h> facility */
    195     #include <time.h>
    196 #endif
    197 
    198 
    199 /* Map default time functions */
    200 #if !defined(XTIME) && !defined(TIME_OVERRIDES) && !defined(USER_TIME)
    201     #define XTIME(tl)       time((tl))
    202 #endif
    203 #if !defined(XGMTIME) && !defined(TIME_OVERRIDES)
    204     #if defined(WOLFSSL_GMTIME) || !defined(HAVE_GMTIME_R)
    205         #define XGMTIME(c, t)   gmtime((c))
    206     #else
    207         #define XGMTIME(c, t)   gmtime_r((c), (t))
    208         #define NEED_TMP_TIME
    209     #endif
    210 #endif
    211 #if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE)
    212     #define USE_WOLF_VALIDDATE
    213     #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
    214 #endif
    215 
    216 /* wolf struct tm and time_t */
    217 #if defined(USE_WOLF_TM)
    218     struct tm {
    219         int  tm_sec;     /* seconds after the minute [0-60] */
    220         int  tm_min;     /* minutes after the hour [0-59] */
    221         int  tm_hour;    /* hours since midnight [0-23] */
    222         int  tm_mday;    /* day of the month [1-31] */
    223         int  tm_mon;     /* months since January [0-11] */
    224         int  tm_year;    /* years since 1900 */
    225         int  tm_wday;    /* days since Sunday [0-6] */
    226         int  tm_yday;    /* days since January 1 [0-365] */
    227         int  tm_isdst;   /* Daylight Savings Time flag */
    228         long tm_gmtoff;  /* offset from CUT in seconds */
    229         char *tm_zone;   /* timezone abbreviation */
     127#ifdef HAVE_SELFTEST
     128    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
     129    enum Asn_Misc {
     130        AES_IV_SIZE         = 16,
     131        AES_128_KEY_SIZE    = 16,
     132        AES_192_KEY_SIZE    = 24,
     133        AES_256_KEY_SIZE    = 32
    230134    };
    231 #endif /* USE_WOLF_TM */
    232 #if defined(USE_WOLF_TIME_T)
    233     typedef long time_t;
    234 #endif
    235 
    236 /* forward declarations */
    237 #if defined(USER_TIME)
    238     struct tm* gmtime(const time_t* timer);
    239     extern time_t XTIME(time_t * timer);
    240 
    241     #ifdef STACK_TRAP
    242         /* for stack trap tracking, don't call os gmtime on OS X/linux,
    243            uses a lot of stack spce */
    244         extern time_t time(time_t * timer);
    245         #define XTIME(tl)  time((tl))
    246     #endif /* STACK_TRAP */
    247 
    248 #elif defined(TIME_OVERRIDES)
    249     extern time_t XTIME(time_t * timer);
    250     extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);
    251 #elif defined(WOLFSSL_GMTIME)
    252     struct tm* gmtime(const time_t* timer);
    253 #endif
    254 
    255 
    256 #if defined(_WIN32_WCE)
    257 time_t windows_time(time_t* timer)
    258 {
    259     SYSTEMTIME     sysTime;
    260     FILETIME       fTime;
    261     ULARGE_INTEGER intTime;
    262     time_t         localTime;
    263 
    264     if (timer == NULL)
    265         timer = &localTime;
    266 
    267     GetSystemTime(&sysTime);
    268     SystemTimeToFileTime(&sysTime, &fTime);
    269 
    270     XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
    271     /* subtract EPOCH */
    272     intTime.QuadPart -= 0x19db1ded53e8000;
    273     /* to secs */
    274     intTime.QuadPart /= 10000000;
    275     *timer = (time_t)intTime.QuadPart;
    276 
    277     return *timer;
    278 }
    279 #endif /*  _WIN32_WCE */
    280 
    281 #if defined(WOLFSSL_GMTIME)
    282 struct tm* gmtime(const time_t* timer)
    283 {
    284     #define YEAR0          1900
    285     #define EPOCH_YEAR     1970
    286     #define SECS_DAY       (24L * 60L * 60L)
    287     #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
    288     #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
    289 
    290     static const int _ytab[2][12] =
    291     {
    292         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    293         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    294     };
    295 
    296     static struct tm st_time;
    297     struct tm* ret = &st_time;
    298     time_t secs = *timer;
    299     unsigned long dayclock, dayno;
    300     int year = EPOCH_YEAR;
    301 
    302     dayclock = (unsigned long)secs % SECS_DAY;
    303     dayno    = (unsigned long)secs / SECS_DAY;
    304 
    305     ret->tm_sec  = (int) dayclock % 60;
    306     ret->tm_min  = (int)(dayclock % 3600) / 60;
    307     ret->tm_hour = (int) dayclock / 3600;
    308     ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
    309 
    310     while(dayno >= (unsigned long)YEARSIZE(year)) {
    311         dayno -= YEARSIZE(year);
    312         year++;
    313     }
    314 
    315     ret->tm_year = year - YEAR0;
    316     ret->tm_yday = (int)dayno;
    317     ret->tm_mon  = 0;
    318 
    319     while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
    320         dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
    321         ret->tm_mon++;
    322     }
    323 
    324     ret->tm_mday  = (int)++dayno;
    325     ret->tm_isdst = 0;
    326 
    327     return ret;
    328 }
    329 #endif /* WOLFSSL_GMTIME */
    330 
    331 
    332 #if defined(HAVE_RTP_SYS)
    333 #define YEAR0          1900
    334 
    335 struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
    336 {
    337     static struct tm st_time;
    338     struct tm* ret = &st_time;
    339 
    340     DC_RTC_CALENDAR cal;
    341     dc_rtc_time_get(&cal, TRUE);
    342 
    343     ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
    344     ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
    345     ret->tm_mday  = cal.day;
    346     ret->tm_hour  = cal.hour;
    347     ret->tm_min   = cal.minute;
    348     ret->tm_sec   = cal.second;
    349 
    350     return ret;
    351 }
    352 
    353 #endif /* HAVE_RTP_SYS */
    354 
    355 
    356 #if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
    357 
    358 /*
    359  * time() is just a stub in Microchip libraries. We need our own
    360  * implementation. Use SNTP client to get seconds since epoch.
    361  */
    362 time_t pic32_time(time_t* timer)
    363 {
    364 #ifdef MICROCHIP_TCPIP_V5
    365     DWORD sec = 0;
    366 #else
    367     uint32_t sec = 0;
    368 #endif
    369     time_t localTime;
    370 
    371     if (timer == NULL)
    372         timer = &localTime;
    373 
    374 #ifdef MICROCHIP_MPLAB_HARMONY
    375     sec = TCPIP_SNTP_UTCSecondsGet();
    376 #else
    377     sec = SNTPGetUTCSeconds();
    378 #endif
    379     *timer = (time_t) sec;
    380 
    381     return *timer;
    382 }
    383 
    384 #endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
    385 
    386 
    387 #if defined(MICRIUM)
    388 
    389 time_t micrium_time(time_t* timer)
    390 {
    391     CLK_TS_SEC sec;
    392 
    393     Clk_GetTS_Unix(&sec);
    394 
    395     return (time_t) sec;
    396 }
    397 
    398 #endif /* MICRIUM */
    399 
    400 
    401 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    402 
    403 time_t mqx_time(time_t* timer)
    404 {
    405     time_t localTime;
    406     TIME_STRUCT time_s;
    407 
    408     if (timer == NULL)
    409         timer = &localTime;
    410 
    411     _time_get(&time_s);
    412     *timer = (time_t) time_s.SECONDS;
    413 
    414     return *timer;
    415 }
    416 
    417 #endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
    418 
    419 
    420 #if defined(WOLFSSL_TIRTOS)
    421 
    422 time_t XTIME(time_t * timer)
    423 {
    424     time_t sec = 0;
    425 
    426     sec = (time_t) Seconds_get();
    427 
    428     if (timer != NULL)
    429         *timer = sec;
    430 
    431     return sec;
    432 }
    433 
    434 #endif /* WOLFSSL_TIRTOS */
    435 
    436 
    437 #if defined(WOLFSSL_XILINX)
    438 #include "xrtcpsu.h"
    439 
    440 time_t XTIME(time_t * timer)
    441 {
    442     time_t sec = 0;
    443     XRtcPsu_Config* con;
    444     XRtcPsu         rtc;
    445 
    446     con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
    447     if (con != NULL) {
    448         if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {
    449             sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);
    450         }
    451         else {
    452             WOLFSSL_MSG("Unable to initialize RTC");
    453         }
    454     }
    455 
    456     if (timer != NULL)
    457         *timer = sec;
    458 
    459     return sec;
    460 }
    461 
    462 #endif /* WOLFSSL_TIRTOS */
    463 
    464 
    465 /* two byte date/time, add to value */
    466 static INLINE void GetTime(int* value, const byte* date, int* idx)
    467 {
    468     int i = *idx;
    469 
    470     *value += btoi(date[i++]) * 10;
    471     *value += btoi(date[i++]);
    472 
    473     *idx = i;
    474 }
    475 
    476 
    477 #if defined(IDIRECT_DEV_TIME)
    478 
    479 extern time_t getTimestamp();
    480 
    481 time_t idirect_time(time_t * timer)
    482 {
    483     time_t sec = getTimestamp();
    484 
    485     if (timer != NULL)
    486         *timer = sec;
    487 
    488     return sec;
    489 }
    490 
    491 #endif /* IDIRECT_DEV_TIME */
    492 
    493 #endif /* !NO_ASN_TIME */
    494 
     135#endif
     136#endif
    495137
    496138WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
    497139                           word32 maxIdx)
     140{
     141    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
     142}
     143
     144
     145/* give option to check length value found against index. 1 to check 0 to not */
     146WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
     147                           word32 maxIdx, int check)
    498148{
    499149    int     length = 0;
     
    525175        length = b;
    526176
    527     if ((idx + length) > maxIdx) {   /* for user of length */
     177    if (check && (idx + length) > maxIdx) {   /* for user of length */
    528178        WOLFSSL_MSG("GetLength value exceeds buffer length");
    529179        return BUFFER_E;
     
    534184        *len = length;
    535185
     186    return length;
     187}
     188
     189
     190static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len,
     191                        word32 maxIdx, int check)
     192{
     193    word32 idx = *inOutIdx;
     194    byte   b;
     195    int    length;
     196
     197    if ((idx + 1) > maxIdx)
     198        return BUFFER_E;
     199
     200    b = input[idx++];
     201    if (b != tag)
     202        return ASN_PARSE_E;
     203
     204    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
     205        return ASN_PARSE_E;
     206
     207    *len      = length;
     208    *inOutIdx = idx;
    536209    return length;
    537210}
     
    552225                        word32 maxIdx)
    553226{
    554     word32 idx = *inOutIdx;
    555     byte   b;
    556     int    length;
    557 
    558     if ((idx + 1) > maxIdx)
    559         return BUFFER_E;
    560 
    561     b = input[idx++];
    562     if (b != tag)
    563         return ASN_PARSE_E;
    564 
    565     if (GetLength(input, &idx, &length, maxIdx) < 0)
    566         return ASN_PARSE_E;
    567 
    568     *len      = length;
    569     *inOutIdx = idx;
    570     return length;
    571 }
     227    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
     228}
     229
    572230
    573231WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
     
    576234    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
    577235                        maxIdx);
     236}
     237
     238
     239WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
     240                           word32 maxIdx, int check)
     241{
     242    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
     243                        maxIdx, check);
    578244}
    579245
     
    724390                return ASN_PARSE_E;
    725391        }
    726         else if ((input[*inOutIdx] & 0x80) == 0x80)
    727             return ASN_PARSE_E;
    728392    }
    729393
     
    759423}
    760424
     425
     426#if !defined(NO_DSA) && !defined(NO_SHA)
     427static char sigSha1wDsaName[] = "SHAwDSA";
     428#endif /* NO_DSA */
     429#ifndef NO_RSA
     430#ifdef WOLFSSL_MD2
     431    static char sigMd2wRsaName[] = "MD2wRSA";
     432#endif
     433#ifndef NO_MD5
     434    static char sigMd5wRsaName[] = "MD5wRSA";
     435#endif
     436#ifndef NO_SHA
     437    static char sigSha1wRsaName[] = "SHAwRSA";
     438#endif
     439#ifdef WOLFSSL_SHA224
     440    static char sigSha224wRsaName[] = "SHA224wRSA";
     441#endif
     442#ifndef NO_SHA256
     443    static char sigSha256wRsaName[] = "SHA256wRSA";
     444#endif
     445#ifdef WOLFSSL_SHA384
     446    static char sigSha384wRsaName[] = "SHA384wRSA";
     447#endif
     448#ifdef WOLFSSL_SHA512
     449    static char sigSha512wRsaName[] = "SHA512wRSA";
     450#endif
     451#endif /* NO_RSA */
     452#ifdef HAVE_ECC
     453#ifndef NO_SHA
     454    static char sigSha1wEcdsaName[] = "SHAwECDSA";
     455#endif
     456#ifdef WOLFSSL_SHA224
     457    static char sigSha224wEcdsaName[] = "SHA224wECDSA";
     458#endif
     459#ifndef NO_SHA256
     460    static char sigSha256wEcdsaName[] = "SHA256wECDSA";
     461#endif
     462#ifdef WOLFSSL_SHA384
     463    static char sigSha384wEcdsaName[] = "SHA384wECDSA";
     464#endif
     465#ifdef WOLFSSL_SHA512
     466    static char sigSha512wEcdsaName[] = "SHA512wECDSA";
     467#endif
     468#endif /* HAVE_ECC */
     469static char sigUnknownName[] = "Unknown";
     470
     471
     472/* Get the human readable string for a signature type
     473 *
     474 * oid  Oid value for signature
     475 */
     476char* GetSigName(int oid) {
     477    switch (oid) {
     478    #if !defined(NO_DSA) && !defined(NO_SHA)
     479        case CTC_SHAwDSA:
     480            return sigSha1wDsaName;
     481    #endif /* NO_DSA && NO_SHA */
     482    #ifndef NO_RSA
     483        #ifdef WOLFSSL_MD2
     484        case CTC_MD2wRSA:
     485            return sigMd2wRsaName;
     486        #endif
     487        #ifndef NO_MD5
     488        case CTC_MD5wRSA:
     489            return sigMd5wRsaName;
     490        #endif
     491        #ifndef NO_SHA
     492        case CTC_SHAwRSA:
     493            return sigSha1wRsaName;
     494        #endif
     495        #ifdef WOLFSSL_SHA224
     496        case CTC_SHA224wRSA:
     497            return sigSha224wRsaName;
     498        #endif
     499        #ifndef NO_SHA256
     500        case CTC_SHA256wRSA:
     501            return sigSha256wRsaName;
     502        #endif
     503        #ifdef WOLFSSL_SHA384
     504        case CTC_SHA384wRSA:
     505            return sigSha384wRsaName;
     506        #endif
     507        #ifdef WOLFSSL_SHA512
     508        case CTC_SHA512wRSA:
     509            return sigSha512wRsaName;
     510        #endif
     511    #endif /* NO_RSA */
     512    #ifdef HAVE_ECC
     513        #ifndef NO_SHA
     514        case CTC_SHAwECDSA:
     515            return sigSha1wEcdsaName;
     516        #endif
     517        #ifdef WOLFSSL_SHA224
     518        case CTC_SHA224wECDSA:
     519            return sigSha224wEcdsaName;
     520        #endif
     521        #ifndef NO_SHA256
     522        case CTC_SHA256wECDSA:
     523            return sigSha256wEcdsaName;
     524        #endif
     525        #ifdef WOLFSSL_SHA384
     526        case CTC_SHA384wECDSA:
     527            return sigSha384wEcdsaName;
     528        #endif
     529        #ifdef WOLFSSL_SHA512
     530        case CTC_SHA512wECDSA:
     531            return sigSha512wEcdsaName;
     532        #endif
     533    #endif /* HAVE_ECC */
     534        default:
     535            return sigUnknownName;
     536    }
     537}
     538
     539
    761540#if !defined(NO_DSA) || defined(HAVE_ECC) || \
    762541   (!defined(NO_RSA) && \
    763542        (defined(WOLFSSL_CERT_GEN) || \
    764         (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA))))
     543        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
    765544/* Set the DER/BER encoding of the ASN.1 INTEGER header.
    766545 *
     
    786565
    787566#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \
    788     (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
     567    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
    789568/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
    790569 * The number is assumed to be positive.
     
    906685    return *number;
    907686}
     687
     688
     689/* Set small integer, 32 bits or less. DER encoding with no leading 0s
     690 * returns total amount written including ASN tag and length byte on success */
     691static int SetShortInt(byte* input, word32* inOutIdx, word32 number,
     692                              word32 maxIdx)
     693{
     694    word32 idx = *inOutIdx;
     695    word32 len = 0;
     696    int    i;
     697    byte ar[MAX_LENGTH_SZ];
     698
     699    /* check for room for type and length bytes */
     700    if ((idx + 2) > maxIdx)
     701        return BUFFER_E;
     702
     703    input[idx++] = ASN_INTEGER;
     704    idx++; /* place holder for length byte */
     705    if (MAX_LENGTH_SZ + idx > maxIdx)
     706        return ASN_PARSE_E;
     707
     708    /* find first non zero byte */
     709    XMEMSET(ar, 0, MAX_LENGTH_SZ);
     710    c32toa(number, ar);
     711    for (i = 0; i < MAX_LENGTH_SZ; i++) {
     712        if (ar[i] != 0) {
     713            break;
     714        }
     715    }
     716
     717    /* handle case of 0 */
     718    if (i == MAX_LENGTH_SZ) {
     719        input[idx++] = 0; len++;
     720    }
     721
     722    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
     723        input[idx++] = ar[i]; len++;
     724    }
     725
     726    /* jump back to beginning of input buffer using unaltered inOutIdx value
     727     * and set number of bytes for integer, then update the index value */
     728    input[*inOutIdx + 1] = (byte)len;
     729    *inOutIdx = idx;
     730
     731    return len + 2; /* size of integer bytes plus ASN TAG and length byte */
     732}
    908733#endif /* !NO_PWDBASED */
    909734
     
    959784    return 0;
    960785}
     786
     787#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
     788    || defined(WOLFSSL_RSA_PUBLIC_ONLY)
     789#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
     790static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
     791{
     792    word32 idx = *inOutIdx;
     793    int    ret;
     794    int    length;
     795
     796    ret = GetASNInt(input, &idx, &length, maxIdx);
     797    if (ret != 0)
     798        return ret;
     799
     800    *inOutIdx = idx + length;
     801
     802    return 0;
     803}
     804#endif
     805#endif
    961806
    962807static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
     
    1008853}
    1009854
    1010 #if (!defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
    1011                           (defined(WOLFSSL_KEY_GEN) && \
    1012                            !defined(HAVE_USER_RSA)))) || \
    1013     (defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || \
    1014                            defined(WOLFSSL_KEY_GEN)))
     855/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */
     856#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
     857        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
     858    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
     859    (defined(HAVE_ED25519) && \
     860        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
     861
    1015862/* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
    1016863 *
     
    1032879    return idx;
    1033880}
     881#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
     882
     883#ifdef ASN_BER_TO_DER
     884/* Convert a BER encoding with indefinite length items to DER.
     885 *
     886 * ber    BER encoded data.
     887 * berSz  Length of BER encoded data.
     888 * der    Buffer to hold DER encoded version of data.
     889 *        NULL indicates only the length is required.
     890 * derSz  The size of the buffer to hold the DER encoded data.
     891 *        Will be set if der is NULL, otherwise the value is checked as der is
     892 *        filled.
     893 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
     894 * derSz are NULL.
     895 */
     896int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
     897{
     898    int ret;
     899    word32 i, j, k;
     900    int len, l;
     901    int indef;
     902    int depth = 0;
     903    byte type;
     904    word32 cnt, sz;
     905    word32 outSz = 0;
     906    byte lenBytes[4];
     907
     908    if (ber == NULL || derSz == NULL)
     909        return BAD_FUNC_ARG;
     910
     911    sz = 0;
     912    outSz = *derSz;
     913
     914    for (i = 0, j = 0; i < berSz; ) {
     915        /* Check that there is data for an ASN item to parse. */
     916        if (i + 2 > berSz)
     917            return ASN_PARSE_E;
     918
     919        /* End Of Content (EOC) mark end of indefinite length items.
     920         * EOCs are not encoded in DER.
     921         * Keep track of no. indefinite length items that have not been
     922         * terminated in depth.
     923         */
     924        if (ber[i] == 0 && ber[i+1] == 0) {
     925            if (depth == 0)
     926                break;
     927            if (--depth == 0)
     928                break;
     929
     930            i += 2;
     931            continue;
     932        }
     933
     934        /* Indefinite length is encoded as: 0x80 */
     935        type = ber[i];
     936        indef = ber[i+1] == ASN_INDEF_LENGTH;
     937        if (indef && (type & 0xC0) == 0 &&
     938                                   ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
     939                                   ber[i] != (ASN_SET      | ASN_CONSTRUCTED)) {
     940            /* Indefinite length OCTET STRING or other simple type.
     941             * Put all the data into one entry.
     942             */
     943
     944            /* Type no longer constructed. */
     945            type &= ~ASN_CONSTRUCTED;
     946            if (der != NULL) {
     947                /* Ensure space for type. */
     948                if (j + 1 >= outSz)
     949                    return BUFFER_E;
     950                der[j] = type;
     951            }
     952            i++; j++;
     953            /* Skip indefinite length. */
     954            i++;
     955
     956            /* There must be further ASN1 items to combine. */
     957            if (i + 2 > berSz)
     958                return ASN_PARSE_E;
     959
     960            /* Calculate length of combined data. */
     961            len = 0;
     962            k = i;
     963            while (ber[k] != 0x00) {
     964                /* Each ASN item must be the same type as the constructed. */
     965                if (ber[k] != type)
     966                    return ASN_PARSE_E;
     967                k++;
     968
     969                ret = GetLength(ber, &k, &l, berSz);
     970                if (ret < 0)
     971                    return ASN_PARSE_E;
     972                k += l;
     973                len += l;
     974
     975                /* Must at least have terminating EOC. */
     976                if (k + 2 > berSz)
     977                    return ASN_PARSE_E;
     978            }
     979            /* Ensure a valid EOC ASN item. */
     980            if (ber[k+1] != 0x00)
     981                return ASN_PARSE_E;
     982
     983            if (der == NULL) {
     984                /* Add length of ASN item length encoding and data. */
     985                j += SetLength(len, lenBytes);
     986                j += len;
     987            }
     988            else {
     989                /* Check space for encoded length. */
     990                if (SetLength(len, lenBytes) > outSz - j)
     991                    return BUFFER_E;
     992                /* Encode new length. */
     993                j += SetLength(len, der + j);
     994
     995                /* Encode data in single item. */
     996                k = i;
     997                while (ber[k] != 0x00) {
     998                    /* Skip ASN type. */
     999                    k++;
     1000
     1001                    /* Find length of data in ASN item. */
     1002                    ret = GetLength(ber, &k, &l, berSz);
     1003                    if (ret < 0)
     1004                        return ASN_PARSE_E;
     1005
     1006                    /* Ensure space for data and copy in. */
     1007                    if (j + l > outSz)
     1008                        return BUFFER_E;
     1009                    XMEMCPY(der + j, ber + k, l);
     1010                    k += l; j += l;
     1011                }
     1012            }
     1013            /* Continue conversion after EOC. */
     1014            i = k + 2;
     1015
     1016            continue;
     1017        }
     1018
     1019        if (der != NULL) {
     1020            /* Ensure space for type and at least one byte of length. */
     1021            if (j + 1 >= outSz)
     1022                return BUFFER_E;
     1023            /* Put in type. */
     1024            der[j] = ber[i];
     1025        }
     1026        i++; j++;
     1027
     1028        if (indef) {
     1029            /* Skip indefinite length. */
     1030            i++;
     1031            /* Calculate the size of the data inside constructed. */
     1032            ret = wc_BerToDer(ber + i, berSz - i, NULL, &sz);
     1033            if (ret != LENGTH_ONLY_E)
     1034                return ret;
     1035
     1036            if (der != NULL) {
     1037                /* Ensure space for encoded length. */
     1038                if (SetLength(sz, lenBytes) > outSz - j)
     1039                    return BUFFER_E;
     1040                /* Encode real length. */
     1041                j += SetLength(sz, der + j);
     1042            }
     1043            else {
     1044                /* Add size of encoded length. */
     1045                j += SetLength(sz, lenBytes);
     1046            }
     1047
     1048            /* Another EOC to find. */
     1049            depth++;
     1050        }
     1051        else {
     1052            /* Get the size of the encode length and length value. */
     1053            cnt = i;
     1054            ret = GetLength(ber, &cnt, &len, berSz);
     1055            if (ret < 0)
     1056                return ASN_PARSE_E;
     1057            cnt -= i;
     1058
     1059            /* Check there is enough data to copy out. */
     1060            if (i + cnt + len > berSz)
     1061                return ASN_PARSE_E;
     1062
     1063            if (der != NULL) {
     1064                /* Ensure space in DER buffer. */
     1065                if (j + cnt + len > outSz)
     1066                    return BUFFER_E;
     1067                /* Copy length and data into DER buffer. */
     1068                XMEMCPY(der + j, ber + i, cnt + len);
     1069            }
     1070            /* Continue conversion after this ASN item. */
     1071            i += cnt + len;
     1072            j += cnt + len;
     1073        }
     1074    }
     1075
     1076    if (depth >= 1)
     1077        return ASN_PARSE_E;
     1078
     1079    /* Return length if no buffer to write to. */
     1080    if (der == NULL) {
     1081        *derSz = j;
     1082        return LENGTH_ONLY_E;
     1083    }
     1084
     1085    return 0;
     1086}
     1087#endif
     1088
     1089#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)
     1090
     1091#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \
     1092    defined(HAVE_ECC) || defined(HAVE_ED25519)
    10341093
    10351094#ifdef WOLFSSL_CERT_EXT
     
    10671126}
    10681127#endif /* WOLFSSL_CERT_EXT */
    1069 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
    1070                                            !HAVE_USER_RSA)) */
     1128#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
     1129#endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */
    10711130
    10721131
    10731132
    10741133/* hashType */
     1134#ifdef WOLFSSL_MD2
    10751135static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
     1136#endif
     1137#ifndef NO_MD5
    10761138static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
     1139#endif
     1140#ifndef NO_SHA
    10771141static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
     1142#endif
     1143#ifdef WOLFSSL_SHA224
    10781144static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
     1145#endif
     1146#ifndef NO_SHA256
    10791147static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
     1148#endif
     1149#ifdef WOLFSSL_SHA384
    10801150static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
     1151#endif
     1152#ifdef WOLFSSL_SHA512
    10811153static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
     1154#endif
     1155
     1156/* hmacType */
     1157#ifndef NO_HMAC
     1158    #ifdef WOLFSSL_SHA224
     1159    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
     1160    #endif
     1161    #ifndef NO_SHA256
     1162    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
     1163    #endif
     1164    #ifdef WOLFSSL_SHA384
     1165    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
     1166    #endif
     1167    #ifdef WOLFSSL_SHA512
     1168    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
     1169    #endif
     1170#endif
    10821171
    10831172/* sigType */
    1084 #ifndef NO_DSA
     1173#if !defined(NO_DSA) && !defined(NO_SHA)
    10851174    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
    10861175#endif /* NO_DSA */
    10871176#ifndef NO_RSA
     1177    #ifdef WOLFSSL_MD2
    10881178    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
     1179    #endif
     1180    #ifndef NO_MD5
    10891181    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
     1182    #endif
     1183    #ifndef NO_SHA
    10901184    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
     1185    #endif
     1186    #ifdef WOLFSSL_SHA224
    10911187    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
     1188    #endif
     1189    #ifndef NO_SHA256
    10921190    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
     1191    #endif
     1192    #ifdef WOLFSSL_SHA384
    10931193    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
     1194    #endif
     1195    #ifdef WOLFSSL_SHA512
    10941196    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
     1197    #endif
    10951198#endif /* NO_RSA */
    10961199#ifdef HAVE_ECC
     1200    #ifndef NO_SHA
    10971201    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
     1202    #endif
     1203    #ifdef WOLFSSL_SHA224
    10981204    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
     1205    #endif
     1206    #ifndef NO_SHA256
    10991207    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
     1208    #endif
     1209    #ifdef WOLFSSL_SHA384
    11001210    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
     1211    #endif
     1212    #ifdef WOLFSSL_SHA512
    11011213    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
     1214    #endif
    11021215#endif /* HAVE_ECC */
    11031216#ifdef HAVE_ED25519
     
    11271240#endif /* HAVE_ECC */
    11281241
     1242#ifdef HAVE_AES_CBC
    11291243/* blkType */
     1244    #ifdef WOLFSSL_AES_128
    11301245static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
     1246    #endif
     1247    #ifdef WOLFSSL_AES_192
    11311248static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
     1249    #endif
     1250    #ifdef WOLFSSL_AES_256
    11321251static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
     1252    #endif
     1253#endif /* HAVE_AES_CBC */
     1254#ifdef HAVE_AESGCM
     1255    #ifdef WOLFSSL_AES_128
     1256    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
     1257    #endif
     1258    #ifdef WOLFSSL_AES_192
     1259    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
     1260    #endif
     1261    #ifdef WOLFSSL_AES_256
     1262    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
     1263    #endif
     1264#endif /* HAVE_AESGCM */
     1265#ifdef HAVE_AESCCM
     1266    #ifdef WOLFSSL_AES_128
     1267    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
     1268    #endif
     1269    #ifdef WOLFSSL_AES_192
     1270    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
     1271    #endif
     1272    #ifdef WOLFSSL_AES_256
     1273    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
     1274    #endif
     1275#endif /* HAVE_AESCCM */
     1276
     1277#ifndef NO_DES3
    11331278static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
    11341279static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
     1280#endif
    11351281
    11361282/* keyWrapType */
     1283#ifdef WOLFSSL_AES_128
    11371284static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
     1285#endif
     1286#ifdef WOLFSSL_AES_192
    11381287static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
     1288#endif
     1289#ifdef WOLFSSL_AES_256
    11391290static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
     1291#endif
     1292#ifdef HAVE_PKCS7
     1293/* From RFC 3211 */
     1294static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
     1295#endif
    11401296
    11411297/* cmsKeyAgreeType */
     1298#ifndef NO_SHA
    11421299static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
    11431300                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
     1301#endif
     1302#ifdef WOLFSSL_SHA224
    11441303static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
     1304#endif
     1305#ifndef NO_SHA256
    11451306static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
     1307#endif
     1308#ifdef WOLFSSL_SHA384
    11461309static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
     1310#endif
     1311#ifdef WOLFSSL_SHA512
    11471312static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
     1313#endif
    11481314
    11491315/* ocspType */
     
    11641330static const byte extInhibitAnyOid[] = {85, 29, 54};
    11651331static const byte extExtKeyUsageOid[] = {85, 29, 37};
     1332#ifndef IGNORE_NAME_CONSTRAINTS
    11661333static const byte extNameConsOid[] = {85, 29, 30};
     1334#endif
    11671335
    11681336/* certAuthInfoType */
     1337#ifdef HAVE_OCSP
    11691338static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
     1339#endif
    11701340static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
    11711341
     
    11881358static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
    11891359
    1190 static const byte* OidFromId(word32 id, word32 type, word32* oidSz)
     1360/* PKCS5 */
     1361#if !defined(NO_DES3) && !defined(NO_SHA)
     1362static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
     1363#endif
     1364static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
     1365
     1366/* PKCS12 */
     1367#if !defined(NO_RC4) && !defined(NO_SHA)
     1368static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
     1369#endif
     1370#if !defined(NO_DES3) && !defined(NO_SHA)
     1371static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
     1372#endif
     1373
     1374#ifdef HAVE_LIBZ
     1375/* zlib compression */
     1376static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
     1377#endif
     1378
     1379
     1380/* returns a pointer to the OID string on success and NULL on fail */
     1381const byte* OidFromId(word32 id, word32 type, word32* oidSz)
    11911382{
    11921383    const byte* oid = NULL;
     
    11981389        case oidHashType:
    11991390            switch (id) {
     1391            #ifdef WOLFSSL_MD2
    12001392                case MD2h:
    12011393                    oid = hashMd2hOid;
    12021394                    *oidSz = sizeof(hashMd2hOid);
    12031395                    break;
     1396            #endif
     1397            #ifndef NO_MD5
    12041398                case MD5h:
    12051399                    oid = hashMd5hOid;
    12061400                    *oidSz = sizeof(hashMd5hOid);
    12071401                    break;
     1402            #endif
     1403            #ifndef NO_SHA
    12081404                case SHAh:
    12091405                    oid = hashSha1hOid;
    12101406                    *oidSz = sizeof(hashSha1hOid);
    12111407                    break;
     1408            #endif
     1409            #ifdef WOLFSSL_SHA224
    12121410                case SHA224h:
    12131411                    oid = hashSha224hOid;
    12141412                    *oidSz = sizeof(hashSha224hOid);
    12151413                    break;
     1414            #endif
     1415            #ifndef NO_SHA256
    12161416                case SHA256h:
    12171417                    oid = hashSha256hOid;
    12181418                    *oidSz = sizeof(hashSha256hOid);
    12191419                    break;
     1420            #endif
     1421            #ifdef WOLFSSL_SHA384
    12201422                case SHA384h:
    12211423                    oid = hashSha384hOid;
    12221424                    *oidSz = sizeof(hashSha384hOid);
    12231425                    break;
     1426            #endif
     1427            #ifdef WOLFSSL_SHA512
    12241428                case SHA512h:
    12251429                    oid = hashSha512hOid;
    12261430                    *oidSz = sizeof(hashSha512hOid);
    12271431                    break;
     1432            #endif
    12281433            }
    12291434            break;
     
    12311436        case oidSigType:
    12321437            switch (id) {
    1233                 #ifndef NO_DSA
     1438                #if !defined(NO_DSA) && !defined(NO_SHA)
    12341439                case CTC_SHAwDSA:
    12351440                    oid = sigSha1wDsaOid;
     
    12381443                #endif /* NO_DSA */
    12391444                #ifndef NO_RSA
     1445                #ifdef WOLFSSL_MD2
    12401446                case CTC_MD2wRSA:
    12411447                    oid = sigMd2wRsaOid;
    12421448                    *oidSz = sizeof(sigMd2wRsaOid);
    12431449                    break;
     1450                #endif
     1451                #ifndef NO_MD5
    12441452                case CTC_MD5wRSA:
    12451453                    oid = sigMd5wRsaOid;
    12461454                    *oidSz = sizeof(sigMd5wRsaOid);
    12471455                    break;
     1456                #endif
     1457                #ifndef NO_SHA
    12481458                case CTC_SHAwRSA:
    12491459                    oid = sigSha1wRsaOid;
    12501460                    *oidSz = sizeof(sigSha1wRsaOid);
    12511461                    break;
     1462                #endif
     1463                #ifdef WOLFSSL_SHA224
    12521464                case CTC_SHA224wRSA:
    12531465                    oid = sigSha224wRsaOid;
    12541466                    *oidSz = sizeof(sigSha224wRsaOid);
    12551467                    break;
     1468                #endif
     1469                #ifndef NO_SHA256
    12561470                case CTC_SHA256wRSA:
    12571471                    oid = sigSha256wRsaOid;
    12581472                    *oidSz = sizeof(sigSha256wRsaOid);
    12591473                    break;
     1474                #endif
     1475                #ifdef WOLFSSL_SHA384
    12601476                case CTC_SHA384wRSA:
    12611477                    oid = sigSha384wRsaOid;
    12621478                    *oidSz = sizeof(sigSha384wRsaOid);
    12631479                    break;
     1480                #endif
     1481                #ifdef WOLFSSL_SHA512
    12641482                case CTC_SHA512wRSA:
    12651483                    oid = sigSha512wRsaOid;
    12661484                    *oidSz = sizeof(sigSha512wRsaOid);
    12671485                    break;
     1486                #endif /* WOLFSSL_SHA512 */
    12681487                #endif /* NO_RSA */
    12691488                #ifdef HAVE_ECC
     1489                #ifndef NO_SHA
    12701490                case CTC_SHAwECDSA:
    12711491                    oid = sigSha1wEcdsaOid;
    12721492                    *oidSz = sizeof(sigSha1wEcdsaOid);
    12731493                    break;
     1494                #endif
     1495                #ifdef WOLFSSL_SHA224
    12741496                case CTC_SHA224wECDSA:
    12751497                    oid = sigSha224wEcdsaOid;
    12761498                    *oidSz = sizeof(sigSha224wEcdsaOid);
    12771499                    break;
     1500                #endif
     1501                #ifndef NO_SHA256
    12781502                case CTC_SHA256wECDSA:
    12791503                    oid = sigSha256wEcdsaOid;
    12801504                    *oidSz = sizeof(sigSha256wEcdsaOid);
    12811505                    break;
     1506                #endif
     1507                #ifdef WOLFSSL_SHA384
    12821508                case CTC_SHA384wECDSA:
    12831509                    oid = sigSha384wEcdsaOid;
    12841510                    *oidSz = sizeof(sigSha384wEcdsaOid);
    12851511                    break;
     1512                #endif
     1513                #ifdef WOLFSSL_SHA512
    12861514                case CTC_SHA512wECDSA:
    12871515                    oid = sigSha512wEcdsaOid;
    12881516                    *oidSz = sizeof(sigSha512wEcdsaOid);
    12891517                    break;
     1518                #endif
    12901519                #endif /* HAVE_ECC */
    12911520                #ifdef HAVE_ED25519
     
    13471576        case oidBlkType:
    13481577            switch (id) {
     1578    #ifdef HAVE_AES_CBC
     1579        #ifdef WOLFSSL_AES_128
    13491580                case AES128CBCb:
    13501581                    oid = blkAes128CbcOid;
    13511582                    *oidSz = sizeof(blkAes128CbcOid);
    13521583                    break;
     1584        #endif
     1585        #ifdef WOLFSSL_AES_192
    13531586                case AES192CBCb:
    13541587                    oid = blkAes192CbcOid;
    13551588                    *oidSz = sizeof(blkAes192CbcOid);
    13561589                    break;
     1590        #endif
     1591        #ifdef WOLFSSL_AES_256
    13571592                case AES256CBCb:
    13581593                    oid = blkAes256CbcOid;
    13591594                    *oidSz = sizeof(blkAes256CbcOid);
    13601595                    break;
     1596        #endif
     1597    #endif /* HAVE_AES_CBC */
     1598    #ifdef HAVE_AESGCM
     1599        #ifdef WOLFSSL_AES_128
     1600                case AES128GCMb:
     1601                    oid = blkAes128GcmOid;
     1602                    *oidSz = sizeof(blkAes128GcmOid);
     1603                    break;
     1604        #endif
     1605        #ifdef WOLFSSL_AES_192
     1606                case AES192GCMb:
     1607                    oid = blkAes192GcmOid;
     1608                    *oidSz = sizeof(blkAes192GcmOid);
     1609                    break;
     1610        #endif
     1611        #ifdef WOLFSSL_AES_256
     1612                case AES256GCMb:
     1613                    oid = blkAes256GcmOid;
     1614                    *oidSz = sizeof(blkAes256GcmOid);
     1615                    break;
     1616        #endif
     1617    #endif /* HAVE_AESGCM */
     1618    #ifdef HAVE_AESCCM
     1619        #ifdef WOLFSSL_AES_128
     1620                case AES128CCMb:
     1621                    oid = blkAes128CcmOid;
     1622                    *oidSz = sizeof(blkAes128CcmOid);
     1623                    break;
     1624        #endif
     1625        #ifdef WOLFSSL_AES_192
     1626                case AES192CCMb:
     1627                    oid = blkAes192CcmOid;
     1628                    *oidSz = sizeof(blkAes192CcmOid);
     1629                    break;
     1630        #endif
     1631        #ifdef WOLFSSL_AES_256
     1632                case AES256CCMb:
     1633                    oid = blkAes256CcmOid;
     1634                    *oidSz = sizeof(blkAes256CcmOid);
     1635                    break;
     1636        #endif
     1637    #endif /* HAVE_AESCCM */
     1638    #ifndef NO_DES3
    13611639                case DESb:
    13621640                    oid = blkDesCbcOid;
     
    13671645                    *oidSz = sizeof(blkDes3CbcOid);
    13681646                    break;
     1647    #endif /* !NO_DES3 */
    13691648            }
    13701649            break;
     
    14271706                    *oidSz = sizeof(extExtKeyUsageOid);
    14281707                    break;
     1708            #ifndef IGNORE_NAME_CONSTRAINTS
    14291709                case NAME_CONS_OID:
    14301710                    oid = extNameConsOid;
    14311711                    *oidSz = sizeof(extNameConsOid);
    14321712                    break;
     1713            #endif
    14331714            }
    14341715            break;
     
    14361717        case oidCertAuthInfoType:
    14371718            switch (id) {
     1719            #ifdef HAVE_OCSP
    14381720                case AIA_OCSP_OID:
    14391721                    oid = extAuthInfoOcspOid;
    14401722                    *oidSz = sizeof(extAuthInfoOcspOid);
    14411723                    break;
     1724            #endif
    14421725                case AIA_CA_ISSUER_OID:
    14431726                    oid = extAuthInfoCaIssuerOid;
     
    15071790            break;
    15081791
     1792        case oidPBEType:
     1793            switch (id) {
     1794        #if !defined(NO_SHA) && !defined(NO_RC4)
     1795                case PBE_SHA1_RC4_128:
     1796                    oid = pbeSha1RC4128;
     1797                    *oidSz = sizeof(pbeSha1RC4128);
     1798                    break;
     1799        #endif
     1800        #if !defined(NO_SHA) && !defined(NO_DES3)
     1801                case PBE_SHA1_DES:
     1802                    oid = pbeSha1Des;
     1803                    *oidSz = sizeof(pbeSha1Des);
     1804                    break;
     1805
     1806        #endif
     1807        #if !defined(NO_SHA) && !defined(NO_DES3)
     1808                case PBE_SHA1_DES3:
     1809                    oid = pbeSha1Des3;
     1810                    *oidSz = sizeof(pbeSha1Des3);
     1811                    break;
     1812        #endif
     1813                case PBES2:
     1814                    oid = pbes2;
     1815                    *oidSz = sizeof(pbes2);
     1816                    break;
     1817            }
     1818            break;
     1819
    15091820        case oidKeyWrapType:
    15101821            switch (id) {
     1822            #ifdef WOLFSSL_AES_128
    15111823                case AES128_WRAP:
    15121824                    oid = wrapAes128Oid;
    15131825                    *oidSz = sizeof(wrapAes128Oid);
    15141826                    break;
     1827            #endif
     1828            #ifdef WOLFSSL_AES_192
    15151829                case AES192_WRAP:
    15161830                    oid = wrapAes192Oid;
    15171831                    *oidSz = sizeof(wrapAes192Oid);
    15181832                    break;
     1833            #endif
     1834            #ifdef WOLFSSL_AES_256
    15191835                case AES256_WRAP:
    15201836                    oid = wrapAes256Oid;
    15211837                    *oidSz = sizeof(wrapAes256Oid);
    15221838                    break;
     1839            #endif
     1840            #ifdef HAVE_PKCS7
     1841                case PWRI_KEK_WRAP:
     1842                    oid = wrapPwriKekOid;
     1843                    *oidSz = sizeof(wrapPwriKekOid);
     1844                    break;
     1845            #endif
    15231846            }
    15241847            break;
     
    15261849        case oidCmsKeyAgreeType:
    15271850            switch (id) {
     1851            #ifndef NO_SHA
    15281852                case dhSinglePass_stdDH_sha1kdf_scheme:
    15291853                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
    15301854                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
    15311855                    break;
     1856            #endif
     1857            #ifdef WOLFSSL_SHA224
    15321858                case dhSinglePass_stdDH_sha224kdf_scheme:
    15331859                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
    15341860                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
    15351861                    break;
     1862            #endif
     1863            #ifndef NO_SHA256
    15361864                case dhSinglePass_stdDH_sha256kdf_scheme:
    15371865                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
    15381866                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
    15391867                    break;
     1868            #endif
     1869            #ifdef WOLFSSL_SHA384
    15401870                case dhSinglePass_stdDH_sha384kdf_scheme:
    15411871                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
    15421872                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
    15431873                    break;
     1874            #endif
     1875            #ifdef WOLFSSL_SHA512
    15441876                case dhSinglePass_stdDH_sha512kdf_scheme:
    15451877                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
    15461878                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
    15471879                    break;
     1880            #endif
    15481881            }
    15491882            break;
     1883
     1884#ifndef NO_HMAC
     1885        case oidHmacType:
     1886            switch (id) {
     1887        #ifdef WOLFSSL_SHA224
     1888                case HMAC_SHA224_OID:
     1889                    oid = hmacSha224Oid;
     1890                    *oidSz = sizeof(hmacSha224Oid);
     1891                    break;
     1892        #endif
     1893        #ifndef NO_SHA256
     1894                case HMAC_SHA256_OID:
     1895                    oid = hmacSha256Oid;
     1896                    *oidSz = sizeof(hmacSha256Oid);
     1897                    break;
     1898        #endif
     1899        #ifdef WOLFSSL_SHA384
     1900                case HMAC_SHA384_OID:
     1901                    oid = hmacSha384Oid;
     1902                    *oidSz = sizeof(hmacSha384Oid);
     1903                    break;
     1904        #endif
     1905        #ifdef WOLFSSL_SHA512
     1906                case HMAC_SHA512_OID:
     1907                    oid = hmacSha512Oid;
     1908                    *oidSz = sizeof(hmacSha512Oid);
     1909                    break;
     1910        #endif
     1911            }
     1912            break;
     1913#endif /* !NO_HMAC */
     1914
     1915#ifdef HAVE_LIBZ
     1916        case oidCompressType:
     1917            switch (id) {
     1918                case ZLIBc:
     1919                    oid = zlibCompress;
     1920                    *oidSz = sizeof(zlibCompress);
     1921                    break;
     1922            }
     1923            break;
     1924#endif /* HAVE_LIBZ */
    15501925
    15511926        case oidIgnoreType:
     
    16822057 *         Otherwise, 0 to indicate success.
    16832058 */
    1684 static int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
     2059int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
    16852060                          word32 maxIdx)
    16862061{
     
    17102085 * returns the number of bytes added to the buffer.
    17112086 */
    1712 static int SetObjectId(int len, byte* output)
     2087int SetObjectId(int len, byte* output)
    17132088{
    17142089    int idx = 0;
     
    17582133        word32 checkOidSz;
    17592134    #ifdef ASN_DUMP_OID
    1760         int i;
     2135        word32 i;
    17612136    #endif
    17622137
     
    18362211
    18372212    /* could have NULL tag and 0 terminator, but may not */
    1838     if (input[idx] == ASN_TAG_NULL) {
     2213    if (idx < maxIdx && input[idx] == ASN_TAG_NULL) {
    18392214        ret = GetASNNull(input, &idx, maxIdx);
    18402215        if (ret != 0)
     
    18682243    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
    18692244        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
     2245#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    18702246        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
    18712247        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
    1872         GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
    1873         GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
     2248        GetInt(&key->q,  input, inOutIdx, inSz) < 0)
     2249#else
     2250        SkipInt(input, inOutIdx, inSz) < 0 ||
     2251        SkipInt(input, inOutIdx, inSz) < 0 ||
     2252        SkipInt(input, inOutIdx, inSz) < 0 )
     2253
     2254#endif
     2255            return ASN_RSA_KEY_E;
     2256#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
     2257    && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
     2258    if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
    18742259        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
    18752260        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
     2261#else
     2262    if (SkipInt(input, inOutIdx, inSz) < 0 ||
     2263        SkipInt(input, inOutIdx, inSz) < 0 ||
     2264        SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
     2265#endif
    18762266
    18772267#ifdef WOLFSSL_XILINX_CRYPT
     
    18882278/* Remove PKCS8 header, place inOutIdx at beginning of traditional,
    18892279 * return traditional length on success, negative on error */
    1890 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
    1891 {
    1892     word32 idx, oid;
     2280int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
     2281                           word32* algId)
     2282{
     2283    word32 idx;
    18932284    int    version, length;
    18942285    int    ret;
     
    19052296        return ASN_PARSE_E;
    19062297
    1907     if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
     2298    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
    19082299        return ASN_PARSE_E;
    19092300
     
    19222313}
    19232314
     2315int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
     2316{
     2317    word32 oid;
     2318
     2319    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
     2320}
     2321
    19242322/* Remove PKCS8 header, move beginning of traditional to beginning of input */
    1925 int ToTraditional(byte* input, word32 sz)
     2323int ToTraditional_ex(byte* input, word32 sz, word32* algId)
    19262324{
    19272325    word32 inOutIdx = 0;
     
    19312329        return BAD_FUNC_ARG;
    19322330
    1933     length = ToTraditionalInline(input, &inOutIdx, sz);
     2331    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
    19342332    if (length < 0)
    19352333        return length;
     
    19402338}
    19412339
     2340int ToTraditional(byte* input, word32 sz)
     2341{
     2342    word32 oid;
     2343
     2344    return ToTraditional_ex(input, sz, &oid);
     2345}
    19422346
    19432347/* find beginning of traditional key inside PKCS#8 unencrypted buffer
     
    19482352{
    19492353    int length;
     2354    word32 algId;
    19502355
    19512356    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
    19522357        return BAD_FUNC_ARG;
    19532358
    1954     length = ToTraditionalInline(input, inOutIdx, sz);
     2359    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
    19552360
    19562361    return length;
     
    20792484{
    20802485    int ret;
     2486    (void)keySz;
    20812487
    20822488    if (key == NULL || der == NULL) {
     
    20842490    }
    20852491
    2086     #if !defined(NO_RSA)
     2492    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
    20872493    /* test if RSA key */
    20882494    if (der->keyOID == RSAk) {
    2089         RsaKey a, b;
     2495    #ifdef WOLFSSL_SMALL_STACK
     2496        RsaKey* a = NULL;
     2497        RsaKey* b = NULL;
     2498    #else
     2499        RsaKey a[1], b[1];
     2500    #endif
    20902501        word32 keyIdx = 0;
    20912502
    2092         if ((ret = wc_InitRsaKey(&a, NULL)) < 0)
     2503    #ifdef WOLFSSL_SMALL_STACK
     2504        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
     2505        if (a == NULL)
     2506            return MEMORY_E;
     2507        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
     2508        if (b == NULL) {
     2509            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2510            return MEMORY_E;
     2511        }
     2512    #endif
     2513
     2514        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
     2515    #ifdef WOLFSSL_SMALL_STACK
     2516            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2517            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2518    #endif
    20932519            return ret;
    2094         if ((ret = wc_InitRsaKey(&b, NULL)) < 0) {
    2095             wc_FreeRsaKey(&a);
     2520        }
     2521        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
     2522            wc_FreeRsaKey(a);
     2523    #ifdef WOLFSSL_SMALL_STACK
     2524            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2525            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2526    #endif
    20962527            return ret;
    20972528        }
    2098         if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, &a, keySz)) == 0) {
     2529        if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
    20992530            WOLFSSL_MSG("Checking RSA key pair");
    21002531            keyIdx = 0; /* reset to 0 for parsing public key */
    21012532
    2102             if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, &b,
     2533            if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
    21032534                                                       der->pubKeySize)) == 0) {
    21042535                /* limit for user RSA crypto because of RsaKey
     
    21102541                /* both keys extracted successfully now check n and e
    21112542                 * values are the same. This is dereferencing RsaKey */
    2112                 if (mp_cmp(&(a.n), &(b.n)) != MP_EQ ||
    2113                     mp_cmp(&(a.e), &(b.e)) != MP_EQ) {
     2543                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
     2544                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
    21142545                    ret = MP_CMP_E;
    21152546                }
     
    21192550            }
    21202551        }
    2121         wc_FreeRsaKey(&b);
    2122         wc_FreeRsaKey(&a);
     2552        wc_FreeRsaKey(b);
     2553        wc_FreeRsaKey(a);
     2554    #ifdef WOLFSSL_SMALL_STACK
     2555        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
     2556        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
     2557    #endif
    21232558    }
    21242559    else
    2125     #endif /* NO_RSA */
    2126 
    2127     #ifdef HAVE_ECC
     2560    #endif /* !NO_RSA && !NO_ASN_CRYPT */
     2561
     2562    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    21282563    if (der->keyOID == ECDSAk) {
     2564    #ifdef WOLFSSL_SMALL_STACK
     2565        ecc_key* key_pair = NULL;
     2566        byte*    privDer;
     2567    #else
     2568        ecc_key  key_pair[1];
     2569        byte     privDer[MAX_ECC_BYTES];
     2570    #endif
     2571        word32   privSz = MAX_ECC_BYTES;
    21292572        word32  keyIdx = 0;
    2130         ecc_key key_pair;
    2131 
    2132         if ((ret = wc_ecc_init(&key_pair)) < 0)
     2573
     2574    #ifdef WOLFSSL_SMALL_STACK
     2575        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
     2576        if (key_pair == NULL)
     2577            return MEMORY_E;
     2578        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2579        if (privDer == NULL) {
     2580            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2581            return MEMORY_E;
     2582        }
     2583    #endif
     2584
     2585        if ((ret = wc_ecc_init(key_pair)) < 0) {
     2586    #ifdef WOLFSSL_SMALL_STACK
     2587            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2588            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2589    #endif
    21332590            return ret;
    2134         if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, &key_pair,
     2591        }
     2592
     2593        if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
    21352594                                                                 keySz)) == 0) {
    21362595            WOLFSSL_MSG("Checking ECC key pair");
    2137             keyIdx = 0;
    2138             if ((ret = wc_ecc_import_x963(der->publicKey, der->pubKeySize,
    2139                                                              &key_pair)) == 0) {
    2140                 /* public and private extracted successfuly no check if is
     2596
     2597            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
     2598                                                                         == 0) {
     2599                wc_ecc_free(key_pair);
     2600                ret = wc_ecc_init(key_pair);
     2601                if (ret == 0) {
     2602                    ret = wc_ecc_import_private_key((const byte*)privDer,
     2603                                            privSz, (const byte*)der->publicKey,
     2604                                            der->pubKeySize, key_pair);
     2605                }
     2606
     2607                /* public and private extracted successfuly now check if is
    21412608                 * a pair and also do sanity checks on key. wc_ecc_check_key
    21422609                 * checks that private * base generator equals pubkey */
    2143                 if ((ret = wc_ecc_check_key(&key_pair)) == 0)
     2610                if (ret == 0) {
     2611                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
    21442612                    ret = 1;
    21452613            }
    21462614        }
    2147         wc_ecc_free(&key_pair);
     2615                ForceZero(privDer, privSz);
     2616            }
     2617        }
     2618        wc_ecc_free(key_pair);
     2619    #ifdef WOLFSSL_SMALL_STACK
     2620        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2621        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
     2622    #endif
    21482623    }
    21492624    else
    2150     #endif /* HAVE_ECC */
    2151 
    2152     #ifdef HAVE_ED25519
     2625    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
     2626
     2627    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    21532628    if (der->keyOID == ED25519k) {
     2629    #ifdef WOLFSSL_SMALL_STACK
     2630        ed25519_key* key_pair = NULL;
     2631    #else
     2632        ed25519_key  key_pair[1];
     2633    #endif
    21542634        word32  keyIdx = 0;
    2155         ed25519_key key_pair;
    2156 
    2157         if ((ret = wc_ed25519_init(&key_pair)) < 0)
     2635
     2636    #ifdef WOLFSSL_SMALL_STACK
     2637        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
     2638                                                          DYNAMIC_TYPE_ED25519);
     2639        if (key_pair == NULL)
     2640            return MEMORY_E;
     2641    #endif
     2642
     2643        if ((ret = wc_ed25519_init(key_pair)) < 0) {
     2644    #ifdef WOLFSSL_SMALL_STACK
     2645            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
     2646    #endif
    21582647            return ret;
    2159         if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, &key_pair,
     2648        }
     2649        if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
    21602650                                                                 keySz)) == 0) {
    21612651            WOLFSSL_MSG("Checking ED25519 key pair");
    21622652            keyIdx = 0;
    21632653            if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
    2164                                                              &key_pair)) == 0) {
     2654                                                              key_pair)) == 0) {
    21652655                /* public and private extracted successfuly no check if is
    21662656                 * a pair and also do sanity checks on key. wc_ecc_check_key
    21672657                 * checks that private * base generator equals pubkey */
    2168                 if ((ret = wc_ed25519_check_key(&key_pair)) == 0)
     2658                if ((ret = wc_ed25519_check_key(key_pair)) == 0)
    21692659                    ret = 1;
    21702660            }
    21712661        }
    2172         wc_ed25519_free(&key_pair);
     2662        wc_ed25519_free(key_pair);
     2663    #ifdef WOLFSSL_SMALL_STACK
     2664        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
     2665    #endif
    21732666    }
    21742667    else
    2175     #endif
     2668    #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
    21762669    {
    21772670        ret = 0;
    21782671    }
    21792672
     2673    (void)keySz;
     2674
    21802675    return ret;
    21812676}
     
    21852680/* Check To see if PKCS version algo is supported, set id if it is return 0
    21862681   < 0 on error */
    2187 static int CheckAlgo(int first, int second, int* id, int* version)
     2682static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
    21882683{
    21892684    *id      = ALGO_ID_E;
    21902685    *version = PKCS5;   /* default */
     2686    if (blockSz) *blockSz = 8; /* default */
    21912687
    21922688    if (first == 1) {
    21932689        switch (second) {
    2194         case 1:
     2690#if !defined(NO_SHA)
     2691    #ifndef NO_RC4
     2692        case PBE_SHA1_RC4_128:
    21952693            *id = PBE_SHA1_RC4_128;
    21962694            *version = PKCS12v1;
    21972695            return 0;
    2198         case 3:
     2696    #endif
     2697    #ifndef NO_DES3
     2698        case PBE_SHA1_DES3:
    21992699            *id = PBE_SHA1_DES3;
    22002700            *version = PKCS12v1;
     2701            if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22012702            return 0;
     2703    #endif
     2704#endif /* !NO_SHA */
    22022705        default:
    22032706            return ALGO_ID_E;
     
    22142717
    22152718    switch (second) {
     2719#ifndef NO_DES3
     2720    #ifndef NO_MD5
    22162721    case 3:                   /* see RFC 2898 for ids */
    22172722        *id = PBE_MD5_DES;
     2723        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22182724        return 0;
     2725    #endif
     2726    #ifndef NO_SHA
    22192727    case 10:
    22202728        *id = PBE_SHA1_DES;
     2729        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22212730        return 0;
     2731    #endif
     2732#endif /* !NO_DES3 */
    22222733    default:
    22232734        return ALGO_ID_E;
     
    22292740/* Check To see if PKCS v2 algo is supported, set id if it is return 0
    22302741   < 0 on error */
    2231 static int CheckAlgoV2(int oid, int* id)
    2232 {
     2742static int CheckAlgoV2(int oid, int* id, int* blockSz)
     2743{
     2744    if (blockSz) *blockSz = 8; /* default */
     2745    (void)id; /* not used if AES and DES3 disabled */
    22332746    switch (oid) {
    2234     case 69:
     2747#if !defined(NO_DES3) && !defined(NO_SHA)
     2748    case DESb:
    22352749        *id = PBE_SHA1_DES;
     2750        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22362751        return 0;
    2237     case 652:
     2752    case DES3b:
    22382753        *id = PBE_SHA1_DES3;
     2754        if (blockSz) *blockSz = DES_BLOCK_SIZE;
    22392755        return 0;
     2756#endif
     2757#ifdef WOLFSSL_AES_256
     2758    case AES256CBCb:
     2759        *id = PBE_AES256_CBC;
     2760        if (blockSz) *blockSz = AES_BLOCK_SIZE;
     2761        return 0;
     2762#endif
    22402763    default:
    22412764        return ALGO_ID_E;
     
    22452768
    22462769
    2247 /* Decrypt input in place from parameters based on id */
    2248 static int DecryptKey(const char* password, int passwordSz, byte* salt,
    2249                       int saltSz, int iterations, int id, byte* input,
    2250                       int length, int version, byte* cbcIv)
    2251 {
    2252     int typeH;
    2253     int derivedLen;
    2254     int decryptionType;
    2255     int ret = 0;
    2256 #ifdef WOLFSSL_SMALL_STACK
    2257     byte* key;
    2258 #else
    2259     byte key[MAX_KEY_SIZE];
    2260 #endif
    2261 
    2262     (void)input;
    2263     (void)length;
    2264 
    2265     switch (id) {
    2266         case PBE_MD5_DES:
    2267             typeH = WC_MD5;
    2268             derivedLen = 16;           /* may need iv for v1.5 */
    2269             decryptionType = DES_TYPE;
    2270             break;
    2271 
    2272         case PBE_SHA1_DES:
    2273             typeH = WC_SHA;
    2274             derivedLen = 16;           /* may need iv for v1.5 */
    2275             decryptionType = DES_TYPE;
    2276             break;
    2277 
    2278         case PBE_SHA1_DES3:
    2279             typeH = WC_SHA;
    2280             derivedLen = 32;           /* may need iv for v1.5 */
    2281             decryptionType = DES3_TYPE;
    2282             break;
    2283 
    2284         case PBE_SHA1_RC4_128:
    2285             typeH = WC_SHA;
    2286             derivedLen = 16;
    2287             decryptionType = RC4_TYPE;
    2288             break;
    2289 
    2290         default:
    2291             return ALGO_ID_E;
    2292     }
    2293 
    2294 #ifdef WOLFSSL_SMALL_STACK
    2295     key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2296     if (key == NULL)
    2297         return MEMORY_E;
    2298 #endif
    2299 
    2300     if (version == PKCS5v2)
    2301         ret = wc_PBKDF2(key, (byte*)password, passwordSz,
    2302                         salt, saltSz, iterations, derivedLen, typeH);
    2303 #ifndef NO_SHA
    2304     else if (version == PKCS5)
    2305         ret = wc_PBKDF1(key, (byte*)password, passwordSz,
    2306                         salt, saltSz, iterations, derivedLen, typeH);
    2307 #endif
    2308     else if (version == PKCS12v1) {
    2309         int  i, idx = 0;
    2310         byte unicodePasswd[MAX_UNICODE_SZ];
    2311 
    2312         if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
    2313 #ifdef WOLFSSL_SMALL_STACK
    2314             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2315 #endif
    2316             return UNICODE_SIZE_E;
    2317         }
    2318 
    2319         for (i = 0; i < passwordSz; i++) {
    2320             unicodePasswd[idx++] = 0x00;
    2321             unicodePasswd[idx++] = (byte)password[i];
    2322         }
    2323         /* add trailing NULL */
    2324         unicodePasswd[idx++] = 0x00;
    2325         unicodePasswd[idx++] = 0x00;
    2326 
    2327         ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
    2328                             iterations, derivedLen, typeH, 1);
    2329         if (decryptionType != RC4_TYPE)
    2330             ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
    2331                                 iterations, 8, typeH, 2);
    2332     }
    2333     else {
    2334 #ifdef WOLFSSL_SMALL_STACK
    2335         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2336 #endif
    2337         return ALGO_ID_E;
    2338     }
    2339 
    2340     if (ret != 0) {
    2341 #ifdef WOLFSSL_SMALL_STACK
    2342         XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2343 #endif
    2344         return ret;
    2345     }
    2346 
    2347     switch (decryptionType) {
    2348 #ifndef NO_DES3
    2349         case DES_TYPE:
    2350         {
    2351             Des    dec;
    2352             byte*  desIv = key + 8;
    2353 
    2354             if (version == PKCS5v2 || version == PKCS12v1)
    2355                 desIv = cbcIv;
    2356 
    2357             ret = wc_Des_SetKey(&dec, key, desIv, DES_DECRYPTION);
    2358             if (ret != 0) {
    2359 #ifdef WOLFSSL_SMALL_STACK
    2360                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2361 #endif
    2362                 return ret;
    2363             }
    2364 
    2365             wc_Des_CbcDecrypt(&dec, input, input, length);
    2366             break;
    2367         }
    2368 
    2369         case DES3_TYPE:
    2370         {
    2371             Des3   dec;
    2372             byte*  desIv = key + 24;
    2373 
    2374             if (version == PKCS5v2 || version == PKCS12v1)
    2375                 desIv = cbcIv;
    2376 
    2377             ret = wc_Des3Init(&dec, NULL, INVALID_DEVID);
    2378             if (ret != 0) {
    2379 #ifdef WOLFSSL_SMALL_STACK
    2380                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2381 #endif
    2382                 return ret;
    2383             }
    2384             ret = wc_Des3_SetKey(&dec, key, desIv, DES_DECRYPTION);
    2385             if (ret != 0) {
    2386 #ifdef WOLFSSL_SMALL_STACK
    2387                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2388 #endif
    2389                 return ret;
    2390             }
    2391             ret = wc_Des3_CbcDecrypt(&dec, input, input, length);
    2392             if (ret != 0) {
    2393 #ifdef WOLFSSL_SMALL_STACK
    2394                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2395 #endif
    2396                 return ret;
    2397             }
    2398             break;
    2399         }
    2400 #endif
    2401 #ifndef NO_RC4
    2402         case RC4_TYPE:
    2403         {
    2404             Arc4    dec;
    2405 
    2406             wc_Arc4SetKey(&dec, key, derivedLen);
    2407             wc_Arc4Process(&dec, input, input, length);
    2408             break;
    2409         }
    2410 #endif
    2411 
    2412         default:
    2413 #ifdef WOLFSSL_SMALL_STACK
    2414             XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2415 #endif
    2416             return ALGO_ID_E;
    2417     }
    2418 
    2419 #ifdef WOLFSSL_SMALL_STACK
    2420     XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2421 #endif
    2422 
    2423     return 0;
    2424 }
    2425 
    2426 
    24272770int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
    24282771        int* algoID, void* heap)
    24292772{
    24302773    word32 tmpIdx = 0;
    2431 #ifdef HAVE_ECC
    2432     ecc_key ecc;
    2433 #endif
    2434 #ifndef NO_RSA
    2435     RsaKey rsa;
    2436 #endif
    2437 #ifdef HAVE_ED25519
    2438     ed25519_key ed25519;
    2439 #endif
    2440 
    2441     if (algoID == NULL) {
     2774
     2775    if (key == NULL || algoID == NULL)
    24422776        return BAD_FUNC_ARG;
    2443     }
     2777
    24442778    *algoID = 0;
    24452779
    2446 #ifndef NO_RSA
    2447     if (wc_InitRsaKey(&rsa, heap) == 0) {
     2780    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
     2781    {
     2782        RsaKey rsa;
     2783
     2784        wc_InitRsaKey(&rsa, heap);
    24482785        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
    24492786            *algoID = RSAk;
    2450         }
     2787    }
    24512788        else {
    24522789            WOLFSSL_MSG("Not RSA DER key");
     
    24542791        wc_FreeRsaKey(&rsa);
    24552792    }
    2456     else {
    2457         WOLFSSL_MSG("GetKeyOID wc_InitRsaKey failed");
    2458     }
    2459 #endif /* NO_RSA */
    2460 #ifdef HAVE_ECC
    2461     if (*algoID != RSAk) {
     2793    #endif /* !NO_RSA && !NO_ASN_CRYPT */
     2794    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
     2795    if (*algoID == 0) {
     2796        ecc_key ecc;
     2797
    24622798        tmpIdx = 0;
    2463         if (wc_ecc_init_ex(&ecc, heap, INVALID_DEVID) == 0) {
    2464             if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
    2465                 *algoID = ECDSAk;
    2466 
    2467                 /* sanity check on arguments */
    2468                 if (curveOID == NULL || oidSz == NULL) {
    2469                     WOLFSSL_MSG("Error getting ECC curve OID");
    2470                     wc_ecc_free(&ecc);
    2471                     return BAD_FUNC_ARG;
    2472                 }
    2473 
    2474                 /* now find oid */
    2475                 if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
    2476                     WOLFSSL_MSG("Error getting ECC curve OID");
    2477                     wc_ecc_free(&ecc);
    2478                     return BAD_FUNC_ARG;
    2479                 }
    2480             }
    2481             else {
    2482                 WOLFSSL_MSG("Not ECC DER key either");
    2483             }
    2484             wc_ecc_free(&ecc);
     2799        wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);
     2800        if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
     2801            *algoID = ECDSAk;
     2802
     2803            /* now find oid */
     2804            if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
     2805                WOLFSSL_MSG("Error getting ECC curve OID");
     2806                wc_ecc_free(&ecc);
     2807                return BAD_FUNC_ARG;
     2808        }
    24852809        }
    24862810        else {
    2487             WOLFSSL_MSG("GetKeyOID wc_ecc_init_ex failed");
    2488         }
    2489     }
    2490 #endif /* HAVE_ECC */
    2491 #ifdef HAVE_ED25519
     2811            WOLFSSL_MSG("Not ECC DER key either");
     2812        }
     2813        wc_ecc_free(&ecc);
     2814    }
     2815#endif /* HAVE_ECC && !NO_ASN_CRYPT */
     2816#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    24922817    if (*algoID != RSAk && *algoID != ECDSAk) {
     2818        ed25519_key ed25519;
     2819
     2820        tmpIdx = 0;
    24932821        if (wc_ed25519_init(&ed25519) == 0) {
    24942822            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
    24952823                                                                         == 0) {
    24962824                *algoID = ED25519k;
    2497             }
    2498             else {
     2825    }
     2826    else {
    24992827                WOLFSSL_MSG("Not ED25519 DER key");
    2500             }
     2828    }
    25012829            wc_ed25519_free(&ed25519);
    2502         }
     2830    }
    25032831        else {
    25042832            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
    25052833        }
    25062834    }
    2507 #endif
     2835#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
    25082836
    25092837    /* if flag is not set then is neither RSA or ECC key that could be
     
    25142842    }
    25152843
     2844    (void)tmpIdx;
    25162845    (void)curveOID;
    25172846    (void)oidSz;
     2847    (void)keySz;
     2848    (void)heap;
    25182849
    25192850    return 1;
    25202851}
    25212852
     2853#define PKCS8_MIN_BLOCK_SIZE 8
     2854static int Pkcs8Pad(byte* buf, int sz, int blockSz)
     2855        {
     2856    int i, padSz;
     2857
     2858    /* calculate pad size */
     2859    padSz = blockSz - (sz & (blockSz - 1));
     2860
     2861    /* pad with padSz value */
     2862    if (buf) {
     2863        for (i = 0; i < padSz; i++) {
     2864            buf[sz+i] = (byte)(padSz & 0xFF);
     2865        }
     2866            }
     2867
     2868    /* return adjusted length */
     2869    return sz + padSz;
     2870        }
     2871
     2872/*
     2873 * Used when creating PKCS12 shrouded key bags
     2874 * vPKCS is the version of PKCS to use
     2875 * vAlgo is the algorithm version to use
     2876 *
     2877 * if salt is NULL a random number is generated
     2878 *
     2879 * returns the size of encrypted data on success
     2880 */
     2881int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
     2882        const char* password, int passwordSz, int vPKCS, int vAlgo,
     2883        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
     2884        {
     2885    int algoID = 0;
     2886    byte*  tmp;
     2887    word32 tmpSz = 0;
     2888    word32 sz;
     2889    word32 seqSz;
     2890    word32 inOutIdx = 0;
     2891    word32 totalSz = 0;
     2892    int    version, id;
     2893    int    ret;
     2894    int    blockSz = 0;
     2895
     2896    const byte* curveOID = NULL;
     2897    word32 oidSz   = 0;
     2898
     2899#ifdef WOLFSSL_SMALL_STACK
     2900    byte*  saltTmp = NULL;
     2901    byte*  cbcIv   = NULL;
     2902#else
     2903    byte   saltTmp[MAX_IV_SIZE];
     2904    byte   cbcIv[MAX_IV_SIZE];
     2905#endif
     2906
     2907    WOLFSSL_ENTER("UnTraditionalEnc()");
     2908
     2909    if (saltSz > MAX_SALT_SIZE)
     2910        return ASN_PARSE_E;
     2911
     2912
     2913    inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */
     2914    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
     2915        WOLFSSL_MSG("Bad/Unsupported algorithm ID");
     2916        return ASN_INPUT_E;  /* Algo ID error */
     2917            }
     2918
     2919    if (out != NULL) {
     2920        if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +
     2921                MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)
     2922                return BUFFER_E;
     2923
     2924        if (version == PKCS5v2) {
     2925            WOLFSSL_MSG("PKCS5v2 Not supported yet\n");
     2926            return ASN_VERSION_E;
     2927        }
     2928
     2929        if (salt == NULL || saltSz <= 0) {
     2930            saltSz = 8;
     2931        #ifdef WOLFSSL_SMALL_STACK
     2932            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2933            if (saltTmp == NULL)
     2934                return MEMORY_E;
     2935        #endif
     2936            salt = saltTmp;
     2937
     2938            if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     2939                WOLFSSL_MSG("Error generating random salt");
     2940#ifdef WOLFSSL_SMALL_STACK
     2941                if (saltTmp != NULL)
     2942                    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2943#endif
     2944                return ret;
     2945            }
     2946        }
     2947
     2948
     2949        /* leave room for a sequence (contains salt and iterations int) */
     2950        inOutIdx += MAX_SEQ_SZ; sz = 0;
     2951        inOutIdx += MAX_ALGO_SZ;
     2952
     2953        /* place salt in buffer */
     2954        out[inOutIdx++] = ASN_OCTET_STRING; sz++;
     2955        tmpSz = SetLength(saltSz, out + inOutIdx);
     2956        inOutIdx += tmpSz; sz += tmpSz;
     2957        XMEMCPY(out + inOutIdx, salt, saltSz);
     2958        inOutIdx += saltSz; sz += saltSz;
     2959
     2960        /* place iteration count in buffer */
     2961        ret = SetShortInt(out, &inOutIdx, itt, *outSz);
     2962        if (ret < 0) {
     2963            return ret;
     2964        }
     2965        sz += (word32)ret;
     2966
     2967        /* wind back index and set sequence then clean up buffer */
     2968        inOutIdx -= (sz + MAX_SEQ_SZ);
     2969        tmpSz = SetSequence(sz, out + inOutIdx);
     2970        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);
     2971        totalSz += tmpSz + sz; sz += tmpSz;
     2972
     2973        /* add in algo ID */
     2974        inOutIdx -= MAX_ALGO_SZ;
     2975        tmpSz =  SetAlgoID(id, out + inOutIdx, oidPBEType, sz);
     2976        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);
     2977        totalSz += tmpSz; inOutIdx += tmpSz + sz;
     2978
     2979        /* octet string containing encrypted key */
     2980        out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;
     2981    }
     2982
     2983    /* check key type and get OID if ECC */
     2984    if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {
     2985            return ret;
     2986    }
     2987
     2988    /* PKCS#8 wrapping around key */
     2989    if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)
     2990            != LENGTH_ONLY_E) {
     2991#ifdef WOLFSSL_SMALL_STACK
     2992        if (saltTmp != NULL)
     2993            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     2994#endif
     2995        return MEMORY_E;
     2996            }
     2997
     2998    /* check if should return max size */
     2999    if (out == NULL) {
     3000        /* account for salt size */
     3001        if (salt == NULL || saltSz <= 0) {
     3002            tmpSz += MAX_SALT_SIZE;
     3003        }
     3004        else {
     3005            tmpSz += saltSz;
     3006        }
     3007
     3008        /* plus 3 for tags */
     3009        *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ
     3010            + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;
     3011        return LENGTH_ONLY_E;
     3012        }
     3013
     3014    /* reserve buffer for crypto and make sure it supports full blocks */
     3015    tmp = (byte*)XMALLOC(tmpSz + (blockSz-1), heap, DYNAMIC_TYPE_TMP_BUFFER);
     3016    if (tmp == NULL) {
     3017    #ifdef WOLFSSL_SMALL_STACK
     3018        if (saltTmp != NULL)
     3019            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3020#endif
     3021        return MEMORY_E;
     3022    }
     3023
     3024    if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,
     3025                    oidSz)) < 0) {
     3026        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3027        WOLFSSL_MSG("Error wrapping key with PKCS#8");
     3028    #ifdef WOLFSSL_SMALL_STACK
     3029        if (saltTmp != NULL)
     3030            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3031    #endif
     3032        return ret;
     3033    }
     3034    tmpSz = ret;
     3035
     3036    /* adjust size to pad */
     3037    tmpSz = Pkcs8Pad(tmp, tmpSz, blockSz);
     3038
     3039#ifdef WOLFSSL_SMALL_STACK
     3040    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3041    if (cbcIv == NULL) {
     3042        if (saltTmp != NULL)
     3043            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3044        XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3045        return MEMORY_E;
     3046        }
     3047#endif
     3048
     3049    /* encrypt PKCS#8 wrapped key */
     3050    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3051               tmp, tmpSz, version, cbcIv, 1)) < 0) {
     3052        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3053        WOLFSSL_MSG("Error encrypting key");
     3054#ifdef WOLFSSL_SMALL_STACK
     3055        if (saltTmp != NULL)
     3056            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3057        if (cbcIv != NULL)
     3058            XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3059#endif
     3060        return ret;  /* encryption failure */
     3061    }
     3062    totalSz += tmpSz;
     3063
     3064#ifdef WOLFSSL_SMALL_STACK
     3065    if (saltTmp != NULL)
     3066        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3067    if (cbcIv != NULL)
     3068        XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3069#endif
     3070
     3071    if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {
     3072        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3073        return BUFFER_E;
     3074}
     3075
     3076    /* set length of key and copy over encrypted key */
     3077    seqSz = SetLength(tmpSz, out + inOutIdx);
     3078    inOutIdx += seqSz; totalSz += seqSz;
     3079    XMEMCPY(out + inOutIdx, tmp, tmpSz);
     3080    XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3081
     3082    /* set total size at beginning */
     3083    sz = SetSequence(totalSz, out);
     3084    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);
     3085
     3086    (void)rng;
     3087
     3088    return totalSz + sz;
     3089}
     3090
     3091static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
     3092                     int *blkSz)
     3093{
     3094    int ret = 0;
     3095
     3096    switch (encAlgId) {
     3097#if !defined(NO_DES3) && !defined(NO_SHA)
     3098    case DESb:
     3099        *len = sizeof(blkDesCbcOid);
     3100        *oid = blkDesCbcOid;
     3101        *id = PBE_SHA1_DES;
     3102        *blkSz = 8;
     3103        break;
     3104    case DES3b:
     3105        *len = sizeof(blkDes3CbcOid);
     3106        *oid = blkDes3CbcOid;
     3107        *id = PBE_SHA1_DES3;
     3108        *blkSz = 8;
     3109        break;
     3110#endif
     3111#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
     3112    case AES256CBCb:
     3113        *len = sizeof(blkAes256CbcOid);
     3114        *oid = blkAes256CbcOid;
     3115        *id = PBE_AES256_CBC;
     3116        *blkSz = 16;
     3117        break;
     3118#endif
     3119    default:
     3120        (void)len;
     3121        (void)oid;
     3122        (void)id;
     3123        (void)blkSz;
     3124        ret = ALGO_ID_E;
     3125    }
     3126
     3127    return ret;
     3128        }
     3129
     3130/* Converts Encrypted PKCS#8 to 'traditional' (i.e. PKCS#8 removed from
     3131 * decrypted key.)
     3132 */
     3133int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
     3134        const char* password, int passwordSz, int vPKCS, int vAlgo,
     3135        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
     3136        void* heap)
     3137{
     3138    int ret = 0;
     3139    int version, blockSz, id;
     3140    word32 idx = 0, encIdx;
     3141#ifdef WOLFSSL_SMALL_STACK
     3142    byte* saltTmp = NULL;
     3143#else
     3144    byte saltTmp[MAX_SALT_SIZE];
     3145#endif
     3146    byte cbcIv[MAX_IV_SIZE];
     3147    byte *pkcs8Key = NULL;
     3148    word32 pkcs8KeySz, padSz = 0;
     3149    int algId;
     3150    const byte* curveOid = NULL;
     3151    word32 curveOidSz = 0;
     3152    const byte* pbeOid = NULL;
     3153    word32 pbeOidSz;
     3154    const byte* encOid = NULL;
     3155    int encOidSz = 0;
     3156    word32 pbeLen = 0, kdfLen = 0, encLen = 0;
     3157    word32 innerLen = 0, outerLen;
     3158
     3159    ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz);
     3160    /* create random salt if one not provided */
     3161    if (ret == 0 && (salt == NULL || saltSz <= 0)) {
     3162        saltSz = 8;
     3163    #ifdef WOLFSSL_SMALL_STACK
     3164        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3165        if (saltTmp == NULL)
     3166            return MEMORY_E;
     3167    #endif
     3168        salt = saltTmp;
     3169
     3170        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     3171            WOLFSSL_MSG("Error generating random salt");
     3172        #ifdef WOLFSSL_SMALL_STACK
     3173            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3174        #endif
     3175            return ret;
     3176    }
     3177    }
     3178
     3179    if (ret == 0) {
     3180        /* check key type and get OID if ECC */
     3181        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
     3182        if (ret == 1)
     3183            ret = 0;
     3184                }
     3185    if (ret == 0) {
     3186        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
     3187                                                                    curveOidSz);
     3188        if (ret == LENGTH_ONLY_E)
     3189            ret = 0;
     3190                }
     3191    if (ret == 0) {
     3192        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     3193        if (pkcs8Key == NULL)
     3194            ret = MEMORY_E;
     3195            }
     3196    if (ret == 0) {
     3197        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
     3198                                                          curveOid, curveOidSz);
     3199        if (ret >= 0) {
     3200            pkcs8KeySz = ret;
     3201            ret = 0;
     3202            }
     3203        }
     3204
     3205    if (ret == 0 && version == PKCS5v2)
     3206        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &id, &blockSz);
     3207
     3208    if (ret == 0) {
     3209        padSz = (blockSz - (pkcs8KeySz & (blockSz - 1))) & (blockSz - 1);
     3210        /* inner = OCT salt INT itt */
     3211        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
     3212
     3213        if (version != PKCS5v2) {
     3214            pbeOid = OidFromId(id, oidPBEType, &pbeOidSz);
     3215            /* pbe = OBJ pbse1 SEQ [ inner ] */
     3216            pbeLen = 2 + pbeOidSz + 2 + innerLen;
     3217        }
     3218        else {
     3219            pbeOid = pbes2;
     3220            pbeOidSz = sizeof(pbes2);
     3221            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
     3222            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
     3223            /* enc = OBJ enc_alg OCT iv */
     3224            encLen = 2 + encOidSz + 2 + blockSz;
     3225            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
     3226            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
     3227
     3228            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
     3229        }
     3230    }
     3231    if (ret == 0) {
     3232        /* outer = SEQ [ pbe ] OCT encrypted_PKCS#8_key */
     3233        outerLen = 2 + pbeLen;
     3234        outerLen += SetOctetString(pkcs8KeySz + padSz, out);
     3235        outerLen += pkcs8KeySz + padSz;
     3236
     3237        idx += SetSequence(outerLen, out + idx);
     3238
     3239        encIdx = idx + outerLen - pkcs8KeySz - padSz;
     3240        /* Put Encrypted content in place. */
     3241        XMEMCPY(out + encIdx, pkcs8Key, pkcs8KeySz);
     3242        if (padSz > 0) {
     3243            XMEMSET(out + encIdx + pkcs8KeySz, padSz, padSz);
     3244            pkcs8KeySz += padSz;
     3245            }
     3246        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3247                                   out + encIdx, pkcs8KeySz, version, cbcIv, 1);
     3248            }
     3249    if (ret == 0) {
     3250        if (version != PKCS5v2) {
     3251            /* PBE algorithm */
     3252            idx += SetSequence(pbeLen, out + idx);
     3253            idx += SetObjectId(pbeOidSz, out + idx);
     3254            XMEMCPY(out + idx, pbeOid, pbeOidSz);
     3255            idx += pbeOidSz;
     3256        }
     3257        else {
     3258            /* PBES2 algorithm identifier */
     3259            idx += SetSequence(pbeLen, out + idx);
     3260            idx += SetObjectId(pbeOidSz, out + idx);
     3261            XMEMCPY(out + idx, pbeOid, pbeOidSz);
     3262            idx += pbeOidSz;
     3263            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
     3264            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
     3265            /* KDF Algorithm Identifier */
     3266            idx += SetSequence(kdfLen, out + idx);
     3267            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
     3268            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
     3269            idx += sizeof(pbkdf2Oid);
     3270        }
     3271        idx += SetSequence(innerLen, out + idx);
     3272        idx += SetOctetString(saltSz, out + idx);
     3273        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
     3274        ret = SetShortInt(out, &idx, itt, *outSz);
     3275        if (ret > 0)
     3276            ret = 0;
     3277        }
     3278    if (ret == 0) {
     3279        if (version == PKCS5v2) {
     3280            /* Encryption Algorithm Identifier */
     3281            idx += SetSequence(encLen, out + idx);
     3282            idx += SetObjectId(encOidSz, out + idx);
     3283            XMEMCPY(out + idx, encOid, encOidSz);
     3284            idx += encOidSz;
     3285            /* Encryption Algorithm Parameter: CBC IV */
     3286            idx += SetOctetString(blockSz, out + idx);
     3287            XMEMCPY(out + idx, cbcIv, blockSz);
     3288            idx += blockSz;
     3289        }
     3290        idx += SetOctetString(pkcs8KeySz, out + idx);
     3291        /* Default PRF - no need to write out OID */
     3292        idx += pkcs8KeySz;
     3293
     3294        ret = idx;
     3295    }
     3296
     3297    if (pkcs8Key != NULL) {
     3298        ForceZero(pkcs8Key, pkcs8KeySz);
     3299        XFREE(pkcs8Key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     3300        }
     3301#ifdef WOLFSSL_SMALL_STACK
     3302    if (saltTmp != NULL) {
     3303        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3304    }
     3305#endif
     3306
     3307    (void)rng;
     3308
     3309    return ret;
     3310}
    25223311
    25233312/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
    25243313   of input */
    2525 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
    2526 {
    2527     word32 inOutIdx = 0, oid;
     3314int ToTraditionalEnc(byte* input, word32 sz,const char* password,
     3315                     int passwordSz, word32* algId)
     3316{
     3317    word32 inOutIdx = 0, seqEnd, oid;
    25283318    int    ret = 0, first, second, length = 0, version, saltSz, id;
    2529     int    iterations = 0;
     3319    int    iterations = 0, keySz = 0;
    25303320#ifdef WOLFSSL_SMALL_STACK
    25313321    byte*  salt = NULL;
     
    25363326#endif
    25373327
     3328    if (passwordSz < 0) {
     3329        WOLFSSL_MSG("Bad password size");
     3330        return BAD_FUNC_ARG;
     3331    }
     3332
    25383333    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
    25393334        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25403335    }
    25413336
    2542     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
     3337    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
    25433338        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25443339    }
     
    25473342    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
    25483343
    2549     if (CheckAlgo(first, second, &id, &version) < 0) {
     3344    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
    25503345        ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */
    25513346    }
     
    25683363        ERROR_OUT(ASN_PARSE_E, exit_tte);
    25693364    }
     3365    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
     3366     * DEFAULT items. */
     3367    seqEnd = inOutIdx + length;
    25703368
    25713369    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
     
    25913389    }
    25923390
     3391    /* OPTIONAL key length */
     3392    if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
     3393        if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
     3394            ERROR_OUT(ASN_PARSE_E, exit_tte);
     3395        }
     3396    }
     3397
     3398    /* DEFAULT HMAC is SHA-1 */
     3399    if (seqEnd > inOutIdx) {
     3400        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
     3401            ERROR_OUT(ASN_PARSE_E, exit_tte);
     3402        }
     3403    }
     3404
    25933405#ifdef WOLFSSL_SMALL_STACK
    25943406    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    26003412    if (version == PKCS5v2) {
    26013413        /* get encryption algo */
    2602         /* JOHN: New type. Need a little more research. */
    26033414        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
    26043415            ERROR_OUT(ASN_PARSE_E, exit_tte);
    26053416        }
    26063417
    2607         if (CheckAlgoV2(oid, &id) < 0) {
     3418        if (CheckAlgoV2(oid, &id, NULL) < 0) {
    26083419            ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */
    26093420        }
     
    26253436        goto exit_tte;
    26263437
    2627     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
    2628                                    input + inOutIdx, length, version, cbcIv);
     3438    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
     3439                   input + inOutIdx, length, version, cbcIv, 0);
    26293440
    26303441exit_tte:
     
    26363447    if (ret == 0) {
    26373448        XMEMMOVE(input, input + inOutIdx, length);
    2638         ret = ToTraditional(input, length);
     3449        ret = ToTraditional_ex(input, length, algId);
    26393450    }
    26403451
     
    26423453}
    26433454
    2644 /* decrypt PKCS */
    2645 int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
    2646 {
    2647     word32 inOutIdx = 0, oid;
     3455
     3456/* encrypt PKCS 12 content
     3457 *
     3458 * NOTE: if out is NULL then outSz is set with the total buffer size needed and
     3459 *       the error value LENGTH_ONLY_E is returned.
     3460 *
     3461 * input      data to encrypt
     3462 * inputSz    size of input buffer
     3463 * out        buffer to hold the result
     3464 * outSz      size of out buffer
     3465 * password   password if used. Can be NULL for no password
     3466 * passwordSz size of password buffer
     3467 * vPKCS      version of PKCS i.e. PKCS5v2
     3468 * vAlgo      algorithm version
     3469 * salt       buffer holding salt if used. If NULL then a random salt is created
     3470 * saltSz     size of salt buffer if it is not NULL
     3471 * itt        number of iterations used
     3472 * rng        random number generator to use
     3473 * heap       possible heap hint for mallocs/frees
     3474 *
     3475 * returns the total size of encrypted content on success.
     3476 */
     3477int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
     3478        const char* password, int passwordSz, int vPKCS, int vAlgo,
     3479        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
     3480{
     3481    word32 sz;
     3482    word32 inOutIdx = 0;
     3483    word32 tmpIdx   = 0;
     3484    word32 totalSz  = 0;
     3485    word32 seqSz;
     3486    int    ret;
     3487    int    version, id, blockSz = 0;
     3488#ifdef WOLFSSL_SMALL_STACK
     3489    byte*  saltTmp = NULL;
     3490    byte*  cbcIv = NULL;
     3491#else
     3492    byte   saltTmp[MAX_SALT_SIZE];
     3493    byte   cbcIv[MAX_IV_SIZE];
     3494#endif
     3495
     3496    (void)heap;
     3497
     3498    WOLFSSL_ENTER("EncryptContent()");
     3499
     3500    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
     3501        return ASN_INPUT_E;  /* Algo ID error */
     3502
     3503    if (version == PKCS5v2) {
     3504        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
     3505        return BAD_FUNC_ARG;
     3506        }
     3507
     3508    if (saltSz > MAX_SALT_SIZE)
     3509        return ASN_PARSE_E;
     3510
     3511    if (outSz == NULL) {
     3512        return BAD_FUNC_ARG;
     3513    }
     3514
     3515    if (out == NULL) {
     3516        sz = inputSz;
     3517        switch (id) {
     3518        #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA))
     3519            case PBE_MD5_DES:
     3520            case PBE_SHA1_DES:
     3521            case PBE_SHA1_DES3:
     3522                /* set to block size of 8 for DES operations. This rounds up
     3523                 * to the nearest multiple of 8 */
     3524                sz &= 0xfffffff8;
     3525                sz += 8;
     3526                break;
     3527        #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */
     3528        #if !defined(NO_RC4) && !defined(NO_SHA)
     3529            case PBE_SHA1_RC4_128:
     3530                break;
     3531        #endif
     3532            case -1:
     3533                break;
     3534
     3535            default:
     3536                return ALGO_ID_E;
     3537        }
     3538
     3539        if (saltSz <= 0) {
     3540            sz += MAX_SALT_SIZE;
     3541        }
     3542        else {
     3543            sz += saltSz;
     3544        }
     3545
     3546        /* add 2 for tags */
     3547        totalSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
     3548            MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2;
     3549
     3550        /* adjust size to pad */
     3551        totalSz = Pkcs8Pad(NULL, totalSz, blockSz);
     3552
     3553        /* return result */
     3554        *outSz = totalSz;
     3555
     3556        return LENGTH_ONLY_E;
     3557    }
     3558
     3559    if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz)
     3560        return BUFFER_E;
     3561
     3562    sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0);
     3563    inOutIdx += sz; totalSz += sz;
     3564    tmpIdx = inOutIdx;
     3565    tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */
     3566    out[tmpIdx++] = ASN_OCTET_STRING;
     3567
     3568    /* create random salt if one not provided */
     3569    if (salt == NULL || saltSz <= 0) {
     3570        saltSz = 8;
     3571    #ifdef WOLFSSL_SMALL_STACK
     3572        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3573        if (saltTmp == NULL)
     3574            return MEMORY_E;
     3575    #endif
     3576        salt = saltTmp;
     3577
     3578        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
     3579            WOLFSSL_MSG("Error generating random salt");
     3580        #ifdef WOLFSSL_SMALL_STACK
     3581            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3582        #endif
     3583            return ret;
     3584        }
     3585    }
     3586
     3587    if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) {
     3588    #ifdef WOLFSSL_SMALL_STACK
     3589        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3590    #endif
     3591        return BUFFER_E;
     3592    }
     3593
     3594    sz = SetLength(saltSz, out + tmpIdx);
     3595    tmpIdx += sz;
     3596
     3597    XMEMCPY(out + tmpIdx, salt, saltSz);
     3598    tmpIdx += saltSz;
     3599
     3600    /* place iteration setting in buffer */
     3601    ret = SetShortInt(out, &tmpIdx, itt, *outSz);
     3602    if (ret < 0) {
     3603    #ifdef WOLFSSL_SMALL_STACK
     3604        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3605    #endif
     3606        return ret;
     3607    }
     3608
     3609    /* rewind and place sequence */
     3610    sz = tmpIdx - inOutIdx - MAX_SEQ_SZ;
     3611    seqSz = SetSequence(sz, out + inOutIdx);
     3612    XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz);
     3613    inOutIdx += seqSz; totalSz += seqSz;
     3614    inOutIdx += sz; totalSz += sz;
     3615
     3616#ifdef WOLFSSL_SMALL_STACK
     3617    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3618    if (cbcIv == NULL) {
     3619        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3620        return MEMORY_E;
     3621    }
     3622#endif
     3623
     3624    if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)
     3625        return BUFFER_E;
     3626
     3627    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; totalSz++;
     3628    sz = SetLength(inputSz, out + inOutIdx);
     3629    inOutIdx += sz; totalSz += sz;
     3630
     3631    /* get pad size and verify buffer room */
     3632    sz = Pkcs8Pad(NULL, inputSz, blockSz);
     3633    if (sz + inOutIdx > *outSz)
     3634        return BUFFER_E;
     3635
     3636    /* copy input to output buffer and pad end */
     3637    XMEMCPY(out + inOutIdx, input, inputSz);
     3638    sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);
     3639    totalSz += sz;
     3640
     3641    /* encrypt */
     3642    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
     3643                   out + inOutIdx, sz, version, cbcIv, 1)) < 0) {
     3644
     3645    #ifdef WOLFSSL_SMALL_STACK
     3646        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
     3647        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3648    #endif
     3649        return ret;  /* encrypt failure */
     3650    }
     3651
     3652#ifdef WOLFSSL_SMALL_STACK
     3653    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
     3654    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
     3655#endif
     3656
     3657    (void)rng;
     3658
     3659    return totalSz;
     3660}
     3661
     3662
     3663/* decrypt PKCS
     3664 *
     3665 * NOTE: input buffer is overwritten with decrypted data!
     3666 *
     3667 * input[in/out] data to decrypt and results are written to
     3668 * sz            size of input buffer
     3669 * password      password if used. Can be NULL for no password
     3670 * passwordSz    size of password buffer
     3671 *
     3672 * returns the total size of decrypted content on success.
     3673 */
     3674int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
     3675{
     3676    word32 inOutIdx = 0, seqEnd, oid;
    26483677    int    ret = 0;
    26493678    int    first, second, length = 0, version, saltSz, id;
    2650     int    iterations = 0;
     3679    int    iterations = 0, keySz = 0;
    26513680#ifdef WOLFSSL_SMALL_STACK
    26523681    byte*  salt = NULL;
     
    26573686#endif
    26583687
    2659     if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0) {
     3688    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
    26603689        ERROR_OUT(ASN_PARSE_E, exit_dc);
    26613690    }
     
    26643693    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
    26653694
    2666     if (CheckAlgo(first, second, &id, &version) < 0) {
     3695    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
    26673696        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
    26683697    }
     
    26853714        ERROR_OUT(ASN_PARSE_E, exit_dc);
    26863715    }
     3716    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
     3717     * DEFAULT items. */
     3718    seqEnd = inOutIdx + length;
    26873719
    26883720    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
     
    27083740    }
    27093741
     3742    /* OPTIONAL key length */
     3743    if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
     3744        if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
     3745            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3746        }
     3747    }
     3748
     3749    /* DEFAULT HMAC is SHA-1 */
     3750    if (seqEnd > inOutIdx) {
     3751        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
     3752            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3753        }
     3754    }
     3755
    27103756#ifdef WOLFSSL_SMALL_STACK
    27113757    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    27173763    if (version == PKCS5v2) {
    27183764        /* get encryption algo */
    2719         /* JOHN: New type. Need a little more research. */
    27203765        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
    27213766            ERROR_OUT(ASN_PARSE_E, exit_dc);
    27223767        }
    27233768
    2724         if (CheckAlgoV2(oid, &id) < 0) {
     3769        if (CheckAlgoV2(oid, &id, NULL) < 0) {
    27253770            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
    27263771        }
     
    27303775            goto exit_dc;
    27313776
     3777        if (length > MAX_IV_SIZE) {
     3778            ERROR_OUT(ASN_PARSE_E, exit_dc);
     3779        }
     3780
    27323781        XMEMCPY(cbcIv, &input[inOutIdx], length);
    27333782        inOutIdx += length;
     
    27423791    }
    27433792
    2744     ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
    2745                                    input + inOutIdx, length, version, cbcIv);
     3793    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
     3794                   input + inOutIdx, length, version, cbcIv, 0);
    27463795
    27473796exit_dc:
     
    27643813
    27653814#ifndef HAVE_USER_RSA
    2766 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
    2767                        word32 inSz)
    2768 {
     3815int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
     3816    const byte** n, word32* nSz, const byte** e, word32* eSz)
     3817{
     3818    int ret = 0;
    27693819    int  length;
    27703820#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
    27713821    byte b;
    27723822#endif
    2773     int ret;
    2774 
    2775     if (input == NULL || inOutIdx == NULL || key == NULL)
     3823
     3824    if (input == NULL || inOutIdx == NULL)
    27763825        return BAD_FUNC_ARG;
    27773826
    27783827    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
    27793828        return ASN_PARSE_E;
    2780 
    2781     key->type = RSA_PUBLIC;
    27823829
    27833830#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
     
    27953842
    27963843        /* Option NULL ASN.1 tag */
     3844        if (*inOutIdx  >= inSz) {
     3845            return BUFFER_E;
     3846        }
    27973847        if (input[*inOutIdx] == ASN_TAG_NULL) {
    27983848            ret = GetASNNull(input, inOutIdx, inSz);
     
    28113861#endif /* OPENSSL_EXTRA */
    28123862
    2813     if (GetInt(&key->n,  input, inOutIdx, inSz) < 0)
     3863    /* Get modulus */
     3864    ret = GetASNInt(input, inOutIdx, &length, inSz);
     3865    if (ret < 0) {
    28143866        return ASN_RSA_KEY_E;
    2815     if (GetInt(&key->e,  input, inOutIdx, inSz) < 0) {
    2816         mp_clear(&key->n);
     3867    }
     3868    if (nSz)
     3869        *nSz = length;
     3870    if (n)
     3871        *n = &input[*inOutIdx];
     3872    *inOutIdx += length;
     3873
     3874    /* Get exponent */
     3875    ret = GetASNInt(input, inOutIdx, &length, inSz);
     3876    if (ret < 0) {
    28173877        return ASN_RSA_KEY_E;
    28183878    }
    2819 
    2820 #ifdef WOLFSSL_XILINX_CRYPT
    2821     if (wc_InitRsaHw(key) != 0) {
    2822         return BAD_STATE_E;
    2823     }
    2824 #endif
    2825 
    2826     return 0;
     3879    if (eSz)
     3880        *eSz = length;
     3881    if (e)
     3882        *e = &input[*inOutIdx];
     3883    *inOutIdx += length;
     3884
     3885    return ret;
     3886    }
     3887
     3888int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
     3889                       word32 inSz)
     3890{
     3891    int ret;
     3892    const byte *n = NULL, *e = NULL;
     3893    word32 nSz = 0, eSz = 0;
     3894
     3895    if (key == NULL)
     3896        return BAD_FUNC_ARG;
     3897
     3898    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
     3899    if (ret == 0) {
     3900        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
     3901    }
     3902
     3903    return ret;
    28273904}
    28283905
     
    28433920        return ASN_GETINT_E;
    28443921    }
     3922#ifdef HAVE_WOLF_BIGINT
     3923    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
     3924        mp_clear(&key->n);
     3925        return ASN_GETINT_E;
     3926    }
     3927#endif /* HAVE_WOLF_BIGINT */
    28453928
    28463929    if (mp_init(&key->e) != MP_OKAY) {
     
    28543937        return ASN_GETINT_E;
    28553938    }
     3939#ifdef HAVE_WOLF_BIGINT
     3940    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
     3941        mp_clear(&key->n);
     3942        mp_clear(&key->e);
     3943        return ASN_GETINT_E;
     3944    }
     3945#endif /* HAVE_WOLF_BIGINT */
    28563946
    28573947#ifdef WOLFSSL_XILINX_CRYPT
     
    28643954}
    28653955#endif /* HAVE_USER_RSA */
    2866 #endif
     3956#endif /* !NO_RSA */
    28673957
    28683958#ifndef NO_DH
     
    29944084
    29954085/* Release Tmp DSA resources */
    2996 static INLINE void FreeTmpDsas(byte** tmps, void* heap)
     4086static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
    29974087{
    29984088    int i;
     
    30764166
    30774167
    3078 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
     4168void InitDecodedCert(DecodedCert* cert,
     4169                     const byte* source, word32 inSz, void* heap)
    30794170{
    30804171    if (cert != NULL) {
     
    31364227        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
    31374228    if (cert->pubKeyStored == 1)
    3138         XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
     4229        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
    31394230    if (cert->weOwnAltNames && cert->altNames)
    31404231        FreeAltNames(cert->altNames, cert->heap);
     
    31524243    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
    31534244#endif /* WOLFSSL_SEP */
    3154 #ifdef OPENSSL_EXTRA
     4245#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    31554246    if (cert->issuerName.fullName != NULL)
    31564247        XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
     
    32314322{
    32324323    int length;
    3233 #ifdef HAVE_NTRU
     4324#if defined(HAVE_ECC) || defined(HAVE_NTRU)
    32344325    int tmpIdx = cert->srcIdx;
    32354326#endif
     
    32644355            word32      rc;
    32654356            word32      remaining = cert->maxIdx - cert->srcIdx;
     4357            byte*       publicKey;
    32664358#ifdef WOLFSSL_SMALL_STACK
    32674359            byte*       keyBlob = NULL;
     
    32774369
    32784370#ifdef WOLFSSL_SMALL_STACK
    3279             keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL,
     4371            keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,
    32804372                                     DYNAMIC_TYPE_TMP_BUFFER);
    32814373            if (keyBlob == NULL)
     
    32874379            if (rc != NTRU_OK) {
    32884380#ifdef WOLFSSL_SMALL_STACK
    3289                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4381                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    32904382#endif
    32914383                return ASN_NTRU_KEY_E;
     
    32944386            if ( (next - key) < 0) {
    32954387#ifdef WOLFSSL_SMALL_STACK
    3296                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4388                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    32974389#endif
    32984390                return ASN_NTRU_KEY_E;
     
    33014393            cert->srcIdx = tmpIdx + (int)(next - key);
    33024394
    3303             cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap,
     4395            publicKey = (byte*)XMALLOC(keyLen, cert->heap,
    33044396                                              DYNAMIC_TYPE_PUBLIC_KEY);
    3305             if (cert->publicKey == NULL) {
     4397            if (publicKey == NULL) {
    33064398#ifdef WOLFSSL_SMALL_STACK
    3307                 XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4399                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    33084400#endif
    33094401                return MEMORY_E;
    33104402            }
    3311             XMEMCPY(cert->publicKey, keyBlob, keyLen);
     4403            XMEMCPY(publicKey, keyBlob, keyLen);
     4404            cert->publicKey = publicKey;
    33124405            cert->pubKeyStored = 1;
    33134406            cert->pubKeySize   = keyLen;
    33144407
    33154408#ifdef WOLFSSL_SMALL_STACK
    3316             XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4409            XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    33174410#endif
    33184411
     
    33244417        {
    33254418            int ret;
    3326 
     4419            byte seq[5];
     4420            int pubLen = length + 1 + SetLength(length, seq);
     4421            byte* publicKey;
     4422
     4423            if (cert->source[cert->srcIdx] !=
     4424                                             (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
    33274425            if (GetObjectId(cert->source, &cert->srcIdx,
    33284426                            &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
     
    33374435            if (ret != 0)
    33384436                return ret;
    3339 
    3340             cert->publicKey = (byte*)XMALLOC(length, cert->heap,
     4437            }
     4438
     4439            publicKey = (byte*)XMALLOC(pubLen, cert->heap,
    33414440                                             DYNAMIC_TYPE_PUBLIC_KEY);
    3342             if (cert->publicKey == NULL)
     4441            if (publicKey == NULL)
    33434442                return MEMORY_E;
    3344             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
     4443            XMEMCPY(publicKey, &cert->source[tmpIdx], pubLen);
     4444            cert->publicKey = publicKey;
    33454445            cert->pubKeyStored = 1;
    3346             cert->pubKeySize   = length;
    3347 
    3348             cert->srcIdx += length;
     4446            cert->pubKeySize   = pubLen;
     4447
     4448            cert->srcIdx = tmpIdx + pubLen;
    33494449
    33504450            return 0;
     
    33544454        case ED25519k:
    33554455        {
     4456            byte* publicKey;
    33564457            int ret;
    33574458
     
    33634464                return ret;
    33644465
    3365             cert->publicKey = (byte*) XMALLOC(length, cert->heap,
     4466            publicKey = (byte*) XMALLOC(length, cert->heap,
    33664467                                              DYNAMIC_TYPE_PUBLIC_KEY);
    3367             if (cert->publicKey == NULL)
     4468            if (publicKey == NULL)
    33684469                return MEMORY_E;
    3369             XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
     4470            XMEMCPY(publicKey, &cert->source[cert->srcIdx], length);
     4471            cert->publicKey = publicKey;
    33704472            cert->pubKeyStored = 1;
    33714473            cert->pubKeySize   = length;
     
    33804482    }
    33814483}
     4484
     4485#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4486WOLFSSL_LOCAL int OBJ_sn2nid(const char *sn)
     4487{
     4488    static const struct {
     4489        const char *sn;
     4490        int  nid;
     4491    } sn2nid[] = {
     4492        {WOLFSSL_COMMON_NAME, NID_commonName},
     4493        {WOLFSSL_COUNTRY_NAME, NID_countryName},
     4494        {WOLFSSL_LOCALITY_NAME, NID_localityName},
     4495        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
     4496        {WOLFSSL_ORG_NAME, NID_organizationName},
     4497        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
     4498        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
     4499        {NULL, -1}};
     4500
     4501    int i;
     4502    WOLFSSL_ENTER("OBJ_osn2nid");
     4503    #ifdef HAVE_ECC
     4504    /* Nginx uses this OpenSSL string. */
     4505    if (XSTRNCMP(sn, "prime256v1", 10) == 0)
     4506        sn = "SECP256R1";
     4507    if (XSTRNCMP(sn, "secp384r1", 10) == 0)
     4508        sn = "SECP384R1";
     4509    /* find based on name and return NID */
     4510    for (i = 0; i < ecc_sets[i].size; i++) {
     4511        if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
     4512            return ecc_sets[i].id;
     4513        }
     4514    }
     4515    #endif
     4516
     4517    for(i=0; sn2nid[i].sn != NULL; i++) {
     4518        if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {
     4519            return sn2nid[i].nid;
     4520        }
     4521    }
     4522
     4523    return NID_undef;
     4524}
     4525#endif
    33824526
    33834527/* process NAME, either issuer or subject */
     
    33904534    byte*  hash;
    33914535    word32 idx;
    3392     #ifdef OPENSSL_EXTRA
     4536    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    33934537        DecodedName* dName =
    33944538                  (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
     4539        int dcnum = 0;
    33954540    #endif /* OPENSSL_EXTRA */
    33964541
     
    34044549        full = cert->subject;
    34054550        hash = cert->subjectHash;
     4551    }
     4552
     4553    if (cert->srcIdx >= cert->maxIdx) {
     4554        return BUFFER_E;
    34064555    }
    34074556
     
    34214570        return ASN_PARSE_E;
    34224571
    3423 #ifdef NO_SHA
    3424     ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
    3425 #else
    3426     ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
    3427 #endif
     4572    ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);
    34284573    if (ret != 0)
    34294574        return ret;
     
    34324577    idx = 0;
    34334578
    3434 #ifdef HAVE_PKCS7
     4579#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
    34354580    /* store pointer to raw issuer */
    34364581    if (nameType == ISSUER) {
     
    34714616        /* v1 name types */
    34724617        if (joint[0] == 0x55 && joint[1] == 0x04) {
     4618            const char*  copy = NULL;
     4619            int    strLen;
    34734620            byte   id;
    3474             byte   copy = FALSE;
    3475             int    strLen;
    34764621
    34774622            cert->srcIdx += 2;
     
    34964641                }
    34974642
    3498                 if (!tooBig) {
    3499                     XMEMCPY(&full[idx], "/CN=", 4);
    3500                     idx += 4;
    3501                     copy = TRUE;
    3502                 }
    3503                 #ifdef OPENSSL_EXTRA
     4643                copy = WOLFSSL_COMMON_NAME;
     4644                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35044645                    dName->cnIdx = cert->srcIdx;
    35054646                    dName->cnLen = strLen;
     
    35074648            }
    35084649            else if (id == ASN_SUR_NAME) {
    3509                 if (!tooBig) {
    3510                     XMEMCPY(&full[idx], "/SN=", 4);
    3511                     idx += 4;
    3512                     copy = TRUE;
    3513                 }
     4650                copy = WOLFSSL_SUR_NAME;
    35144651                #ifdef WOLFSSL_CERT_GEN
    35154652                    if (nameType == SUBJECT) {
     
    35194656                    }
    35204657                #endif /* WOLFSSL_CERT_GEN */
    3521                 #ifdef OPENSSL_EXTRA
     4658                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35224659                    dName->snIdx = cert->srcIdx;
    35234660                    dName->snLen = strLen;
     
    35254662            }
    35264663            else if (id == ASN_COUNTRY_NAME) {
    3527                 if (!tooBig) {
    3528                     XMEMCPY(&full[idx], "/C=", 3);
    3529                     idx += 3;
    3530                     copy = TRUE;
    3531                 }
     4664                copy = WOLFSSL_COUNTRY_NAME;
    35324665                #ifdef WOLFSSL_CERT_GEN
    35334666                    if (nameType == SUBJECT) {
     
    35374670                    }
    35384671                #endif /* WOLFSSL_CERT_GEN */
    3539                 #ifdef OPENSSL_EXTRA
     4672                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35404673                    dName->cIdx = cert->srcIdx;
    35414674                    dName->cLen = strLen;
     
    35434676            }
    35444677            else if (id == ASN_LOCALITY_NAME) {
    3545                 if (!tooBig) {
    3546                     XMEMCPY(&full[idx], "/L=", 3);
    3547                     idx += 3;
    3548                     copy = TRUE;
    3549                 }
     4678                copy = WOLFSSL_LOCALITY_NAME;
    35504679                #ifdef WOLFSSL_CERT_GEN
    35514680                    if (nameType == SUBJECT) {
     
    35554684                    }
    35564685                #endif /* WOLFSSL_CERT_GEN */
    3557                 #ifdef OPENSSL_EXTRA
     4686                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35584687                    dName->lIdx = cert->srcIdx;
    35594688                    dName->lLen = strLen;
     
    35614690            }
    35624691            else if (id == ASN_STATE_NAME) {
    3563                 if (!tooBig) {
    3564                     XMEMCPY(&full[idx], "/ST=", 4);
    3565                     idx += 4;
    3566                     copy = TRUE;
    3567                 }
     4692                copy = WOLFSSL_STATE_NAME;
    35684693                #ifdef WOLFSSL_CERT_GEN
    35694694                    if (nameType == SUBJECT) {
     
    35734698                    }
    35744699                #endif /* WOLFSSL_CERT_GEN */
    3575                 #ifdef OPENSSL_EXTRA
     4700                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35764701                    dName->stIdx = cert->srcIdx;
    35774702                    dName->stLen = strLen;
     
    35794704            }
    35804705            else if (id == ASN_ORG_NAME) {
    3581                 if (!tooBig) {
    3582                     XMEMCPY(&full[idx], "/O=", 3);
    3583                     idx += 3;
    3584                     copy = TRUE;
    3585                 }
     4706                copy = WOLFSSL_ORG_NAME;
    35864707                #ifdef WOLFSSL_CERT_GEN
    35874708                    if (nameType == SUBJECT) {
     
    35914712                    }
    35924713                #endif /* WOLFSSL_CERT_GEN */
    3593                 #ifdef OPENSSL_EXTRA
     4714                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    35944715                    dName->oIdx = cert->srcIdx;
    35954716                    dName->oLen = strLen;
     
    35974718            }
    35984719            else if (id == ASN_ORGUNIT_NAME) {
    3599                 if (!tooBig) {
    3600                     XMEMCPY(&full[idx], "/OU=", 4);
    3601                     idx += 4;
    3602                     copy = TRUE;
    3603                 }
     4720                copy = WOLFSSL_ORGUNIT_NAME;
    36044721                #ifdef WOLFSSL_CERT_GEN
    36054722                    if (nameType == SUBJECT) {
     
    36094726                    }
    36104727                #endif /* WOLFSSL_CERT_GEN */
    3611                 #ifdef OPENSSL_EXTRA
     4728                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36124729                    dName->ouIdx = cert->srcIdx;
    36134730                    dName->ouLen = strLen;
     
    36154732            }
    36164733            else if (id == ASN_SERIAL_NUMBER) {
    3617                 if (!tooBig) {
    3618                    XMEMCPY(&full[idx], "/serialNumber=", 14);
    3619                    idx += 14;
    3620                    copy = TRUE;
     4734                copy = WOLFSSL_SERIAL_NUMBER;
     4735                #ifdef WOLFSSL_CERT_GEN
     4736                    if (nameType == SUBJECT) {
     4737                        cert->subjectSND = (char*)&cert->source[cert->srcIdx];
     4738                        cert->subjectSNDLen = strLen;
     4739                        cert->subjectSNDEnc = b;
    36214740                }
    3622                 #ifdef OPENSSL_EXTRA
     4741                #endif /* WOLFSSL_CERT_GEN */
     4742                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36234743                    dName->snIdx = cert->srcIdx;
    36244744                    dName->snLen = strLen;
    36254745                #endif /* OPENSSL_EXTRA */
    36264746            }
    3627 
     4747        #ifdef WOLFSSL_CERT_EXT
     4748            else if (id == ASN_BUS_CAT) {
     4749                copy = WOLFSSL_BUS_CAT;
     4750            #ifdef WOLFSSL_CERT_GEN
     4751                if (nameType == SUBJECT) {
     4752                    cert->subjectBC = (char*)&cert->source[cert->srcIdx];
     4753                    cert->subjectBCLen = strLen;
     4754                    cert->subjectBCEnc = b;
     4755                }
     4756            #endif /* WOLFSSL_CERT_GEN */
     4757            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4758                dName->bcIdx = cert->srcIdx;
     4759                dName->bcLen = strLen;
     4760            #endif /* OPENSSL_EXTRA */
     4761            }
     4762        #endif /* WOLFSSL_CERT_EXT */
    36284763            if (copy && !tooBig) {
     4764                XMEMCPY(&full[idx], copy, XSTRLEN(copy));
     4765                idx += (word32)XSTRLEN(copy);
     4766            #ifdef WOLFSSL_WPAS
     4767                full[idx] = '=';
     4768                idx++;
     4769            #endif
    36294770                XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
    36304771                idx += strLen;
     
    36334774            cert->srcIdx += strLen;
    36344775        }
     4776    #ifdef WOLFSSL_CERT_EXT
     4777        else if ((0 == XMEMCMP(&cert->source[cert->srcIdx], ASN_JOI_PREFIX,
     4778                               XSTRLEN(ASN_JOI_PREFIX))) &&
     4779                 ((cert->source[cert->srcIdx + XSTRLEN(ASN_JOI_PREFIX)] ==
     4780                         ASN_JOI_C) ||
     4781                  (cert->source[cert->srcIdx + XSTRLEN(ASN_JOI_PREFIX)] ==
     4782                          ASN_JOI_ST)))
     4783        {
     4784            int strLen;
     4785            byte id;
     4786            const char* copy = NULL;
     4787
     4788            cert->srcIdx += 10;
     4789            id = cert->source[cert->srcIdx++];
     4790            b = cert->source[cert->srcIdx++]; /* encoding */
     4791
     4792            if (GetLength(cert->source, &cert->srcIdx, &strLen,
     4793                          cert->maxIdx) < 0)
     4794                return ASN_PARSE_E;
     4795
     4796            if ((strLen + strlen(WOLFSSL_JOI_ST)) > (ASN_NAME_MAX - idx)) {
     4797                WOLFSSL_MSG("ASN Name too big, skipping");
     4798                tooBig = TRUE;
     4799            }
     4800
     4801            /* Check for jurisdiction of incorporation country name */
     4802            if (id == ASN_JOI_C) {
     4803                copy = WOLFSSL_JOI_C;
     4804                #ifdef WOLFSSL_CERT_GEN
     4805                    if (nameType == SUBJECT) {
     4806                        cert->subjectJC = (char*)&cert->source[cert->srcIdx];
     4807                        cert->subjectJCLen = strLen;
     4808                        cert->subjectJCEnc = b;
     4809                    }
     4810                #endif /* WOLFSSL_CERT_GEN */
     4811                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4812                    dName->jcIdx = cert->srcIdx;
     4813                    dName->jcLen = strLen;
     4814                #endif /* OPENSSL_EXTRA */
     4815            }
     4816
     4817            /* Check for jurisdiction of incorporation state name */
     4818            else if (id == ASN_JOI_ST) {
     4819                copy = WOLFSSL_JOI_ST;
     4820                #ifdef WOLFSSL_CERT_GEN
     4821                    if (nameType == SUBJECT) {
     4822                        cert->subjectJS = (char*)&cert->source[cert->srcIdx];
     4823                        cert->subjectJSLen = strLen;
     4824                        cert->subjectJSEnc = b;
     4825                    }
     4826                #endif /* WOLFSSL_CERT_GEN */
     4827                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
     4828                    dName->jsIdx = cert->srcIdx;
     4829                    dName->jsLen = strLen;
     4830                #endif /* OPENSSL_EXTRA */
     4831            }
     4832
     4833            if ((copy != NULL) && (tooBig != 1)) {
     4834                XMEMCPY(&full[idx], copy, XSTRLEN(copy));
     4835                idx += (word32)XSTRLEN(copy);
     4836            #ifdef WOLFSSL_WPAS
     4837                full[idx] = '=';
     4838                idx++;
     4839            #endif
     4840                XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
     4841                idx += strLen;
     4842            }
     4843
     4844            cert->srcIdx += strLen;
     4845        }
     4846    #endif /* WOLFSSL_CERT_EXT */
    36354847        else {
    36364848            /* skip */
    36374849            byte email = FALSE;
    3638             byte uid   = FALSE;
     4850            byte pilot = FALSE;
     4851            byte id    = 0;
    36394852            int  adv;
    36404853
     
    36424855                email = TRUE;
    36434856
    3644             if (joint[0] == 0x9  && joint[1] == 0x92)  /* uid id hdr */
    3645                 uid = TRUE;
     4857            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
     4858                /* last value of OID is the type of pilot attribute */
     4859                id    = cert->source[cert->srcIdx + oidSz - 1];
     4860                pilot = TRUE;
     4861            }
    36464862
    36474863            cert->srcIdx += oidSz + 1;
     
    36714887                    }
    36724888                #endif /* WOLFSSL_CERT_GEN */
    3673                 #ifdef OPENSSL_EXTRA
     4889                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    36744890                    dName->emailIdx = cert->srcIdx;
    36754891                    dName->emailLen = adv;
     
    36854901                            return MEMORY_E;
    36864902                        }
     4903                        emailName->type = 0;
    36874904                        emailName->name = (char*)XMALLOC(adv + 1,
    36884905                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
     
    36924909                            return MEMORY_E;
    36934910                        }
     4911                        emailName->len = adv;
    36944912                        XMEMCPY(emailName->name,
    36954913                                              &cert->source[cert->srcIdx], adv);
    3696                         emailName->name[adv] = 0;
     4914                        emailName->name[adv] = '\0';
    36974915
    36984916                        emailName->next = cert->altEmailNames;
     
    37064924            }
    37074925
    3708             if (uid) {
     4926            if (pilot) {
    37094927                if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
    37104928                    WOLFSSL_MSG("ASN name too big, skipping");
     
    37124930                }
    37134931                if (!tooBig) {
     4932                    switch (id) {
     4933                        case ASN_USER_ID:
    37144934                    XMEMCPY(&full[idx], "/UID=", 5);
    37154935                    idx += 5;
    3716 
     4936                        #if defined(OPENSSL_EXTRA) || \
     4937                            defined(OPENSSL_EXTRA_X509_SMALL)
     4938                            dName->uidIdx = cert->srcIdx;
     4939                            dName->uidLen = adv;
     4940                        #endif /* OPENSSL_EXTRA */
     4941                            break;
     4942
     4943                        case ASN_DOMAIN_COMPONENT:
     4944                            XMEMCPY(&full[idx], "/DC=", 4);
     4945                            idx += 4;
     4946                        #if defined(OPENSSL_EXTRA) || \
     4947                            defined(OPENSSL_EXTRA_X509_SMALL)
     4948                            dName->dcIdx[dcnum] = cert->srcIdx;
     4949                            dName->dcLen[dcnum] = adv;
     4950                            dName->dcNum = dcnum + 1;
     4951                            dcnum++;
     4952                        #endif /* OPENSSL_EXTRA */
     4953                            break;
     4954
     4955                        default:
     4956                            WOLFSSL_MSG("Unknown pilot attribute type");
     4957                            return ASN_PARSE_E;
     4958                    }
    37174959                    XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
    37184960                    idx += adv;
    37194961                }
    3720                 #ifdef OPENSSL_EXTRA
    3721                     dName->uidIdx = cert->srcIdx;
    3722                     dName->uidLen = adv;
    3723                 #endif /* OPENSSL_EXTRA */
    37244962            }
    37254963
     
    37294967    full[idx++] = 0;
    37304968
    3731     #ifdef OPENSSL_EXTRA
     4969    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    37324970    {
    37334971        int totalLen = 0;
     4972        int i = 0;
    37344973
    37354974        if (dName->cnLen != 0)
     
    37534992        if (dName->serialLen != 0)
    37544993            totalLen += dName->serialLen + 14;
     4994        if (dName->dcNum != 0){
     4995            for (i = 0;i < dName->dcNum;i++)
     4996                totalLen += dName->dcLen[i] + 4;
     4997        }
    37554998
    37564999        dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
     
    37615004            if (dName->cnLen != 0) {
    37625005                dName->entryCount++;
    3763                 XMEMCPY(&dName->fullName[idx], "/CN=", 4);
     5006                XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);
     5007                dName->cnNid = OBJ_sn2nid((const char *)WOLFSSL_COMMON_NAME);
    37645008                idx += 4;
    37655009                XMEMCPY(&dName->fullName[idx],
     
    37705014            if (dName->snLen != 0) {
    37715015                dName->entryCount++;
    3772                 XMEMCPY(&dName->fullName[idx], "/SN=", 4);
     5016                XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);
     5017                dName->snNid = OBJ_sn2nid((const char *)WOLFSSL_SUR_NAME);
    37735018                idx += 4;
    37745019                XMEMCPY(&dName->fullName[idx],
     
    37795024            if (dName->cLen != 0) {
    37805025                dName->entryCount++;
    3781                 XMEMCPY(&dName->fullName[idx], "/C=", 3);
     5026                XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);
     5027                dName->cNid = OBJ_sn2nid((const char *)WOLFSSL_COUNTRY_NAME);
    37825028                idx += 3;
    37835029                XMEMCPY(&dName->fullName[idx],
     
    37885034            if (dName->lLen != 0) {
    37895035                dName->entryCount++;
    3790                 XMEMCPY(&dName->fullName[idx], "/L=", 3);
     5036                XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);
     5037                dName->lNid = OBJ_sn2nid((const char *)WOLFSSL_LOCALITY_NAME);
    37915038                idx += 3;
    37925039                XMEMCPY(&dName->fullName[idx],
     
    37975044            if (dName->stLen != 0) {
    37985045                dName->entryCount++;
    3799                 XMEMCPY(&dName->fullName[idx], "/ST=", 4);
     5046                XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);
     5047                dName->stNid = OBJ_sn2nid((const char *)WOLFSSL_STATE_NAME);
    38005048                idx += 4;
    38015049                XMEMCPY(&dName->fullName[idx],
     
    38065054            if (dName->oLen != 0) {
    38075055                dName->entryCount++;
    3808                 XMEMCPY(&dName->fullName[idx], "/O=", 3);
     5056                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);
     5057                dName->oNid = OBJ_sn2nid((const char *)WOLFSSL_ORG_NAME);
    38095058                idx += 3;
    38105059                XMEMCPY(&dName->fullName[idx],
     
    38155064            if (dName->ouLen != 0) {
    38165065                dName->entryCount++;
    3817                 XMEMCPY(&dName->fullName[idx], "/OU=", 4);
     5066                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);
     5067                dName->ouNid = OBJ_sn2nid((const char *)WOLFSSL_ORGUNIT_NAME);
    38185068                idx += 4;
    38195069                XMEMCPY(&dName->fullName[idx],
     
    38255075                dName->entryCount++;
    38265076                XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
     5077                dName->emailNid = OBJ_sn2nid((const char *)"/emailAddress=");
    38275078                idx += 14;
    38285079                XMEMCPY(&dName->fullName[idx],
     
    38315082                idx += dName->emailLen;
    38325083            }
     5084            for (i = 0;i < dName->dcNum;i++){
     5085                if (dName->dcLen[i] != 0) {
     5086                    dName->entryCount++;
     5087                    XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);
     5088                    idx += 4;
     5089                    XMEMCPY(&dName->fullName[idx],
     5090                                    &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
     5091                    dName->dcIdx[i] = idx;
     5092                    idx += dName->dcLen[i];
     5093                }
     5094            }
    38335095            if (dName->uidLen != 0) {
    38345096                dName->entryCount++;
    38355097                XMEMCPY(&dName->fullName[idx], "/UID=", 5);
     5098                dName->uidNid = OBJ_sn2nid((const char *)"/UID=");
    38365099                idx += 5;
    38375100                XMEMCPY(&dName->fullName[idx],
     
    38425105            if (dName->serialLen != 0) {
    38435106                dName->entryCount++;
    3844                 XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
     5107                XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);
     5108                dName->serialNid = OBJ_sn2nid((const char *)WOLFSSL_SERIAL_NUMBER);
    38455109                idx += 14;
    38465110                XMEMCPY(&dName->fullName[idx],
     
    38605124
    38615125#ifndef NO_ASN_TIME
    3862 #if !defined(NO_TIME_H) && defined(USE_WOLF_VALIDDATE)
    3863 
    3864 /* to the second */
    3865 static int DateGreaterThan(const struct tm* a, const struct tm* b)
    3866 {
    3867     if (a->tm_year > b->tm_year)
    3868         return 1;
    3869 
    3870     if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
    3871         return 1;
    3872 
    3873     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3874            a->tm_mday > b->tm_mday)
    3875         return 1;
    3876 
    3877     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3878         a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
    3879         return 1;
    3880 
    3881     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3882         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
    3883         a->tm_min > b->tm_min)
    3884         return 1;
    3885 
    3886     if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
    3887         a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
    3888         a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
    3889         return 1;
    3890 
    3891     return 0; /* false */
    3892 }
    3893 
    3894 
    3895 static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
    3896 {
    3897     return DateGreaterThan(b,a);
    3898 }
    3899 
    3900 
    3901 #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    3902 int GetTimeString(byte* date, int format, char* buf, int len)
    3903 {
    3904     struct tm t;
    3905     int idx = 0;
    3906 
    3907     if (!ExtractDate(date, format, &t, &idx)) {
    3908         return 0;
    3909     }
    3910 
    3911     if (date[idx] != 'Z') {
    3912         WOLFSSL_MSG("UTCtime, not Zulu") ;
    3913         return 0;
    3914     }
    3915 
    3916     /* place month in buffer */
    3917     buf[0] = '\0';
    3918     switch(t.tm_mon) {
    3919         case 0:  XSTRNCAT(buf, "Jan ", 4); break;
    3920         case 1:  XSTRNCAT(buf, "Feb ", 4); break;
    3921         case 2:  XSTRNCAT(buf, "Mar ", 4); break;
    3922         case 3:  XSTRNCAT(buf, "Apr ", 4); break;
    3923         case 4:  XSTRNCAT(buf, "May ", 4); break;
    3924         case 5:  XSTRNCAT(buf, "Jun ", 4); break;
    3925         case 6:  XSTRNCAT(buf, "Jul ", 4); break;
    3926         case 7:  XSTRNCAT(buf, "Aug ", 4); break;
    3927         case 8:  XSTRNCAT(buf, "Sep ", 4); break;
    3928         case 9:  XSTRNCAT(buf, "Oct ", 4); break;
    3929         case 10: XSTRNCAT(buf, "Nov ", 4); break;
    3930         case 11: XSTRNCAT(buf, "Dec ", 4); break;
    3931         default:
    3932             return 0;
    3933 
    3934     }
    3935     idx = 4; /* use idx now for char buffer */
    3936     buf[idx] = ' ';
    3937 
    3938     XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
    3939               t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
    3940 
    3941     return 1;
    3942 }
    3943 #endif /* WOLFSSL_MYSQL_COMPATIBLE */
     5126
     5127/* two byte date/time, add to value */
     5128static WC_INLINE void GetTime(int* value, const byte* date, int* idx)
     5129{
     5130    int i = *idx;
     5131
     5132    *value += btoi(date[i++]) * 10;
     5133    *value += btoi(date[i++]);
     5134
     5135    *idx = i;
     5136}
    39445137
    39455138int ExtractDate(const unsigned char* date, unsigned char format,
     
    39575150        certTime->tm_year += btoi(date[*idx]) * 1000; *idx = *idx + 1;
    39585151        certTime->tm_year += btoi(date[*idx]) * 100;  *idx = *idx + 1;
    3959     }
     5152}
    39605153
    39615154    /* adjust tm_year, tm_mon */
     
    39705163}
    39715164
     5165
     5166#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
     5167    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     5168int GetTimeString(byte* date, int format, char* buf, int len)
     5169{
     5170    struct tm t;
     5171    int idx = 0;
     5172
     5173    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
     5174        return 0;
     5175    }
     5176
     5177    if (date[idx] != 'Z') {
     5178        WOLFSSL_MSG("UTCtime, not Zulu") ;
     5179        return 0;
     5180    }
     5181
     5182    /* place month in buffer */
     5183    buf[0] = '\0';
     5184    switch(t.tm_mon) {
     5185        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
     5186        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
     5187        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
     5188        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
     5189        case 4:  XSTRNCAT(buf, "May ", 5); break;
     5190        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
     5191        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
     5192        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
     5193        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
     5194        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
     5195        case 10: XSTRNCAT(buf, "Nov ", 5); break;
     5196        case 11: XSTRNCAT(buf, "Dec ", 5); break;
     5197        default:
     5198            return 0;
     5199
     5200    }
     5201    idx = 4; /* use idx now for char buffer */
     5202
     5203    XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
     5204              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
     5205
     5206    return 1;
     5207}
     5208#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
     5209
     5210
     5211#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
     5212
     5213/* Set current time string, either UTC or GeneralizedTime.
     5214 * (void*) tm should be a pointer to time_t, output is placed in buf.
     5215 *
     5216 * Return time string length placed in buf on success, negative on error */
     5217int GetAsnTimeString(void* currTime, byte* buf, word32 len)
     5218{
     5219    struct tm* ts      = NULL;
     5220    struct tm* tmpTime = NULL;
     5221#if defined(NEED_TMP_TIME)
     5222    struct tm tmpTimeStorage;
     5223    tmpTime = &tmpTimeStorage;
     5224#else
     5225    (void)tmpTime;
     5226#endif
     5227    byte* data_ptr  = buf;
     5228    word32 data_len = 0;
     5229    int year, mon, day, hour, mini, sec;
     5230
     5231    WOLFSSL_ENTER("SetAsnTimeString");
     5232
     5233    if (buf == NULL || len == 0)
     5234        return BAD_FUNC_ARG;
     5235
     5236    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
     5237    if (ts == NULL){
     5238        WOLFSSL_MSG("failed to get time data.");
     5239        return ASN_TIME_E;
     5240    }
     5241
     5242    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
     5243     * the null terminator. ASN encoded values leave off the terminator. */
     5244
     5245    if (ts->tm_year >= 50 && ts->tm_year < 150) {
     5246        /* UTC Time */
     5247        char utc_str[ASN_UTC_TIME_SIZE];
     5248        data_len = ASN_UTC_TIME_SIZE - 1 + 2;
     5249
     5250        if (len < data_len)
     5251            return BUFFER_E;
     5252
     5253        if (ts->tm_year >= 50 && ts->tm_year < 100) {
     5254            year = ts->tm_year;
     5255        } else if (ts->tm_year >= 100 && ts->tm_year < 150) {
     5256            year = ts->tm_year - 100;
     5257        }
     5258        else {
     5259            WOLFSSL_MSG("unsupported year range");
     5260            return BAD_FUNC_ARG;
     5261    }
     5262        mon  = ts->tm_mon + 1;
     5263        day  = ts->tm_mday;
     5264        hour = ts->tm_hour;
     5265        mini = ts->tm_min;
     5266        sec  = ts->tm_sec;
     5267        XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
     5268                  "%02d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
     5269        *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
     5270        /* -1 below excludes null terminator */
     5271        *data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;
     5272        XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);
     5273
     5274    } else {
     5275        /* GeneralizedTime */
     5276        char gt_str[ASN_GENERALIZED_TIME_SIZE];
     5277        data_len = ASN_GENERALIZED_TIME_SIZE - 1 + 2;
     5278
     5279        if (len < data_len)
     5280            return BUFFER_E;
     5281
     5282        year = ts->tm_year + 1900;
     5283        mon  = ts->tm_mon + 1;
     5284        day  = ts->tm_mday;
     5285        hour = ts->tm_hour;
     5286        mini = ts->tm_min;
     5287        sec  = ts->tm_sec;
     5288        XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
     5289                  "%4d%02d%02d%02d%02d%02dZ", year, mon, day, hour, mini, sec);
     5290        *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
     5291        /* -1 below excludes null terminator */
     5292        *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;
     5293        XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);
     5294    }
     5295
     5296    return data_len;
     5297}
     5298
     5299#endif /* !NO_ASN_TIME && HAVE_PKCS7 */
     5300
     5301
     5302#if defined(USE_WOLF_VALIDDATE)
     5303
     5304/* to the second */
     5305static int DateGreaterThan(const struct tm* a, const struct tm* b)
     5306{
     5307    if (a->tm_year > b->tm_year)
     5308        return 1;
     5309
     5310    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
     5311        return 1;
     5312
     5313    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5314           a->tm_mday > b->tm_mday)
     5315        return 1;
     5316
     5317    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5318        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
     5319        return 1;
     5320
     5321    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5322        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
     5323        a->tm_min > b->tm_min)
     5324        return 1;
     5325
     5326    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
     5327        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
     5328        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
     5329    return 1;
     5330
     5331    return 0; /* false */
     5332}
     5333
     5334
     5335static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
     5336{
     5337    return DateGreaterThan(b,a);
     5338}
    39725339
    39735340/* like atoi but only use first byte */
     
    40465413    return 1;
    40475414}
    4048 #endif /* !NO_TIME_H && USE_WOLF_VALIDDATE */
     5415#endif /* USE_WOLF_VALIDDATE */
    40495416
    40505417int wc_GetTime(void* timePtr, word32 timeSize)
     
    40675434#endif /* !NO_ASN_TIME */
    40685435
    4069 static int GetDate(DecodedCert* cert, int dateType)
     5436
     5437/* Get date buffer, format and length. Returns 0=success or error */
     5438static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
     5439                        byte* pFormat, int* pLength, word32 maxIdx)
    40705440{
    40715441    int    length;
     5442    byte format;
     5443
     5444    if (source == NULL || idx == NULL)
     5445        return BAD_FUNC_ARG;
     5446
     5447    /* get ASN format header */
     5448    if (*idx+1 > maxIdx)
     5449        return BUFFER_E;
     5450    format = source[*idx];
     5451    *idx += 1;
     5452    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
     5453        return ASN_TIME_E;
     5454
     5455    /* get length */
     5456    if (GetLength(source, idx, &length, maxIdx) < 0)
     5457        return ASN_PARSE_E;
     5458    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
     5459        return ASN_DATE_SZ_E;
     5460
     5461    /* return format, date and length */
     5462    if (pFormat)
     5463        *pFormat = format;
     5464    if (pDate)
     5465        *pDate = &source[*idx];
     5466    if (pLength)
     5467        *pLength = length;
     5468
     5469    *idx += length;
     5470
     5471    return 0;
     5472}
     5473
     5474static int GetDate(DecodedCert* cert, int dateType, int verify)
     5475{
     5476    int    ret, length;
     5477    const byte *datePtr = NULL;
    40725478    byte   date[MAX_DATE_SIZE];
    4073     byte   b;
     5479    byte   format;
    40745480    word32 startIdx = 0;
    4075 
    4076     XMEMSET(date, 0, MAX_DATE_SIZE);
    40775481
    40785482    if (dateType == BEFORE)
     
    40825486    startIdx = cert->srcIdx;
    40835487
    4084     b = cert->source[cert->srcIdx++];
    4085     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
    4086         return ASN_TIME_E;
    4087 
    4088     if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
    4089         return ASN_PARSE_E;
    4090 
    4091     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
    4092         return ASN_DATE_SZ_E;
    4093 
    4094     XMEMCPY(date, &cert->source[cert->srcIdx], length);
    4095     cert->srcIdx += length;
     5488    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
     5489                      &length, cert->maxIdx);
     5490    if (ret < 0)
     5491        return ret;
     5492
     5493    XMEMSET(date, 0, MAX_DATE_SIZE);
     5494    XMEMCPY(date, datePtr, length);
    40965495
    40975496    if (dateType == BEFORE)
     
    41015500
    41025501#ifndef NO_ASN_TIME
    4103     if (!XVALIDATE_DATE(date, b, dateType)) {
     5502    if (verify != NO_VERIFY && !XVALIDATE_DATE(date, format, dateType)) {
    41045503        if (dateType == BEFORE)
    41055504            return ASN_BEFORE_DATE_E;
     
    41075506            return ASN_AFTER_DATE_E;
    41085507    }
     5508#else
     5509    (void)verify;
    41095510#endif
    41105511
     
    41205521        return ASN_PARSE_E;
    41215522
    4122     if (GetDate(cert, BEFORE) < 0 && verify != NO_VERIFY)
     5523    if (GetDate(cert, BEFORE, verify) < 0)
    41235524        badDate = ASN_BEFORE_DATE_E;           /* continue parsing */
    41245525
    4125     if (GetDate(cert, AFTER) < 0 && verify != NO_VERIFY)
     5526    if (GetDate(cert, AFTER, verify) < 0)
    41265527        return ASN_AFTER_DATE_E;
    41275528
     
    41315532    return 0;
    41325533}
     5534
     5535
     5536int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
     5537    byte* format, int* length)
     5538{
     5539    int ret;
     5540    word32 idx = 0;
     5541
     5542    ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
     5543    if (ret < 0)
     5544        return ret;
     5545
     5546    return 0;
     5547}
     5548
     5549#ifndef NO_ASN_TIME
     5550int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
     5551    struct tm* timearg)
     5552{
     5553    int idx = 0;
     5554    (void)length;
     5555    if (!ExtractDate(date, format, timearg, &idx))
     5556        return ASN_TIME_E;
     5557    return 0;
     5558}
     5559
     5560#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
     5561int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
     5562{
     5563    int ret = 0;
     5564    const byte* date;
     5565    byte format;
     5566    int length;
     5567
     5568    if (cert == NULL)
     5569        return BAD_FUNC_ARG;
     5570
     5571    if (before && cert->beforeDateSz > 0) {
     5572        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
     5573                             &format, &length);
     5574        if (ret == 0)
     5575            ret = wc_GetDateAsCalendarTime(date, length, format, before);
     5576    }
     5577    if (after && cert->afterDateSz > 0) {
     5578        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
     5579                             &format, &length);
     5580        if (ret == 0)
     5581            ret = wc_GetDateAsCalendarTime(date, length, format, after);
     5582    }
     5583
     5584    return ret;
     5585}
     5586#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
     5587#endif /* !NO_ASN_TIME */
    41335588
    41345589
     
    42675722
    42685723
    4269 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
     5724#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
    42705725
    42715726static int SetCurve(ecc_key* key, byte* output)
     
    43065761}
    43075762
    4308 #endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
    4309 
    4310 
    4311 static INLINE int IsSigAlgoECDSA(int algoOID)
     5763#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
     5764
     5765
     5766#ifdef HAVE_ECC
     5767static WC_INLINE int IsSigAlgoECDSA(int algoOID)
    43125768{
    43135769    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
     
    43195775    return 0;
    43205776}
     5777#endif
    43215778
    43225779WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
     
    43285785
    43295786    tagSz = (type == oidHashType ||
    4330              (type == oidSigType && !IsSigAlgoECDSA(algoOID) &&
    4331                                          algoOID != ED25519k) ||
     5787             (type == oidSigType
     5788        #ifdef HAVE_ECC
     5789              && !IsSigAlgoECDSA(algoOID)
     5790        #endif
     5791        #ifdef HAVE_ED25519
     5792              && algoOID != ED25519k
     5793        #endif
     5794              ) ||
    43325795             (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
    43335796
     
    43755838int wc_GetCTC_HashOID(int type)
    43765839{
    4377     switch (type) {
    4378 #ifdef WOLFSSL_MD2
    4379         case MD2:
    4380             return MD2h;
    4381 #endif
    4382 #ifndef NO_MD5
    4383         case WC_MD5:
    4384             return MD5h;
    4385 #endif
    4386 #ifndef NO_SHA
    4387         case WC_SHA:
    4388             return SHAh;
    4389 #endif
    4390 #ifdef WOLFSSL_SHA224
    4391         case WC_SHA224:
    4392             return SHA224h;
    4393 #endif
    4394 #ifndef NO_SHA256
    4395         case WC_SHA256:
    4396             return SHA256h;
    4397 #endif
    4398 #ifdef WOLFSSL_SHA384
    4399         case WC_SHA384:
    4400             return SHA384h;
    4401 #endif
    4402 #ifdef WOLFSSL_SHA512
    4403         case WC_SHA512:
    4404             return SHA512h;
    4405 #endif
    4406         default:
    4407             return 0;
    4408     };
     5840    int ret;
     5841    enum wc_HashType hType;
     5842
     5843    hType = wc_HashTypeConvert(type);
     5844    ret = wc_HashGetOID(hType);
     5845    if (ret < 0)
     5846        ret = 0; /* backwards compatibility */
     5847
     5848    return ret;
    44095849}
    44105850
     
    44335873    }
    44345874#endif
     5875#ifndef NO_ASN_CRYPT
    44355876    if (sigCtx->key.ptr) {
    44365877        switch (sigCtx->keyOID) {
     
    44585899        sigCtx->key.ptr = NULL;
    44595900    }
     5901#endif
    44605902
    44615903    /* reset state, we are done */
     
    44635905}
    44645906
     5907#ifndef NO_ASN_CRYPT
    44655908static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
    44665909                            byte* digest, int* typeH, int* digestSz, int verify)
     
    45495992    return ret;
    45505993}
     5994#endif /* !NO_ASN_CRYPT */
    45515995
    45525996/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
     
    45706014    WOLFSSL_ENTER("ConfirmSignature");
    45716015
     6016#ifndef NO_ASN_CRYPT
    45726017    switch (sigCtx->state) {
    45736018        case SIG_STATE_BEGIN:
    45746019        {
     6020            sigCtx->keyOID = keyOID; /* must set early for cleanup */
     6021
    45756022            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
    45766023                                                    DYNAMIC_TYPE_DIGEST);
     
    45976044        case SIG_STATE_KEY:
    45986045        {
    4599             sigCtx->keyOID = keyOID;
    4600 
    46016046            switch (keyOID) {
    46026047            #ifndef NO_RSA
     
    46376082                case ECDSAk:
    46386083                {
     6084                    word32 idx = 0;
     6085
    46396086                    sigCtx->verify = 0;
    46406087                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
     
    46476094                        goto exit_cs;
    46486095                    }
    4649                     if ((ret = wc_ecc_import_x963(key, keySz,
    4650                                                         sigCtx->key.ecc)) < 0) {
     6096                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
     6097                                                                         keySz);
     6098                    if (ret < 0) {
    46516099                        WOLFSSL_MSG("ASN Key import error ECC");
    46526100                        goto exit_cs;
     
    46966144        #ifdef WOLFSSL_ASYNC_CRYPT
    46976145            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
    4698                 /* make sure event is intialized */
     6146                /* make sure event is initialized */
    46996147                WOLF_EVENT* event = &sigCtx->asyncDev->event;
    47006148                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
     
    47116159                case RSAk:
    47126160                {
     6161                #ifdef HAVE_PK_CALLBACKS
     6162                    if (sigCtx->pkCbRsa) {
     6163                        ret = sigCtx->pkCbRsa(
     6164                                sigCtx->plain, sigSz, &sigCtx->out,
     6165                                key, keySz,
     6166                                sigCtx->pkCtxRsa);
     6167                    }
     6168                    else
     6169                #endif /* HAVE_PK_CALLBACKS */
     6170                    {
    47136171                    ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
    47146172                                                &sigCtx->out, sigCtx->key.rsa);
     6173                    }
    47156174                    break;
    47166175                }
     
    47196178                case ECDSAk:
    47206179                {
     6180                #ifdef HAVE_PK_CALLBACKS
     6181                    if (sigCtx->pkCbEcc) {
     6182                        ret = sigCtx->pkCbEcc(
     6183                                sig, sigSz,
     6184                                sigCtx->digest, sigCtx->digestSz,
     6185                                key, keySz, &sigCtx->verify,
     6186                                sigCtx->pkCtxEcc);
     6187                    }
     6188                    else
     6189                #endif /* HAVE_PK_CALLBACKS */
     6190                    {
    47216191                    ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
    4722                         sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
     6192                                            sigCtx->digestSz, &sigCtx->verify,
     6193                                            sigCtx->key.ecc);
     6194                    }
    47236195                    break;
    47246196                }
     
    47696241                    encodedSigSz = wc_EncodeSignature(encodedSig,
    47706242                            sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
    4771                     if (encodedSigSz == verifySz &&
     6243                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
    47726244                        XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
    47736245                        ret = 0;
     
    48206292exit_cs:
    48216293
     6294#endif /* !NO_ASN_CRYPT */
     6295
     6296    (void)keyOID;
     6297    (void)sigOID;
     6298
    48226299    WOLFSSL_LEAVE("ConfirmSignature", ret);
    48236300
     
    49116388                    while (name != NULL) {
    49126389                        if (MatchBaseName(ASN_DNS_TYPE,
    4913                                           name->name, (int)XSTRLEN(name->name),
     6390                                          name->name, name->len,
    49146391                                          base->name, base->nameSz)) {
    49156392                            return 0;
     
    49246401                    while (name != NULL) {
    49256402                        if (MatchBaseName(ASN_RFC822_TYPE,
    4926                                           name->name, (int)XSTRLEN(name->name),
     6403                                          name->name, name->len,
    49276404                                          base->name, base->nameSz)) {
    49286405                            return 0;
     
    49686445                    while (name != NULL) {
    49696446                        matchDns = MatchBaseName(ASN_DNS_TYPE,
    4970                                           name->name, (int)XSTRLEN(name->name),
     6447                                          name->name, name->len,
    49716448                                          base->name, base->nameSz);
    49726449                        name = name->next;
     
    49836460                    while (name != NULL) {
    49846461                        matchEmail = MatchBaseName(ASN_DNS_TYPE,
    4985                                           name->name, (int)XSTRLEN(name->name),
     6462                                          name->name, name->len,
    49866463                                          base->name, base->nameSz);
    49876464                        name = name->next;
     
    50176494#endif /* IGNORE_NAME_CONSTRAINTS */
    50186495
    5019 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
     6496static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
    50206497{
    50216498    word32 idx = 0;
     
    50566533            }
    50576534
     6535            dnsEntry->type = ASN_DNS_TYPE;
    50586536            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
    50596537                                         DYNAMIC_TYPE_ALTNAME);
     
    50636541                return MEMORY_E;
    50646542            }
    5065 
     6543            dnsEntry->len = strLen;
    50666544            XMEMCPY(dnsEntry->name, &input[idx], strLen);
    50676545            dnsEntry->name[strLen] = '\0';
     
    50926570            }
    50936571
     6572            emailEntry->type = ASN_RFC822_TYPE;
    50946573            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
    50956574                                         DYNAMIC_TYPE_ALTNAME);
     
    50996578                return MEMORY_E;
    51006579            }
    5101 
     6580            emailEntry->len = strLen;
    51026581            XMEMCPY(emailEntry->name, &input[idx], strLen);
    51036582            emailEntry->name[strLen] = '\0';
     
    51056584            emailEntry->next = cert->altEmailNames;
    51066585            cert->altEmailNames = emailEntry;
     6586
     6587            length -= strLen;
     6588            idx    += strLen;
     6589        }
     6590        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
     6591            DNS_entry* uriEntry;
     6592            int strLen;
     6593            word32 lenStartIdx = idx;
     6594
     6595            WOLFSSL_MSG("\tPutting URI into list but not using");
     6596            if (GetLength(input, &idx, &strLen, sz) < 0) {
     6597                WOLFSSL_MSG("\tfail: str length");
     6598                return ASN_PARSE_E;
     6599            }
     6600            length -= (idx - lenStartIdx);
     6601
     6602            /* check that strLen at index is not past input buffer */
     6603            if (strLen + (int)idx > sz) {
     6604                return BUFFER_E;
     6605            }
     6606
     6607        #ifndef WOLFSSL_NO_ASN_STRICT
     6608            /* Verify RFC 5280 Sec 4.2.1.6 rule:
     6609                "The name MUST NOT be a relative URI" */
     6610
     6611            {
     6612                int i;
     6613
     6614                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
     6615                for (i = 0; i < strLen; i++) {
     6616                    if (input[idx + i] == ':') {
     6617                        break;
     6618                    }
     6619                    if (input[idx + i] == '/') {
     6620                        i = strLen; /* error, found relative path since '/' was
     6621                                     * encountered before ':'. Returning error
     6622                                     * value in next if statement. */
     6623                    }
     6624                }
     6625
     6626                /* test if no ':' char was found and test that the next two
     6627                 * chars are // to match the pattern "://" */
     6628                if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
     6629                                        input[idx + i + 2] != '/')) {
     6630                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
     6631                    return ASN_ALT_NAME_E;
     6632                }
     6633            }
     6634        #endif
     6635
     6636            uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
     6637                                        DYNAMIC_TYPE_ALTNAME);
     6638            if (uriEntry == NULL) {
     6639                WOLFSSL_MSG("\tOut of Memory");
     6640                return MEMORY_E;
     6641            }
     6642
     6643            uriEntry->type = ASN_URI_TYPE;
     6644            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
     6645                                         DYNAMIC_TYPE_ALTNAME);
     6646            if (uriEntry->name == NULL) {
     6647                WOLFSSL_MSG("\tOut of Memory");
     6648                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
     6649                return MEMORY_E;
     6650            }
     6651            uriEntry->len = strLen;
     6652            XMEMCPY(uriEntry->name, &input[idx], strLen);
     6653            uriEntry->name[strLen] = '\0';
     6654
     6655            uriEntry->next = cert->altNames;
     6656            cert->altNames = uriEntry;
    51076657
    51086658            length -= strLen;
     
    52016751}
    52026752
    5203 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
     6753static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
    52046754{
    52056755    word32 idx = 0;
     
    52486798    /* From RFC3280 SS4.2.1.7, GeneralName */
    52496799
    5250 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
     6800static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
    52516801{
    52526802    word32 idx = 0;
     
    53296879
    53306880
    5331 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
     6881static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
    53326882/*
    53336883 *  Read the first of the Authority Information Access records. If there are
     
    53756925
    53766926
    5377 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
     6927static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
    53786928{
    53796929    word32 idx = 0;
     
    53976947    }
    53986948
    5399 #ifdef OPENSSL_EXTRA
     6949#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54006950    cert->extAuthKeyIdSrc = &input[idx];
    54016951    cert->extAuthKeyIdSz = length;
     
    54056955        XMEMCPY(cert->extAuthKeyId, input + idx, length);
    54066956    }
    5407     else {
    5408     #ifdef NO_SHA
    5409         ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
    5410     #else
    5411         ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
    5412     #endif
    5413     }
     6957    else
     6958        ret = CalcHashId(input + idx, length, cert->extAuthKeyId);
    54146959
    54156960    return ret;
     
    54176962
    54186963
    5419 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
     6964static int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)
    54206965{
    54216966    word32 idx = 0;
     
    54316976        return ret;
    54326977
    5433     #ifdef OPENSSL_EXTRA
     6978    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54346979        cert->extSubjKeyIdSrc = &input[idx];
    54356980        cert->extSubjKeyIdSz = length;
    54366981    #endif /* OPENSSL_EXTRA */
    54376982
    5438     if (length == SIGNER_DIGEST_SIZE) {
     6983    if (length == KEYID_SIZE) {
    54396984        XMEMCPY(cert->extSubjKeyId, input + idx, length);
    54406985    }
    5441     else {
    5442     #ifdef NO_SHA
    5443         ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
    5444     #else
    5445         ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
    5446     #endif
    5447     }
     6986    else
     6987        ret = CalcHashId(input + idx, length, cert->extSubjKeyId);
    54486988
    54496989    return ret;
     
    54516991
    54526992
    5453 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
     6993static int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)
    54546994{
    54556995    word32 idx = 0;
     
    54707010
    54717011
    5472 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
     7012static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)
    54737013{
    54747014    word32 idx = 0, oid;
    5475     int length;
    5476 
    5477     WOLFSSL_ENTER("DecodeExtKeyUsage");
     7015    int length, ret;
     7016
     7017    WOLFSSL_MSG("DecodeExtKeyUsage");
    54787018
    54797019    if (GetSequence(input, &idx, &length, sz) < 0) {
     
    54827022    }
    54837023
    5484 #ifdef OPENSSL_EXTRA
     7024#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    54857025    cert->extExtKeyUsageSrc = input + idx;
    54867026    cert->extExtKeyUsageSz = length;
     
    54887028
    54897029    while (idx < (word32)sz) {
    5490         if (GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz) < 0)
    5491             return ASN_PARSE_E;
     7030        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
     7031        if (ret == ASN_UNKNOWN_OID_E)
     7032            continue;
     7033        else if (ret < 0)
     7034            return ret;
    54927035
    54937036        switch (oid) {
     
    55157058        }
    55167059
    5517     #ifdef OPENSSL_EXTRA
     7060    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    55187061        cert->extExtKeyUsageCount++;
    55197062    #endif
     
    55267069#ifndef IGNORE_NAME_CONSTRAINTS
    55277070#define ASN_TYPE_MASK 0xF
    5528 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
     7071static int DecodeSubtree(const byte* input, int sz,
     7072                         Base_entry** head, void* heap)
    55297073{
    55307074    word32 idx = 0;
     
    55937137
    55947138
    5595 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
     7139static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)
    55967140{
    55977141    word32 idx = 0;
     
    56327176#endif /* IGNORE_NAME_CONSTRAINTS */
    56337177
    5634 
    5635 #if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)
     7178#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)
    56367179
    56377180static int Word32ToString(char* d, word32 number)
     
    56697212/* Decode ITU-T X.690 OID format to a string representation
    56707213 * return string length */
    5671 static int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
     7214int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
    56727215{
    56737216    word32 val, idx = 0, nb_bytes;
     
    57167259    }
    57177260
    5718     return 0;
     7261    return (int)w_bytes;
    57197262}
    57207263#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
     
    57227265#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
    57237266    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
    5724     static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
     7267    static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)
    57257268    {
    57267269        word32 idx = 0;
     
    57787321        #elif defined(WOLFSSL_CERT_EXT)
    57797322                /* decode cert policy */
    5780                 if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb],
    5781                                     MAX_CERTPOL_SZ, input + idx, length) != 0) {
     7323                if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
     7324                                    input + idx, length) <= 0) {
    57827325                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
    57837326                    return ASN_PARSE_E;
     
    58177360#endif /* WOLFSSL_SEP */
    58187361
     7362/* Macro to check if bit is set, if not sets and return success.
     7363    Otherwise returns failure */
     7364/* Macro required here because bit-field operation */
     7365#ifndef WOLFSSL_NO_ASN_STRICT
     7366    #define VERIFY_AND_SET_OID(bit) \
     7367        if (bit == 0) \
     7368            bit = 1; \
     7369        else \
     7370            return ASN_OBJECT_ID_E;
     7371#else
     7372    /* With no strict defined, the verify is skipped */
     7373#define VERIFY_AND_SET_OID(bit) bit = 1;
     7374#endif
     7375
    58197376static int DecodeCertExtensions(DecodedCert* cert)
    58207377/*
     
    58237380 */
    58247381{
    5825     int ret;
     7382    int ret = 0;
    58267383    word32 idx = 0;
    58277384    int sz = cert->extensionsSz;
    5828     byte* input = cert->extensions;
     7385    const byte* input = cert->extensions;
    58297386    int length;
    58307387    word32 oid;
     
    58857442        switch (oid) {
    58867443            case BASIC_CA_OID:
    5887                 #ifdef OPENSSL_EXTRA
    5888                     cert->extBasicConstSet = 1;
     7444                VERIFY_AND_SET_OID(cert->extBasicConstSet);
     7445                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    58897446                    cert->extBasicConstCrit = critical;
    58907447                #endif
     
    58947451
    58957452            case CRL_DIST_OID:
    5896                 #ifdef OPENSSL_EXTRA
    5897                     cert->extCRLdistSet  = 1;
     7453                VERIFY_AND_SET_OID(cert->extCRLdistSet);
     7454                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    58987455                    cert->extCRLdistCrit = critical;
    58997456                #endif
     
    59037460
    59047461            case AUTH_INFO_OID:
    5905                 #ifdef OPENSSL_EXTRA
    5906                     cert->extAuthInfoSet  = 1;
     7462                VERIFY_AND_SET_OID(cert->extAuthInfoSet);
     7463                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59077464                    cert->extAuthInfoCrit = critical;
    59087465                #endif
     
    59127469
    59137470            case ALT_NAMES_OID:
    5914                 #ifdef OPENSSL_EXTRA
    5915                     cert->extSubjAltNameSet = 1;
     7471                VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
     7472                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59167473                    cert->extSubjAltNameCrit = critical;
    59177474                #endif
    5918                 if (DecodeAltNames(&input[idx], length, cert) < 0)
    5919                     return ASN_PARSE_E;
     7475                ret = DecodeAltNames(&input[idx], length, cert);
     7476                if (ret < 0)
     7477                    return ret;
    59207478                break;
    59217479
    59227480            case AUTH_KEY_OID:
    5923                 cert->extAuthKeyIdSet = 1;
    5924                 #ifdef OPENSSL_EXTRA
     7481                VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
     7482                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59257483                    cert->extAuthKeyIdCrit = critical;
     7484                #endif
     7485                #ifndef WOLFSSL_ALLOW_CRIT_SKID
     7486                    /* This check is added due to RFC 5280 section 4.2.1.1
     7487                     * stating that conforming CA's must mark this extension
     7488                     * as non-critical. When parsing extensions check that
     7489                     * certificate was made in compliance with this. */
     7490                    if (critical) {
     7491                        WOLFSSL_MSG("Critical Auth Key ID is not allowed");
     7492                        WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
     7493                        return ASN_CRIT_EXT_E;
     7494                    }
    59267495                #endif
    59277496                if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
     
    59307499
    59317500            case SUBJ_KEY_OID:
    5932                 cert->extSubjKeyIdSet = 1;
    5933                 #ifdef OPENSSL_EXTRA
     7501                VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
     7502                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59347503                    cert->extSubjKeyIdCrit = critical;
    59357504                #endif
     
    59527521            case CERT_POLICY_OID:
    59537522                #ifdef WOLFSSL_SEP
    5954                     #ifdef OPENSSL_EXTRA
    5955                         cert->extCertPolicySet = 1;
     7523                    VERIFY_AND_SET_OID(cert->extCertPolicySet);
     7524                    #if defined(OPENSSL_EXTRA) || \
     7525                        defined(OPENSSL_EXTRA_X509_SMALL)
    59567526                        cert->extCertPolicyCrit = critical;
    59577527                    #endif
     
    59677537
    59687538            case KEY_USAGE_OID:
    5969                 cert->extKeyUsageSet = 1;
    5970                 #ifdef OPENSSL_EXTRA
     7539                VERIFY_AND_SET_OID(cert->extKeyUsageSet);
     7540                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59717541                    cert->extKeyUsageCrit = critical;
    59727542                #endif
     
    59767546
    59777547            case EXT_KEY_USAGE_OID:
    5978                 cert->extExtKeyUsageSet = 1;
    5979                 #ifdef OPENSSL_EXTRA
     7548                VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
     7549                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59807550                    cert->extExtKeyUsageCrit = critical;
    59817551                #endif
     
    59867556            #ifndef IGNORE_NAME_CONSTRAINTS
    59877557            case NAME_CONS_OID:
    5988                 cert->extNameConstraintSet = 1;
    5989                 #ifdef OPENSSL_EXTRA
     7558            #ifndef WOLFSSL_NO_ASN_STRICT
     7559                /* Verify RFC 5280 Sec 4.2.1.10 rule:
     7560                    "The name constraints extension,
     7561                    which MUST be used only in a CA certificate" */
     7562                if (!cert->isCA) {
     7563                    WOLFSSL_MSG("Name constraints allowed only for CA certs");
     7564                    return ASN_NAME_INVALID_E;
     7565                }
     7566            #endif
     7567                VERIFY_AND_SET_OID(cert->extNameConstraintSet);
     7568                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
    59907569                    cert->extNameConstraintCrit = critical;
    59917570                #endif
     
    59967575
    59977576            case INHIBIT_ANY_OID:
     7577                VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
    59987578                WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
    59997579                break;
    60007580
    60017581            default:
     7582            #ifndef WOLFSSL_NO_ASN_STRICT
    60027583                /* While it is a failure to not support critical extensions,
    60037584                 * still parse the certificate ignoring the unsupported
     
    60067587                if (critical)
    60077588                    criticalFail = 1;
     7589            #endif
    60087590                break;
    60097591        }
     
    60487630}
    60497631
     7632
    60507633/* from SSL proper, for locking can't do find here anymore */
    60517634#ifdef __cplusplus
     
    61017684#endif
    61027685
     7686#ifdef WOLFSSL_SMALL_CERT_VERIFY
     7687/* Only quick step through the certificate to find fields that are then used
     7688 * in certificate signature verification.
     7689 * Must use the signature OID from the signed part of the certificate.
     7690 *
     7691 * This is only for minimizing dynamic memory usage during TLS certificate
     7692 * chain processing.
     7693 * Doesn't support:
     7694 *   OCSP Only: alt lookup using subject and pub key w/o sig check
     7695 */
     7696int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
     7697{
     7698#ifndef WOLFSSL_SMALL_STACK
     7699    SignatureCtx  sigCtx[1];
     7700#else
     7701    SignatureCtx* sigCtx;
     7702#endif
     7703    byte          hash[KEYID_SIZE];
     7704    Signer*       ca = NULL;
     7705    word32        idx = 0;
     7706    int           len;
     7707    word32        tbsCertIdx;
     7708    word32        sigIndex;
     7709    word32        signatureOID;
     7710    word32        oid;
     7711    word32        issuerIdx;
     7712    word32        issuerSz;
     7713#ifndef NO_SKID
     7714    int           extLen;
     7715    word32        extIdx;
     7716    word32        extEndIdx;
     7717    int           extAuthKeyIdSet = 0;
     7718#endif
     7719    int    ret = 0;
     7720
     7721    if (cert == NULL) {
     7722        return BAD_FUNC_ARG;
     7723    }
     7724
     7725#ifdef WOLFSSL_SMALL_STACK
     7726    sigCtx = XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
     7727    if (sigCtx == NULL)
     7728        return MEMORY_E;
     7729#endif
     7730    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
     7731
     7732    /* Certificate SEQUENCE */
     7733    if (GetSequence(cert, &idx, &len, certSz) < 0)
     7734        ret = ASN_PARSE_E;
     7735    if (ret == 0) {
     7736        tbsCertIdx = idx;
     7737
     7738        /* TBSCertificate SEQUENCE */
     7739        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7740            ret = ASN_PARSE_E;
     7741            }
     7742    if (ret == 0) {
     7743        sigIndex = len + idx;
     7744
     7745        if ((idx + 1) > certSz)
     7746            ret = BUFFER_E;
     7747    }
     7748    if (ret == 0) {
     7749        /* version - optional */
     7750        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
     7751            idx++;
     7752            if (GetLength(cert, &idx, &len, certSz) < 0)
     7753                ret = ASN_PARSE_E;
     7754            idx += len;
     7755        }
     7756            }
     7757
     7758    if (ret == 0) {
     7759        /* serialNumber */
     7760        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
     7761            ret = ASN_PARSE_E;
     7762        }
     7763    if (ret == 0) {
     7764        idx += len;
     7765
     7766        /* signature */
     7767        if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
     7768            ret = ASN_PARSE_E;
     7769    }
     7770
     7771    if (ret == 0) {
     7772        issuerIdx = idx;
     7773        /* issuer */
     7774        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7775            ret = ASN_PARSE_E;
     7776    }
     7777    if (ret == 0) {
     7778        issuerSz = len + idx - issuerIdx;
     7779    }
     7780#ifndef NO_SKID
     7781    if (ret == 0) {
     7782        idx += len;
     7783
     7784        /* validity */
     7785        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7786            ret = ASN_PARSE_E;
     7787    }
     7788    if (ret == 0) {
     7789        idx += len;
     7790
     7791        /* subject */
     7792        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7793            ret = ASN_PARSE_E;
     7794    }
     7795    if (ret == 0) {
     7796        idx += len;
     7797
     7798        /* subjectPublicKeyInfo */
     7799        if (GetSequence(cert, &idx, &len, certSz) < 0)
     7800            ret = ASN_PARSE_E;
     7801    }
     7802    if (ret == 0) {
     7803        idx += len;
     7804
     7805        if ((idx + 1) > certSz)
     7806            ret = BUFFER_E;
     7807    }
     7808    if (ret == 0) {
     7809        /* issuerUniqueID - optional */
     7810        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
     7811            idx++;
     7812            if (GetLength(cert, &idx, &len, certSz) < 0)
     7813                ret = ASN_PARSE_E;
     7814            idx += len;
     7815        }
     7816    }
     7817    if (ret == 0) {
     7818        if ((idx + 1) > certSz)
     7819            ret = BUFFER_E;
     7820    }
     7821    if (ret == 0) {
     7822        /* subjectUniqueID - optional */
     7823        if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
     7824            idx++;
     7825            if (GetLength(cert, &idx, &len, certSz) < 0)
     7826                ret = ASN_PARSE_E;
     7827            idx += len;
     7828        }
     7829    }
     7830
     7831    if (ret == 0) {
     7832        if ((idx + 1) > certSz)
     7833            ret = BUFFER_E;
     7834    }
     7835    /* extensions - optional */
     7836    if (ret == 0 && cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
     7837        idx++;
     7838        if (GetLength(cert, &idx, &extLen, certSz) < 0)
     7839            ret = ASN_PARSE_E;
     7840        if (ret == 0) {
     7841            if (GetSequence(cert, &idx, &extLen, certSz) < 0)
     7842                ret = ASN_PARSE_E;
     7843        }
     7844        if (ret == 0) {
     7845            extEndIdx = idx + extLen;
     7846
     7847            /* Check each extension for the ones we want. */
     7848            while (ret == 0 && idx < extEndIdx) {
     7849                if (GetSequence(cert, &idx, &len, certSz) < 0)
     7850                    ret = ASN_PARSE_E;
     7851                if (ret == 0) {
     7852                    extIdx = idx;
     7853                    if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
     7854                                                                  certSz) < 0) {
     7855                        ret = ASN_PARSE_E;
     7856                    }
     7857                }
     7858                if (ret == 0) {
     7859                    if (cert[extIdx] == ASN_BOOLEAN) {
     7860                        if (GetBoolean(cert, &extIdx, certSz) < 0)
     7861                            ret = ASN_PARSE_E;
     7862                    }
     7863                }
     7864                if (ret == 0) {
     7865                    if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
     7866                        ret = ASN_PARSE_E;
     7867                }
     7868
     7869                if (ret == 0) {
     7870                    switch (oid) {
     7871                    case AUTH_KEY_OID:
     7872                        extAuthKeyIdSet = 1;
     7873                        if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
     7874                            ret = ASN_PARSE_E;
     7875
     7876                        if (ret == 0 &&
     7877                                 cert[extIdx++] == (ASN_CONTEXT_SPECIFIC | 0)) {
     7878                            if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
     7879                                ret = ASN_PARSE_E;
     7880                            if (ret == 0) {
     7881                                if (extLen == KEYID_SIZE)
     7882                                    XMEMCPY(hash, cert + extIdx, extLen);
     7883                                else {
     7884                                    ret = CalcHashId(cert + extIdx, extLen,
     7885                                                                          hash);
     7886                                }
     7887                            }
     7888                        }
     7889                        break;
     7890
     7891                    default:
     7892                        break;
     7893                    }
     7894                }
     7895                idx += len;
     7896            }
     7897        }
     7898    }
     7899
     7900    if (ret == 0) {
     7901        if (extAuthKeyIdSet)
     7902            ca = GetCA(cm, hash);
     7903        if (ca == NULL) {
     7904            ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
     7905            if (ret == 0)
     7906                ca = GetCAByName(cm, hash);
     7907        }
     7908    }
     7909#else
     7910    if (ret == 0) {
     7911        ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
     7912        if (ret == 0)
     7913            ca = GetCA(cm, hash);
     7914    }
     7915#endif /* !NO_SKID */
     7916    if (ca == NULL)
     7917        ret = ASN_NO_SIGNER_E;
     7918
     7919    if (ret == 0) {
     7920        idx = sigIndex;
     7921        /* signatureAlgorithm */
     7922        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
     7923            ret = ASN_PARSE_E;
     7924    }
     7925    if (ret == 0) {
     7926        if (oid != signatureOID)
     7927            ret = ASN_SIG_OID_E;
     7928    }
     7929    if (ret == 0) {
     7930        /* signatureValue */
     7931        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
     7932            ret = ASN_PARSE_E;
     7933    }
     7934
     7935    if (ret == 0) {
     7936        ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, sigIndex - tbsCertIdx,
     7937                               ca->publicKey, ca->pubKeySize, ca->keyOID,
     7938                               cert + idx, len, signatureOID);
     7939        if (ret != WC_PENDING_E) {
     7940            WOLFSSL_MSG("Confirm signature failed");
     7941        }
     7942    }
     7943
     7944#ifdef WOLFSSL_SMALL_STACK
     7945    if (sigCtx != NULL)
     7946        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
     7947#endif
     7948    return ret;
     7949}
     7950#endif /* WOLFSSL_SMALL_CERT_VERIFY */
     7951
    61037952int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
    61047953{
     
    61077956    int    criticalExt = 0;
    61087957    word32 confirmOID;
     7958    int    selfSigned = 0;
    61097959
    61107960    if (cert == NULL) {
     
    61598009        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
    61608010                                                        cert->pubKeySize > 0) {
    6161         #ifdef NO_SHA
    6162             ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
     8011            ret = CalcHashId(cert->publicKey, cert->pubKeySize,
    61638012                                                            cert->extSubjKeyId);
    6164         #else
    6165             ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
    6166                                                             cert->extSubjKeyId);
    6167         #endif /* NO_SHA */
    61688013            if (ret != 0)
    61698014                return ret;
     
    61978042    #else
    61988043            cert->ca = GetCA(cm, cert->issuerHash);
     8044            if (XMEMCMP(cert->issuerHash, cert->subjectHash, KEYID_SIZE) == 0)
     8045                selfSigned = 1;
    61998046    #endif /* !NO_SKID */
    62008047
    62018048            WOLFSSL_MSG("About to verify certificate signature");
    62028049            if (cert->ca) {
    6203                 if (cert->isCA) {
    6204                     if (cert->ca->pathLengthSet) {
     8050                if (cert->isCA && cert->ca->pathLengthSet) {
     8051                    if (selfSigned) {
     8052                        if (cert->ca->pathLength != 0) {
     8053                           WOLFSSL_MSG("Root CA with path length > 0");
     8054                           return ASN_PATHLEN_INV_E;
     8055                        }
     8056                    }
     8057                    else {
    62058058                        if (cert->ca->pathLength == 0) {
    62068059                            WOLFSSL_MSG("CA with path length 0 signing a CA");
    62078060                            return ASN_PATHLEN_INV_E;
    62088061                        }
    6209                         if (cert->pathLengthSet &&
    6210                             cert->pathLength >= cert->ca->pathLength) {
     8062                        else if (cert->pathLength >= cert->ca->pathLength) {
    62118063
    62128064                            WOLFSSL_MSG("CA signing CA with longer path length");
     
    62188070        #ifdef HAVE_OCSP
    62198071                /* Need the CA's public key hash for OCSP */
    6220             #ifdef NO_SHA
    6221                 ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
     8072            ret = CalcHashId(cert->ca->publicKey, cert->ca->pubKeySize,
    62228073                                                           cert->issuerKeyHash);
    6223             #else
    6224                 ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
    6225                                                            cert->issuerKeyHash);
    6226             #endif /* NO_SHA */
    62278074                if (ret != 0)
    62288075                    return ret;
     
    62478094                    return ret;
    62488095                }
     8096            }
    62498097            #ifndef IGNORE_NAME_CONSTRAINTS
     8098            if (verify == VERIFY || verify == VERIFY_OCSP ||
     8099                                                        verify == VERIFY_NAME) {
    62508100                /* check that this cert's name is permitted by the signer's
    62518101                 * name constraints */
     
    62548104                    return ASN_NAME_INVALID_E;
    62558105                }
    6256             #endif /* IGNORE_NAME_CONSTRAINTS */
    6257             }
     8106            }
     8107        #endif /* IGNORE_NAME_CONSTRAINTS */
    62588108        }
    62598109        else {
     
    62948144        signer->pathLengthSet = 0;
    62958145        signer->pathLength = 0;
     8146    #ifdef WOLFSSL_SIGNER_DER_CERT
     8147        signer->derCert    = NULL;
     8148    #endif
    62968149        signer->next       = NULL;
    62978150    }
     
    63068159{
    63078160    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
    6308     XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
     8161    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
    63098162#ifndef IGNORE_NAME_CONSTRAINTS
    63108163    if (signer->permittedNames)
     
    63128165    if (signer->excludedNames)
    63138166        FreeNameSubtrees(signer->excludedNames, heap);
     8167#endif
     8168#ifdef WOLFSSL_SIGNER_DER_CERT
     8169    FreeDer(&signer->derCert);
    63148170#endif
    63158171    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
     
    64768332
    64778333
    6478 
    6479 const char* BEGIN_CERT         = "-----BEGIN CERTIFICATE-----";
    6480 const char* END_CERT           = "-----END CERTIFICATE-----";
    6481 const char* BEGIN_CERT_REQ     = "-----BEGIN CERTIFICATE REQUEST-----";
    6482 const char* END_CERT_REQ       = "-----END CERTIFICATE REQUEST-----";
    6483 const char* BEGIN_DH_PARAM     = "-----BEGIN DH PARAMETERS-----";
    6484 const char* END_DH_PARAM       = "-----END DH PARAMETERS-----";
    6485 const char* BEGIN_DSA_PARAM    = "-----BEGIN DSA PARAMETERS-----";
    6486 const char* END_DSA_PARAM      = "-----END DSA PARAMETERS-----";
    6487 const char* BEGIN_X509_CRL     = "-----BEGIN X509 CRL-----";
    6488 const char* END_X509_CRL       = "-----END X509 CRL-----";
    6489 const char* BEGIN_RSA_PRIV     = "-----BEGIN RSA PRIVATE KEY-----";
    6490 const char* END_RSA_PRIV       = "-----END RSA PRIVATE KEY-----";
    6491 const char* BEGIN_PRIV_KEY     = "-----BEGIN PRIVATE KEY-----";
    6492 const char* END_PRIV_KEY       = "-----END PRIVATE KEY-----";
    6493 const char* BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
    6494 const char* END_ENC_PRIV_KEY   = "-----END ENCRYPTED PRIVATE KEY-----";
    6495 const char* BEGIN_EC_PRIV      = "-----BEGIN EC PRIVATE KEY-----";
    6496 const char* END_EC_PRIV        = "-----END EC PRIVATE KEY-----";
    6497 const char* BEGIN_DSA_PRIV     = "-----BEGIN DSA PRIVATE KEY-----";
    6498 const char* END_DSA_PRIV       = "-----END DSA PRIVATE KEY-----";
    6499 const char* BEGIN_PUB_KEY      = "-----BEGIN PUBLIC KEY-----";
    6500 const char* END_PUB_KEY        = "-----END PUBLIC KEY-----";
    6501 const char* BEGIN_EDDSA_PRIV   = "-----BEGIN EDDSA PRIVATE KEY-----";
    6502 const char* END_EDDSA_PRIV     = "-----END EDDSA PRIVATE KEY-----";
    6503 
    6504 #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA)
     8334int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
     8335{
     8336    int ret = BAD_FUNC_ARG;
     8337    if (pDer) {
     8338        int dynType = 0;
     8339        DerBuffer* der;
     8340
     8341        /* Determine dynamic type */
     8342        switch (type) {
     8343            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
     8344            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
     8345            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
     8346            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
     8347            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
     8348            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
     8349            default:        dynType = DYNAMIC_TYPE_KEY;  break;
     8350        }
     8351
     8352        /* Setup new buffer */
     8353        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
     8354        if (*pDer == NULL) {
     8355            return MEMORY_E;
     8356        }
     8357        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
     8358
     8359        der = *pDer;
     8360        der->type = type;
     8361        der->dynType = dynType; /* Cache this for FreeDer */
     8362        der->heap = heap;
     8363        der->buffer = (byte*)der + sizeof(DerBuffer);
     8364        der->length = length;
     8365        ret = 0; /* Success */
     8366    }
     8367    return ret;
     8368}
     8369
     8370void FreeDer(DerBuffer** pDer)
     8371{
     8372    if (pDer && *pDer)
     8373    {
     8374        DerBuffer* der = (DerBuffer*)*pDer;
     8375
     8376        /* ForceZero private keys */
     8377        if (der->type == PRIVATEKEY_TYPE) {
     8378            ForceZero(der->buffer, der->length);
     8379}
     8380        der->buffer = NULL;
     8381        der->length = 0;
     8382        XFREE(der, der->heap, der->dynType);
     8383
     8384        *pDer = NULL;
     8385    }
     8386}
     8387
     8388int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
     8389{
     8390    return AllocDer(pDer, length, type, heap);
     8391}
     8392void wc_FreeDer(DerBuffer** pDer)
     8393{
     8394    FreeDer(pDer);
     8395}
     8396
     8397
     8398#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
     8399
     8400/* Max X509 header length indicates the max length + 2 ('\n', '\0') */
     8401#define MAX_X509_HEADER_SZ  (37 + 2)
     8402
     8403const char* const BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
     8404const char* const END_CERT             = "-----END CERTIFICATE-----";
     8405#ifdef WOLFSSL_CERT_REQ
     8406    const char* const BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
     8407    const char* const END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
     8408#endif
     8409#ifndef NO_DH
     8410    const char* const BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
     8411    const char* const END_DH_PARAM     = "-----END DH PARAMETERS-----";
     8412#endif
     8413#ifndef NO_DSA
     8414    const char* const BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
     8415    const char* const END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
     8416#endif
     8417const char* const BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
     8418const char* const END_X509_CRL         = "-----END X509 CRL-----";
     8419const char* const BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
     8420const char* const END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
     8421const char* const BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
     8422const char* const END_PRIV_KEY         = "-----END PRIVATE KEY-----";
     8423const char* const BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
     8424const char* const END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
     8425#ifdef HAVE_ECC
     8426    const char* const BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
     8427    const char* const END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
     8428#endif
     8429#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA)
     8430    const char* const BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
     8431    const char* const END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
     8432#endif
     8433const char* const BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
     8434const char* const END_PUB_KEY          = "-----END PUBLIC KEY-----";
     8435#ifdef HAVE_ED25519
     8436    const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
     8437    const char* const END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
     8438#endif
     8439#ifdef HAVE_CRL
     8440    const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----";
     8441    const char* const END_CRL   = "-----END X509 CRL-----";
     8442#endif
     8443
     8444
     8445static WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine)
     8446{
     8447    /* eat end of line characters */
     8448    while (line < endOfLine &&
     8449              (line[0] == '\r' || line[0] == '\n')) {
     8450        line++;
     8451    }
     8452    return line;
     8453    }
     8454
     8455int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
     8456{
     8457    int ret = BAD_FUNC_ARG;
     8458
     8459    switch (type) {
     8460        case CA_TYPE:       /* same as below */
     8461        case TRUSTED_PEER_TYPE:
     8462        case CERT_TYPE:
     8463            if (header) *header = BEGIN_CERT;
     8464            if (footer) *footer = END_CERT;
     8465            ret = 0;
     8466            break;
     8467
     8468        case CRL_TYPE:
     8469            if (header) *header = BEGIN_X509_CRL;
     8470            if (footer) *footer = END_X509_CRL;
     8471            ret = 0;
     8472            break;
     8473    #ifndef NO_DH
     8474        case DH_PARAM_TYPE:
     8475            if (header) *header = BEGIN_DH_PARAM;
     8476            if (footer) *footer = END_DH_PARAM;
     8477            ret = 0;
     8478            break;
     8479    #endif
     8480    #ifndef NO_DSA
     8481        case DSA_PARAM_TYPE:
     8482            if (header) *header = BEGIN_DSA_PARAM;
     8483            if (footer) *footer = END_DSA_PARAM;
     8484            ret = 0;
     8485            break;
     8486    #endif
     8487    #ifdef WOLFSSL_CERT_REQ
     8488        case CERTREQ_TYPE:
     8489            if (header) *header = BEGIN_CERT_REQ;
     8490            if (footer) *footer = END_CERT_REQ;
     8491            ret = 0;
     8492            break;
     8493    #endif
     8494    #ifndef NO_DSA
     8495        case DSA_TYPE:
     8496        case DSA_PRIVATEKEY_TYPE:
     8497            if (header) *header = BEGIN_DSA_PRIV;
     8498            if (footer) *footer = END_DSA_PRIV;
     8499            ret = 0;
     8500            break;
     8501    #endif
     8502    #ifdef HAVE_ECC
     8503        case ECC_TYPE:
     8504        case ECC_PRIVATEKEY_TYPE:
     8505            if (header) *header = BEGIN_EC_PRIV;
     8506            if (footer) *footer = END_EC_PRIV;
     8507            ret = 0;
     8508            break;
     8509    #endif
     8510        case RSA_TYPE:
     8511        case PRIVATEKEY_TYPE:
     8512            if (header) *header = BEGIN_RSA_PRIV;
     8513            if (footer) *footer = END_RSA_PRIV;
     8514            ret = 0;
     8515            break;
     8516    #ifdef HAVE_ED25519
     8517        case ED25519_TYPE:
     8518        case EDDSA_PRIVATEKEY_TYPE:
     8519            if (header) *header = BEGIN_EDDSA_PRIV;
     8520            if (footer) *footer = END_EDDSA_PRIV;
     8521            ret = 0;
     8522            break;
     8523    #endif
     8524        case PUBLICKEY_TYPE:
     8525            if (header) *header = BEGIN_PUB_KEY;
     8526            if (footer) *footer = END_PUB_KEY;
     8527            ret = 0;
     8528            break;
     8529        case PKCS8_PRIVATEKEY_TYPE:
     8530            if (header) *header = BEGIN_PRIV_KEY;
     8531            if (footer) *footer = END_PRIV_KEY;
     8532            ret = 0;
     8533            break;
     8534        case PKCS8_ENC_PRIVATEKEY_TYPE:
     8535            if (header) *header = BEGIN_ENC_PRIV_KEY;
     8536            if (footer) *footer = END_ENC_PRIV_KEY;
     8537            ret = 0;
     8538            break;
     8539        default:
     8540            break;
     8541    }
     8542    return ret;
     8543}
     8544
     8545#ifdef WOLFSSL_ENCRYPTED_KEYS
     8546
     8547static const char* const kProcTypeHeader = "Proc-Type";
     8548static const char* const kDecInfoHeader = "DEK-Info";
     8549
     8550#ifdef WOLFSSL_PEM_TO_DER
     8551#ifndef NO_DES3
     8552    static const char* const kEncTypeDes = "DES-CBC";
     8553    static const char* const kEncTypeDes3 = "DES-EDE3-CBC";
     8554#endif
     8555#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
     8556    static const char* const kEncTypeAesCbc128 = "AES-128-CBC";
     8557#endif
     8558#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
     8559    static const char* const kEncTypeAesCbc192 = "AES-192-CBC";
     8560#endif
     8561#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
     8562    static const char* const kEncTypeAesCbc256 = "AES-256-CBC";
     8563#endif
     8564
     8565int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
     8566{
     8567    int ret = 0;
     8568
     8569    if (info == NULL || cipherInfo == NULL)
     8570        return BAD_FUNC_ARG;
     8571
     8572    /* determine cipher information */
     8573#ifndef NO_DES3
     8574    if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
     8575        info->cipherType = WC_CIPHER_DES;
     8576        info->keySz = DES_KEY_SIZE;
     8577        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
     8578    }
     8579    else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
     8580        info->cipherType = WC_CIPHER_DES3;
     8581        info->keySz = DES3_KEY_SIZE;
     8582        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
     8583    }
     8584    else
     8585#endif /* !NO_DES3 */
     8586#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
     8587    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
     8588        info->cipherType = WC_CIPHER_AES_CBC;
     8589        info->keySz = AES_128_KEY_SIZE;
     8590        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8591    }
     8592    else
     8593#endif
     8594#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
     8595    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
     8596        info->cipherType = WC_CIPHER_AES_CBC;
     8597        info->keySz = AES_192_KEY_SIZE;
     8598        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8599    }
     8600    else
     8601#endif
     8602#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
     8603    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
     8604        info->cipherType = WC_CIPHER_AES_CBC;
     8605        info->keySz = AES_256_KEY_SIZE;
     8606        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
     8607    }
     8608    else
     8609#endif
     8610    {
     8611        ret = NOT_COMPILED_IN;
     8612    }
     8613    return ret;
     8614}
     8615
     8616int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz)
     8617{
     8618    int err = 0;
     8619    char*  bufferStart;
     8620    char*  bufferEnd;
     8621    char*  line;
     8622    word32 lineSz;
     8623    char*  finish;
     8624    word32 finishSz;
     8625    char*  start = NULL;
     8626    word32 startSz;
     8627    char*  newline = NULL;
     8628
     8629    if (info == NULL || pBuffer == NULL || bufSz == 0)
     8630        return BAD_FUNC_ARG;
     8631
     8632    bufferStart = *pBuffer;
     8633    bufferEnd = bufferStart + bufSz;
     8634
     8635    /* find encrypted info marker */
     8636    line = XSTRNSTR(bufferStart, kProcTypeHeader,
     8637                    min((word32)bufSz, PEM_LINE_LEN));
     8638    if (line != NULL) {
     8639        if (line >= bufferEnd) {
     8640            return BUFFER_E;
     8641        }
     8642
     8643        lineSz = (word32)(bufferEnd - line);
     8644
     8645        /* find DEC-Info marker */
     8646        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
     8647
     8648        if (start == NULL)
     8649            return BUFFER_E;
     8650
     8651        /* skip dec-info and ": " */
     8652        start += XSTRLEN(kDecInfoHeader);
     8653        if (start >= bufferEnd)
     8654            return BUFFER_E;
     8655
     8656        if (start[0] == ':') {
     8657            start++;
     8658            if (start >= bufferEnd)
     8659                return BUFFER_E;
     8660        }
     8661        if (start[0] == ' ')
     8662            start++;
     8663
     8664        startSz = (word32)(bufferEnd - start);
     8665        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
     8666
     8667        if ((start != NULL) && (finish != NULL) && (start < finish)) {
     8668            if (finish >= bufferEnd) {
     8669                return BUFFER_E;
     8670            }
     8671
     8672            finishSz = (word32)(bufferEnd - finish);
     8673            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
     8674
     8675            /* get cipher name */
     8676            if (NAME_SZ < (finish - start)) /* buffer size of info->name */
     8677                return BUFFER_E;
     8678            if (XMEMCPY(info->name, start, finish - start) == NULL)
     8679                return BUFFER_E;
     8680            info->name[finish - start] = '\0'; /* null term */
     8681
     8682            /* populate info */
     8683            err = wc_EncryptedInfoGet(info, info->name);
     8684            if (err != 0)
     8685                return err;
     8686
     8687            /* get IV */
     8688            if (finishSz < info->ivSz + 1)
     8689                return BUFFER_E;
     8690
     8691            if (newline == NULL) {
     8692                newline = XSTRNSTR(finish, "\n", min(finishSz,
     8693                                                     PEM_LINE_LEN));
     8694            }
     8695            if ((newline != NULL) && (newline > finish)) {
     8696                info->ivSz = (word32)(newline - (finish + 1));
     8697                if (XMEMCPY(info->iv, finish + 1, info->ivSz) == NULL)
     8698                    return BUFFER_E;
     8699                info->set = 1;
     8700            }
     8701            else
     8702                return BUFFER_E;
     8703        }
     8704        else
     8705            return BUFFER_E;
     8706
     8707        /* eat end of line characters */
     8708        newline = SkipEndOfLineChars(newline, bufferEnd);
     8709
     8710        /* return new headerEnd */
     8711        if (pBuffer)
     8712            *pBuffer = newline;
     8713    }
     8714
     8715    return err;
     8716}
     8717#endif /* WOLFSSL_PEM_TO_DER */
     8718
     8719#ifdef WOLFSSL_DER_TO_PEM
     8720static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
     8721{
     8722    if (cipherInfo != NULL) {
     8723        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
     8724
     8725        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
     8726            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
     8727
     8728        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
     8729            /* strncat's src length needs to include the NULL */
     8730            XSTRNCAT(dest, kProcTypeHeader, 10);
     8731            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
     8732            XSTRNCAT(dest, kDecInfoHeader, 9);
     8733            XSTRNCAT(dest, ": ", 3);
     8734            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
     8735            XSTRNCAT(dest, "\n\n", 4);
     8736        }
     8737    }
     8738    return 0;
     8739}
     8740#endif /* WOLFSSL_DER_TO_PEM */
     8741#endif /* WOLFSSL_ENCRYPTED_KEYS */
     8742
     8743#ifdef WOLFSSL_DER_TO_PEM
    65058744
    65068745/* Used for compatibility API */
     
    65168755             byte *cipher_info, int type)
    65178756{
     8757    const char* headerStr = NULL;
     8758    const char* footerStr = NULL;
    65188759#ifdef WOLFSSL_SMALL_STACK
    65198760    char* header = NULL;
    65208761    char* footer = NULL;
    65218762#else
    6522     char header[40 + HEADER_ENCRYPTED_KEY_SIZE];
    6523     char footer[40];
    6524 #endif
    6525 
    6526     int headerLen = 40 + HEADER_ENCRYPTED_KEY_SIZE;
    6527     int footerLen = 40;
     8763    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
     8764    char footer[MAX_X509_HEADER_SZ];
     8765#endif
     8766    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
     8767    int footerLen = MAX_X509_HEADER_SZ;
    65288768    int i;
    65298769    int err;
    65308770    int outLen;   /* return length or error */
    65318771
     8772    (void)cipher_info;
     8773
    65328774    if (der == output)      /* no in place conversion */
    65338775        return BAD_FUNC_ARG;
     8776
     8777    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
     8778    if (err != 0)
     8779        return err;
    65348780
    65358781#ifdef WOLFSSL_SMALL_STACK
     
    65448790    }
    65458791#endif
    6546     if (type == CERT_TYPE) {
    6547         XSTRNCPY(header, BEGIN_CERT, headerLen);
    6548         XSTRNCAT(header, "\n", 1);
    6549 
    6550         XSTRNCPY(footer, END_CERT, footerLen);
    6551         XSTRNCAT(footer, "\n", 1);
    6552     }
    6553     else if (type == PRIVATEKEY_TYPE) {
    6554         XSTRNCPY(header, BEGIN_RSA_PRIV, headerLen);
    6555         XSTRNCAT(header, "\n", 1);
    6556 
    6557         XSTRNCPY(footer, END_RSA_PRIV, footerLen);
    6558         XSTRNCAT(footer, "\n", 1);
    6559     }
    6560 #ifndef NO_DSA
    6561     else if (type == DSA_PRIVATEKEY_TYPE) {
    6562         XSTRNCPY(header, BEGIN_DSA_PRIV, headerLen);
    6563         XSTRNCAT(header, "\n", 1);
    6564 
    6565         XSTRNCPY(footer, END_DSA_PRIV, footerLen);
    6566         XSTRNCAT(footer, "\n", 1);
    6567     }
    6568 #endif
    6569 #ifdef HAVE_ECC
    6570     else if (type == ECC_PRIVATEKEY_TYPE) {
    6571         XSTRNCPY(header, BEGIN_EC_PRIV, headerLen);
    6572         XSTRNCAT(header, "\n", 1);
    6573 
    6574         XSTRNCPY(footer, END_EC_PRIV, footerLen);
    6575         XSTRNCAT(footer, "\n", 1);
    6576     }
    6577 #endif
    6578 #ifdef HAVE_ED25519
    6579     else if (type == EDDSA_PRIVATEKEY_TYPE) {
    6580         XSTRNCPY(header, BEGIN_EDDSA_PRIV, headerLen);
    6581         XSTRNCAT(header, "\n", 1);
    6582 
    6583         XSTRNCPY(footer, END_EDDSA_PRIV, footerLen);
    6584         XSTRNCAT(footer, "\n", 1);
    6585     }
    6586 #endif
    6587 #ifdef WOLFSSL_CERT_REQ
    6588     else if (type == CERTREQ_TYPE)
    6589     {
    6590         XSTRNCPY(header, BEGIN_CERT_REQ, headerLen);
    6591         XSTRNCAT(header, "\n", 1);
    6592 
    6593         XSTRNCPY(footer, END_CERT_REQ, footerLen);
    6594         XSTRNCAT(footer, "\n", 1);
    6595     }
    6596 #endif
    6597 #ifdef HAVE_CRL
    6598     else if (type == CRL_TYPE)
    6599     {
    6600         XSTRNCPY(header, BEGIN_X509_CRL, headerLen);
    6601         XSTRNCAT(header, "\n", 1);
    6602 
    6603         XSTRNCPY(footer, END_X509_CRL, footerLen);
    6604         XSTRNCAT(footer, "\n", 1);
    6605     }
    6606 #endif
    6607     else {
    6608 #ifdef WOLFSSL_SMALL_STACK
     8792
     8793    /* build header and footer based on type */
     8794    XSTRNCPY(header, headerStr, headerLen - 1);
     8795    header[headerLen - 1] = 0;
     8796    XSTRNCPY(footer, footerStr, footerLen - 1);
     8797    footer[footerLen - 1] = 0;
     8798
     8799    /* add new line to end */
     8800    XSTRNCAT(header, "\n", 2);
     8801    XSTRNCAT(footer, "\n", 2);
     8802
     8803#ifdef WOLFSSL_ENCRYPTED_KEYS
     8804    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
     8805    if (err != 0) {
     8806    #ifdef WOLFSSL_SMALL_STACK
    66098807        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    66108808        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6611 #endif
    6612         return BAD_FUNC_ARG;
    6613     }
    6614 
    6615     /* extra header information for encrypted key */
    6616     if (cipher_info != NULL) {
    6617         size_t cipherInfoStrLen = XSTRLEN((char*)cipher_info);
    6618         if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (23+10+2))
    6619             cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (23+10+2);
    6620 
    6621         XSTRNCAT(header, "Proc-Type: 4,ENCRYPTED\n", 23);
    6622         XSTRNCAT(header, "DEK-Info: ", 10);
    6623         XSTRNCAT(header, (char*)cipher_info, cipherInfoStrLen);
    6624         XSTRNCAT(header, "\n\n", 2);
    6625     }
     8809    #endif
     8810        return err;
     8811    }
     8812#endif
    66268813
    66278814    headerLen = (int)XSTRLEN(header);
     
    66938880}
    66948881
    6695 #endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN || OPENSSL_EXTRA */
     8882#endif /* WOLFSSL_DER_TO_PEM */
     8883
     8884#ifdef WOLFSSL_PEM_TO_DER
     8885
     8886/* Remove PEM header/footer, convert to ASN1, store any encrypted data
     8887   info->consumed tracks of PEM bytes consumed in case multiple parts */
     8888int PemToDer(const unsigned char* buff, long longSz, int type,
     8889              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
     8890{
     8891    const char* header      = NULL;
     8892    const char* footer      = NULL;
     8893    char*       headerEnd;
     8894    char*       footerEnd;
     8895    char*       consumedEnd;
     8896    char*       bufferEnd   = (char*)(buff + longSz);
     8897    long        neededSz;
     8898    int         ret         = 0;
     8899    int         sz          = (int)longSz;
     8900    int         encrypted_key = 0;
     8901    DerBuffer*  der;
     8902    word32      algId = 0;
     8903
     8904    WOLFSSL_ENTER("PemToDer");
     8905
     8906    /* get PEM header and footer based on type */
     8907    ret = wc_PemGetHeaderFooter(type, &header, &footer);
     8908    if (ret != 0)
     8909        return ret;
     8910
     8911    /* map header if not found for type */
     8912    for (;;) {
     8913        headerEnd = XSTRNSTR((char*)buff, header, sz);
     8914
     8915        if (headerEnd || type != PRIVATEKEY_TYPE) {
     8916            break;
     8917        } else
     8918        if (header == BEGIN_RSA_PRIV) {
     8919            header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;
     8920        } else
     8921        if (header == BEGIN_PRIV_KEY) {
     8922            header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;
     8923        } else
     8924#ifdef HAVE_ECC
     8925        if (header == BEGIN_ENC_PRIV_KEY) {
     8926            header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;
     8927        } else
     8928        if (header == BEGIN_EC_PRIV) {
     8929            header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;
     8930        } else
     8931#endif
     8932#ifdef HAVE_ED25519
     8933    #ifdef HAVE_ECC
     8934        if (header == BEGIN_DSA_PRIV)
     8935    #else
     8936        if (header == BEGIN_ENC_PRIV_KEY)
     8937    #endif
     8938        {
     8939            header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;
     8940        } else
     8941#endif
     8942#ifdef HAVE_CRL
     8943        if (type == CRL_TYPE) {
     8944            header =  BEGIN_CRL;        footer = END_CRL;
     8945        } else
     8946#endif
     8947        {
     8948            break;
     8949        }
     8950    }
     8951
     8952    if (!headerEnd) {
     8953        WOLFSSL_MSG("Couldn't find PEM header");
     8954        return ASN_NO_PEM_HEADER;
     8955    }
     8956
     8957    headerEnd += XSTRLEN(header);
     8958
     8959    /* eat end of line characters */
     8960    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
     8961
     8962    if (type == PRIVATEKEY_TYPE) {
     8963        if (eccKey) {
     8964        #ifdef HAVE_ECC
     8965            *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0;
     8966        #else
     8967            *eccKey = 0;
     8968        #endif
     8969        }
     8970    }
     8971
     8972#ifdef WOLFSSL_ENCRYPTED_KEYS
     8973    if (info) {
     8974        ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
     8975        if (ret < 0)
     8976            return ret;
     8977        if (info->set)
     8978            encrypted_key = 1;
     8979    }
     8980#endif /* WOLFSSL_ENCRYPTED_KEYS */
     8981
     8982    /* find footer */
     8983    footerEnd = XSTRNSTR((char*)buff, footer, sz);
     8984    if (!footerEnd) {
     8985        if (info)
     8986            info->consumed = longSz; /* No more certs if no footer */
     8987        return BUFFER_E;
     8988    }
     8989
     8990    consumedEnd = footerEnd + XSTRLEN(footer);
     8991
     8992    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
     8993        /* eat end of line characters */
     8994        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
     8995        /* skip possible null term */
     8996        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
     8997            consumedEnd++;
     8998    }
     8999
     9000    if (info)
     9001        info->consumed = (long)(consumedEnd - (char*)buff);
     9002
     9003    /* set up der buffer */
     9004    neededSz = (long)(footerEnd - headerEnd);
     9005    if (neededSz > sz || neededSz <= 0)
     9006        return BUFFER_E;
     9007
     9008    ret = AllocDer(pDer, (word32)neededSz, type, heap);
     9009    if (ret < 0) {
     9010        return ret;
     9011    }
     9012    der = *pDer;
     9013
     9014    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
     9015                      der->buffer, &der->length) < 0)
     9016        return BUFFER_E;
     9017
     9018    if ((header == BEGIN_PRIV_KEY
     9019#ifdef HAVE_ECC
     9020         || header == BEGIN_EC_PRIV
     9021#endif
     9022        ) && !encrypted_key)
     9023    {
     9024        /* pkcs8 key, convert and adjust length */
     9025        if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
     9026            der->length = ret;
     9027        }
     9028        else {
     9029            /* ignore failure here and assume key is not pkcs8 wrapped */
     9030        }
     9031
     9032        return 0;
     9033    }
     9034
     9035#ifdef WOLFSSL_ENCRYPTED_KEYS
     9036    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
     9037        int   passwordSz = NAME_SZ;
     9038    #ifdef WOLFSSL_SMALL_STACK
     9039        char* password = NULL;
     9040    #else
     9041        char  password[NAME_SZ];
     9042    #endif
     9043
     9044        if (!info || !info->passwd_cb) {
     9045            WOLFSSL_MSG("No password callback set");
     9046            return NO_PASSWORD;
     9047        }
     9048
     9049    #ifdef WOLFSSL_SMALL_STACK
     9050        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
     9051        if (password == NULL)
     9052            return MEMORY_E;
     9053    #endif
     9054
     9055        /* get password */
     9056        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
     9057            info->passwd_userdata);
     9058        if (ret >= 0) {
     9059            passwordSz = ret;
     9060
     9061            /* convert and adjust length */
     9062            if (header == BEGIN_ENC_PRIV_KEY) {
     9063            #ifndef NO_PWDBASED
     9064                ret = ToTraditionalEnc(der->buffer, der->length,
     9065                                       password, passwordSz, &algId);
     9066
     9067                if (ret >= 0) {
     9068                    der->length = ret;
     9069                    if ((algId == ECDSAk) && (eccKey != NULL)) {
     9070                        *eccKey = 1;
     9071                    }
     9072                    ret = 0;
     9073                }
     9074            #else
     9075                ret = NOT_COMPILED_IN;
     9076            #endif
     9077            }
     9078            /* decrypt the key */
     9079            else {
     9080                ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
     9081                    (byte*)password, passwordSz, WC_MD5);
     9082            }
     9083            ForceZero(password, passwordSz);
     9084        }
     9085
     9086    #ifdef WOLFSSL_SMALL_STACK
     9087        XFREE(password, heap, DYNAMIC_TYPE_STRING);
     9088    #endif
     9089    }
     9090#endif /* WOLFSSL_ENCRYPTED_KEYS */
     9091
     9092    return ret;
     9093}
     9094
     9095int wc_PemToDer(const unsigned char* buff, long longSz, int type,
     9096              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
     9097{
     9098    return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
     9099}
     9100
     9101
     9102/* our KeyPemToDer password callback, password in userData */
     9103static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
     9104{
     9105    (void)rw;
     9106
     9107    if (userdata == NULL)
     9108        return 0;
     9109
     9110    XSTRNCPY(passwd, (char*)userdata, sz);
     9111    return min((word32)sz, (word32)XSTRLEN((char*)userdata));
     9112}
     9113
     9114/* Return bytes written to buff or < 0 for error */
     9115int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
     9116                        unsigned char* buff, int buffSz, const char* pass)
     9117{
     9118    int            eccKey = 0;
     9119    int            ret;
     9120    DerBuffer*     der = NULL;
     9121#ifdef WOLFSSL_SMALL_STACK
     9122    EncryptedInfo* info = NULL;
     9123#else
     9124    EncryptedInfo  info[1];
     9125#endif
     9126
     9127    WOLFSSL_ENTER("wc_KeyPemToDer");
     9128
     9129    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9130        WOLFSSL_MSG("Bad pem der args");
     9131        return BAD_FUNC_ARG;
     9132    }
     9133
     9134#ifdef WOLFSSL_SMALL_STACK
     9135    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
     9136                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
     9137    if (info == NULL)
     9138        return MEMORY_E;
     9139#endif
     9140
     9141    XMEMSET(info, 0, sizeof(EncryptedInfo));
     9142    info->passwd_cb = OurPasswordCb;
     9143    info->passwd_userdata = (void*)pass;
     9144
     9145    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
     9146
     9147#ifdef WOLFSSL_SMALL_STACK
     9148    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
     9149#endif
     9150
     9151    if (ret < 0) {
     9152        WOLFSSL_MSG("Bad Pem To Der");
     9153    }
     9154    else {
     9155        if (der->length <= (word32)buffSz) {
     9156            XMEMCPY(buff, der->buffer, der->length);
     9157            ret = der->length;
     9158        }
     9159        else {
     9160            WOLFSSL_MSG("Bad der length");
     9161            ret = BAD_FUNC_ARG;
     9162        }
     9163    }
     9164
     9165    FreeDer(&der);
     9166    return ret;
     9167}
     9168
     9169
     9170/* Return bytes written to buff or < 0 for error */
     9171int wc_CertPemToDer(const unsigned char* pem, int pemSz,
     9172                        unsigned char* buff, int buffSz, int type)
     9173{
     9174    int            eccKey = 0;
     9175    int            ret;
     9176    DerBuffer*     der = NULL;
     9177
     9178    WOLFSSL_ENTER("wc_CertPemToDer");
     9179
     9180    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9181        WOLFSSL_MSG("Bad pem der args");
     9182        return BAD_FUNC_ARG;
     9183    }
     9184
     9185    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
     9186        WOLFSSL_MSG("Bad cert type");
     9187        return BAD_FUNC_ARG;
     9188    }
     9189
     9190
     9191    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
     9192    if (ret < 0) {
     9193        WOLFSSL_MSG("Bad Pem To Der");
     9194    }
     9195    else {
     9196        if (der->length <= (word32)buffSz) {
     9197            XMEMCPY(buff, der->buffer, der->length);
     9198            ret = der->length;
     9199        }
     9200        else {
     9201            WOLFSSL_MSG("Bad der length");
     9202            ret = BAD_FUNC_ARG;
     9203        }
     9204    }
     9205
     9206    FreeDer(&der);
     9207    return ret;
     9208}
     9209
     9210#endif /* WOLFSSL_PEM_TO_DER */
     9211#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
     9212
     9213
     9214#ifdef WOLFSSL_PEM_TO_DER
     9215#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
     9216/* Return bytes written to buff or < 0 for error */
     9217int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
     9218                           unsigned char* buff, int buffSz)
     9219{
     9220    int ret;
     9221    DerBuffer* der = NULL;
     9222
     9223    WOLFSSL_ENTER("wc_PubKeyPemToDer");
     9224
     9225    if (pem == NULL || buff == NULL || buffSz <= 0) {
     9226        WOLFSSL_MSG("Bad pem der args");
     9227        return BAD_FUNC_ARG;
     9228    }
     9229
     9230    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
     9231    if (ret < 0) {
     9232        WOLFSSL_MSG("Bad Pem To Der");
     9233    }
     9234    else {
     9235        if (der->length <= (word32)buffSz) {
     9236            XMEMCPY(buff, der->buffer, der->length);
     9237            ret = der->length;
     9238        }
     9239        else {
     9240            WOLFSSL_MSG("Bad der length");
     9241            ret = BAD_FUNC_ARG;
     9242        }
     9243    }
     9244
     9245    FreeDer(&der);
     9246    return ret;
     9247}
     9248#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
     9249#endif /* WOLFSSL_PEM_TO_DER */
     9250
     9251#ifndef NO_FILESYSTEM
     9252
     9253#ifdef WOLFSSL_CERT_GEN
     9254/* load pem cert from file into der buffer, return der size or error */
     9255int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
     9256{
     9257#ifdef WOLFSSL_SMALL_STACK
     9258    byte   staticBuffer[1]; /* force XMALLOC */
     9259#else
     9260    byte   staticBuffer[FILE_BUFFER_SIZE];
     9261#endif
     9262    byte*  fileBuf = staticBuffer;
     9263    int    dynamic = 0;
     9264    int    ret     = 0;
     9265    long   sz      = 0;
     9266    XFILE  file;
     9267    DerBuffer* converted = NULL;
     9268
     9269    WOLFSSL_ENTER("wc_PemCertToDer");
     9270
     9271    if (fileName == NULL) {
     9272        ret = BAD_FUNC_ARG;
     9273    }
     9274    else {
     9275        file = XFOPEN(fileName, "rb");
     9276        if (file == XBADFILE) {
     9277            ret = BUFFER_E;
     9278        }
     9279    }
     9280
     9281    if (ret == 0) {
     9282        if(XFSEEK(file, 0, XSEEK_END) != 0)
     9283            ret = BUFFER_E;
     9284        sz = XFTELL(file);
     9285        XREWIND(file);
     9286
     9287        if (sz <= 0) {
     9288            ret = BUFFER_E;
     9289        }
     9290        else if (sz > (long)sizeof(staticBuffer)) {
     9291        #ifdef WOLFSSL_STATIC_MEMORY
     9292            WOLFSSL_MSG("File was larger then static buffer");
     9293            return MEMORY_E;
     9294        #endif
     9295            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
     9296            if (fileBuf == NULL)
     9297                ret = MEMORY_E;
     9298            else
     9299                dynamic = 1;
     9300        }
     9301
     9302        if (ret == 0) {
     9303            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
     9304                ret = BUFFER_E;
     9305            }
     9306        #ifdef WOLFSSL_PEM_TO_DER
     9307            else {
     9308                ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,  0, NULL,NULL);
     9309            }
     9310        #endif
     9311
     9312            if (ret == 0) {
     9313                if (converted->length < (word32)derSz) {
     9314                    XMEMCPY(derBuf, converted->buffer, converted->length);
     9315                    ret = converted->length;
     9316                }
     9317                else
     9318                    ret = BUFFER_E;
     9319            }
     9320
     9321            FreeDer(&converted);
     9322        }
     9323
     9324        XFCLOSE(file);
     9325        if (dynamic)
     9326            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
     9327    }
     9328
     9329    return ret;
     9330}
     9331#endif /* WOLFSSL_CERT_GEN */
     9332
     9333#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
     9334/* load pem public key from file into der buffer, return der size or error */
     9335int wc_PemPubKeyToDer(const char* fileName,
     9336                           unsigned char* derBuf, int derSz)
     9337{
     9338#ifdef WOLFSSL_SMALL_STACK
     9339    byte   staticBuffer[1]; /* force XMALLOC */
     9340#else
     9341    byte   staticBuffer[FILE_BUFFER_SIZE];
     9342#endif
     9343    byte*  fileBuf = staticBuffer;
     9344    int    dynamic = 0;
     9345    int    ret     = 0;
     9346    long   sz      = 0;
     9347    XFILE  file;
     9348    DerBuffer* converted = NULL;
     9349
     9350    WOLFSSL_ENTER("wc_PemPubKeyToDer");
     9351
     9352    if (fileName == NULL) {
     9353        ret = BAD_FUNC_ARG;
     9354    }
     9355    else {
     9356        file = XFOPEN(fileName, "rb");
     9357        if (file == XBADFILE) {
     9358            ret = BUFFER_E;
     9359        }
     9360    }
     9361
     9362    if (ret == 0) {
     9363        if(XFSEEK(file, 0, XSEEK_END) != 0)
     9364            ret = BUFFER_E;
     9365        sz = XFTELL(file);
     9366        XREWIND(file);
     9367
     9368        if (sz <= 0) {
     9369            ret = BUFFER_E;
     9370        }
     9371        else if (sz > (long)sizeof(staticBuffer)) {
     9372        #ifdef WOLFSSL_STATIC_MEMORY
     9373            WOLFSSL_MSG("File was larger then static buffer");
     9374            return MEMORY_E;
     9375        #endif
     9376            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
     9377            if (fileBuf == NULL)
     9378                ret = MEMORY_E;
     9379            else
     9380                dynamic = 1;
     9381        }
     9382        if (ret == 0) {
     9383            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
     9384                ret = BUFFER_E;
     9385            }
     9386        #ifdef WOLFSSL_PEM_TO_DER
     9387            else {
     9388                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
     9389                               0, NULL, NULL);
     9390            }
     9391        #endif
     9392
     9393            if (ret == 0) {
     9394                if (converted->length < (word32)derSz) {
     9395                    XMEMCPY(derBuf, converted->buffer, converted->length);
     9396                    ret = converted->length;
     9397                }
     9398                else
     9399                    ret = BUFFER_E;
     9400    }
     9401
     9402            FreeDer(&converted);
     9403    }
     9404
     9405        XFCLOSE(file);
     9406        if (dynamic)
     9407            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
     9408    }
     9409
     9410    return ret;
     9411}
     9412#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
     9413
     9414#endif /* !NO_FILESYSTEM */
     9415
    66969416
    66979417#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
    6698         (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)))
     9418    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
    66999419/* USER RSA ifdef portions used instead of refactor in consideration for
    67009420   possible fips build */
     
    67239443    /* n */
    67249444#ifdef WOLFSSL_SMALL_STACK
    6725     n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9445    n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67269446    if (n == NULL)
    67279447        return MEMORY_E;
     
    67359455    if (nSz < 0) {
    67369456#ifdef WOLFSSL_SMALL_STACK
    6737         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9457        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67389458#endif
    67399459        return nSz;
     
    67429462    /* e */
    67439463#ifdef WOLFSSL_SMALL_STACK
    6744     e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9464    e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67459465    if (e == NULL) {
    67469466#ifdef WOLFSSL_SMALL_STACK
    6747         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9467        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67489468#endif
    67499469        return MEMORY_E;
     
    67589478    if (eSz < 0) {
    67599479#ifdef WOLFSSL_SMALL_STACK
    6760         XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6761         XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9480        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9481        XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67629482#endif
    67639483        return eSz;
     
    67699489    if ( (seqSz + nSz + eSz) > outLen) {
    67709490#ifdef WOLFSSL_SMALL_STACK
    6771         XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6772         XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9491        XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9492        XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67739493#endif
    67749494        return BUFFER_E;
     
    67819501        byte* algo = NULL;
    67829502
    6783         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9503        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67849504        if (algo == NULL) {
    6785             XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6786             XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9505            XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9506            XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    67879507            return MEMORY_E;
    67889508        }
     
    67989518        if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
    67999519            #ifdef WOLFSSL_SMALL_STACK
    6800                 XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6801                 XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6802                 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9520                XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9521                XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9522                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    68039523            #endif
    68049524
     
    68139533        idx += bitStringSz;
    68149534#ifdef WOLFSSL_SMALL_STACK
    6815         XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9535        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    68169536#endif
    68179537    }
     
    68309550
    68319551#ifdef WOLFSSL_SMALL_STACK
    6832     XFREE(n,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6833     XFREE(e,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    6834 #endif
     9552    XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9553    XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9554#endif
     9555
     9556    return idx;
     9557}
     9558
     9559int RsaPublicKeyDerSize(RsaKey* key, int with_header)
     9560{
     9561    byte* dummy = NULL;
     9562    byte seq[MAX_SEQ_SZ];
     9563    byte bitString[1 + MAX_LENGTH_SZ + 1];
     9564    int  nSz;
     9565    int  eSz;
     9566    int  seqSz;
     9567    int  bitStringSz;
     9568    int  idx;
     9569
     9570    if (key == NULL)
     9571        return BAD_FUNC_ARG;
     9572
     9573    /* n */
     9574    dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9575    if (dummy == NULL)
     9576        return MEMORY_E;
     9577
     9578#ifdef HAVE_USER_RSA
     9579    nSz = SetASNIntRSA(key->n, dummy);
     9580#else
     9581    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, dummy);
     9582#endif
     9583    XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9584    if (nSz < 0) {
     9585        return nSz;
     9586    }
     9587
     9588    /* e */
     9589    dummy = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9590    if (dummy == NULL) {
     9591        XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9592        return MEMORY_E;
     9593    }
     9594
     9595#ifdef HAVE_USER_RSA
     9596    eSz = SetASNIntRSA(key->e, dummy);
     9597#else
     9598    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, dummy);
     9599#endif
     9600    XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9601    if (eSz < 0) {
     9602        return eSz;
     9603    }
     9604
     9605    seqSz  = SetSequence(nSz + eSz, seq);
     9606
     9607    /* headers */
     9608    if (with_header) {
     9609        int  algoSz;
     9610        dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9611        if (dummy == NULL)
     9612            return MEMORY_E;
     9613
     9614        algoSz = SetAlgoID(RSAk, dummy, oidKeyType, 0);
     9615        bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);
     9616
     9617        idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, dummy);
     9618        XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9619
     9620        /* algo */
     9621        idx += algoSz;
     9622        /* bit string */
     9623        idx += bitStringSz;
     9624    }
     9625    else
     9626        idx = 0;
     9627
     9628    /* seq */
     9629    idx += seqSz;
     9630    /* n */
     9631    idx += nSz;
     9632    /* e */
     9633    idx += eSz;
    68359634
    68369635    return idx;
     
    68419640
    68429641#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
    6843 
    68449642
    68459643static mp_int* GetRsaInt(RsaKey* key, int idx)
     
    68679665
    68689666/* Release Tmp RSA resources */
    6869 static INLINE void FreeTmpRsas(byte** tmps, void* heap)
     9667static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
    68709668{
    68719669    int i;
     
    69299727
    69309728    outLen = seqSz + verSz + intTotalLen;
    6931     if (outLen > (int)inLen)
     9729    if (outLen > (int)inLen) {
     9730        FreeTmpRsas(tmps, key->heap);
    69329731        return BAD_FUNC_ARG;
     9732    }
    69339733
    69349734    /* write to output */
     
    69469746    return outLen;
    69479747}
    6948 
    6949 
     9748#endif
     9749
     9750#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
    69509751/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
    69519752   written */
     
    69559756}
    69569757
    6957 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
     9758#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
    69589759
    69599760
     
    69719772int wc_InitCert(Cert* cert)
    69729773{
     9774#ifdef WOLFSSL_MULTI_ATTRIB
     9775    int i = 0;
     9776#endif
    69739777    if (cert == NULL) {
    69749778        return BAD_FUNC_ARG;
    69759779    }
    69769780
     9781    XMEMSET(cert, 0, sizeof(Cert));
     9782
    69779783    cert->version    = 2;   /* version 3 is hex 2 */
     9784#ifndef NO_SHA
    69789785    cert->sigType    = CTC_SHAwRSA;
     9786#elif !defined(NO_SHA256)
     9787    cert->sigType    = CTC_SHA256wRSA;
     9788#else
     9789    cert->sigType    = 0;
     9790#endif
    69799791    cert->daysValid  = 500;
    69809792    cert->selfSigned = 1;
    6981     cert->isCA       = 0;
    6982     cert->bodySz     = 0;
    6983 #ifdef WOLFSSL_ALT_NAMES
    6984     cert->altNamesSz   = 0;
    6985     cert->beforeDateSz = 0;
    6986     cert->afterDateSz  = 0;
    6987 #endif
    6988 #ifdef WOLFSSL_CERT_EXT
    6989     cert->skidSz = 0;
    6990     cert->akidSz = 0;
    6991     cert->keyUsage = 0;
    6992     cert->extKeyUsage = 0;
    6993     cert->certPoliciesNb = 0;
    6994     XMEMSET(cert->akid, 0, CTC_MAX_AKID_SIZE);
    6995     XMEMSET(cert->skid, 0, CTC_MAX_SKID_SIZE);
    6996     XMEMSET(cert->certPolicies, 0, CTC_MAX_CERTPOL_NB*CTC_MAX_CERTPOL_SZ);
    6997 #endif
    69989793    cert->keyType    = RSA_KEY;
    6999     XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
    7000     cert->serialSz = 0;
    7001 
    7002     cert->issuer.country[0] = '\0';
     9794
    70039795    cert->issuer.countryEnc = CTC_PRINTABLE;
    7004     cert->issuer.state[0] = '\0';
    70059796    cert->issuer.stateEnc = CTC_UTF8;
    7006     cert->issuer.locality[0] = '\0';
    70079797    cert->issuer.localityEnc = CTC_UTF8;
    7008     cert->issuer.sur[0] = '\0';
    70099798    cert->issuer.surEnc = CTC_UTF8;
    7010     cert->issuer.org[0] = '\0';
    70119799    cert->issuer.orgEnc = CTC_UTF8;
    7012     cert->issuer.unit[0] = '\0';
    70139800    cert->issuer.unitEnc = CTC_UTF8;
    7014     cert->issuer.commonName[0] = '\0';
    70159801    cert->issuer.commonNameEnc = CTC_UTF8;
    7016     cert->issuer.email[0] = '\0';
    7017 
    7018     cert->subject.country[0] = '\0';
     9802
    70199803    cert->subject.countryEnc = CTC_PRINTABLE;
    7020     cert->subject.state[0] = '\0';
    70219804    cert->subject.stateEnc = CTC_UTF8;
    7022     cert->subject.locality[0] = '\0';
    70239805    cert->subject.localityEnc = CTC_UTF8;
    7024     cert->subject.sur[0] = '\0';
    70259806    cert->subject.surEnc = CTC_UTF8;
    7026     cert->subject.org[0] = '\0';
    70279807    cert->subject.orgEnc = CTC_UTF8;
    7028     cert->subject.unit[0] = '\0';
    70299808    cert->subject.unitEnc = CTC_UTF8;
    7030     cert->subject.commonName[0] = '\0';
    70319809    cert->subject.commonNameEnc = CTC_UTF8;
    7032     cert->subject.email[0] = '\0';
    7033 
    7034 #ifdef WOLFSSL_CERT_REQ
    7035     cert->challengePw[0] ='\0';
    7036 #endif
     9810
     9811#ifdef WOLFSSL_MULTI_ATTRIB
     9812    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
     9813        cert->issuer.name[i].type   = CTC_UTF8;
     9814        cert->subject.name[i].type  = CTC_UTF8;
     9815    }
     9816#endif /* WOLFSSL_MULTI_ATTRIB */
     9817
    70379818#ifdef WOLFSSL_HEAP_TEST
    70389819    cert->heap = (void*)WOLFSSL_HEAP_TEST;
    7039 #else
    7040     cert->heap = NULL;
    70419820#endif
    70429821
     
    70499828    byte size[MAX_LENGTH_SZ];          /* length encoded */
    70509829    byte version[MAX_VERSION_SZ];      /* version encoded */
    7051     byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */
     9830    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
    70529831    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
    70539832    byte issuer[ASN_NAME_MAX];         /* issuer  encoded */
     
    71109889#endif /*WOLFSSL_CERT_GEN */
    71119890
    7112 #if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
     9891
     9892#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
    71139893
    71149894/* Write a public ECC key to output */
     
    71309910    byte pub[ECC_BUFSIZE];
    71319911#endif
     9912    int ret;
    71329913
    71339914#ifdef WOLFSSL_SMALL_STACK
    7134     pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9915    pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71359916    if (pub == NULL)
    71369917        return MEMORY_E;
    71379918#endif
    71389919
    7139     int ret = wc_ecc_export_x963(key, pub, &pubSz);
     9920    ret = wc_ecc_export_x963(key, pub, &pubSz);
    71409921    if (ret != 0) {
    71419922#ifdef WOLFSSL_SMALL_STACK
    7142         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9923        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71439924#endif
    71449925        return ret;
     
    71489929    if (with_header) {
    71499930#ifdef WOLFSSL_SMALL_STACK
    7150         curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9931        curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71519932        if (curve == NULL) {
    7152             XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9933            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71539934            return MEMORY_E;
    71549935        }
     
    71579938        if (curveSz <= 0) {
    71589939#ifdef WOLFSSL_SMALL_STACK
    7159             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7160             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9940            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9941            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71619942#endif
    71629943            return curveSz;
     
    71649945
    71659946#ifdef WOLFSSL_SMALL_STACK
    7166         algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9947        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71679948        if (algo == NULL) {
    7168             XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7169             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9949            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9950            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    71709951            return MEMORY_E;
    71719952        }
     
    71959976#ifdef WOLFSSL_SMALL_STACK
    71969977    if (with_header) {
    7197         XFREE(algo,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7198         XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    7199     }
    7200     XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     9978        XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9979        XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     9980    }
     9981    XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    72019982#endif
    72029983
     
    724110022    return SetEccPublicKey(output, key, with_AlgCurve);
    724210023}
    7243 #endif /* HAVE_ECC && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
     10024#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
    724410025
    724510026#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \
     
    727110052    if (ret != 0) {
    727210053#ifdef WOLFSSL_SMALL_STACK
    7273         XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     10054        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    727410055#endif
    727510056        return ret;
     
    728110062        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    728210063        if (algo == NULL) {
    7283             XFREE(pub,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
     10064            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    728410065            return MEMORY_E;
    728510066        }
     
    735110132#ifdef WOLFSSL_CERT_GEN
    735210133
    7353 static INLINE byte itob(int number)
     10134static WC_INLINE byte itob(int number)
    735410135{
    735510136    return (byte)number + 0x30;
     
    740610187
    740710188
    7408 /* for systems where mktime() doesn't normalize fully */
    7409 static void RebuildTime(time_t* in, struct tm* out)
    7410 {
    7411     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
    7412         out = localtime_r(in, out);
    7413     #else
    7414         (void)in;
    7415         (void)out;
    7416     #endif
    7417 }
    7418 
    7419 
    742010189/* Set Date validity from now until now + daysValid
    742110190 * return size in bytes written to output, 0 on error */
     
    742910198    int seqSz;
    743010199
    7431     time_t     ticks;
    7432     time_t     normalTime;
    7433     struct tm* now;
     10200    time_t now;
     10201    time_t then;
    743410202    struct tm* tmpTime = NULL;
    7435     struct tm  local;
     10203    struct tm* expandedTime;
     10204    struct tm localTime;
    743610205
    743710206#if defined(NEED_TMP_TIME)
     
    744310212#endif
    744410213
    7445     ticks = XTIME(0);
    7446     now   = XGMTIME(&ticks, tmpTime);
    7447 
    7448     if (now == NULL) {
     10214    now = XTIME(0);
     10215
     10216    /* before now */
     10217    before[0] = ASN_GENERALIZED_TIME;
     10218    beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
     10219
     10220    /* subtract 1 day of seconds for more compliance */
     10221    then = now - 86400;
     10222    expandedTime = XGMTIME(&then, tmpTime);
     10223    if (expandedTime == NULL) {
    744910224        WOLFSSL_MSG("XGMTIME failed");
    745010225        return 0;   /* error */
    745110226    }
    7452 
    7453     /* before now */
    7454     local = *now;
    7455     before[0] = ASN_GENERALIZED_TIME;
    7456     beforeSz  = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
    7457 
    7458     /* subtract 1 day for more compliance */
    7459     local.tm_mday -= 1;
    7460     normalTime = mktime(&local);
    7461     RebuildTime(&normalTime, &local);
     10227    localTime = *expandedTime;
    746210228
    746310229    /* adjust */
    7464     local.tm_year += 1900;
    7465     local.tm_mon +=    1;
    7466 
    7467     SetTime(&local, before + beforeSz);
     10230    localTime.tm_year += 1900;
     10231    localTime.tm_mon +=    1;
     10232
     10233    SetTime(&localTime, before + beforeSz);
    746810234    beforeSz += ASN_GEN_TIME_SZ;
    746910235
    7470     /* after now + daysValid */
    7471     local = *now;
    747210236    after[0] = ASN_GENERALIZED_TIME;
    747310237    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
    747410238
    7475     /* add daysValid */
    7476     local.tm_mday += daysValid;
    7477     normalTime = mktime(&local);
    7478     RebuildTime(&normalTime, &local);
     10239    /* add daysValid of seconds */
     10240    then = now + (daysValid * 86400);
     10241    expandedTime = XGMTIME(&then, tmpTime);
     10242    if (expandedTime == NULL) {
     10243        WOLFSSL_MSG("XGMTIME failed");
     10244        return 0;   /* error */
     10245    }
     10246    localTime = *expandedTime;
    747910247
    748010248    /* adjust */
    7481     local.tm_year += 1900;
    7482     local.tm_mon  +=    1;
    7483 
    7484     SetTime(&local, after + afterSz);
     10249    localTime.tm_year += 1900;
     10250    localTime.tm_mon  +=    1;
     10251
     10252    SetTime(&localTime, after + afterSz);
    748510253    afterSz += ASN_GEN_TIME_SZ;
    748610254
     
    753010298
    753110299    case 7:
     10300       return name->serialDev;
     10301
     10302#ifdef WOLFSSL_CERT_EXT
     10303    case 8:
     10304       return name->busCat;
     10305
     10306    case 9:
     10307#else
     10308    case 8:
     10309#endif
    753210310       return name->email;
    753310311
     
    756310341       return name->commonNameEnc;
    756410342
     10343    case 7:
     10344       return name->serialDevEnc;
     10345
     10346#ifdef WOLFSSL_CERT_EXT
     10347    case 8:
     10348       return name->busCatEnc;
     10349
     10350    case 9:
     10351#else
     10352    case 8:
     10353#endif
     10354        /* FALL THROUGH */
     10355        /* The last index, email name, does not have encoding type.
     10356           The empty case here is to keep track of it for future reference. */
    756510357    default:
    756610358       return 0;
     
    759510387
    759610388    case 7:
    7597        /* email uses different id type */
    7598        return 0;
     10389       return ASN_SERIAL_NUMBER;
     10390
     10391#ifdef WOLFSSL_CERT_EXT
     10392    case 8:
     10393        return ASN_BUS_CAT;
     10394
     10395    case 9:
     10396#else
     10397    case 8:
     10398#endif
     10399        return ASN_EMAIL_NAME;
    759910400
    760010401    default:
     
    781410615
    781510616/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
    7816 static int SetExtKeyUsage(byte* output, word32 outSz, byte input)
     10617static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
    781710618{
    781810619    int idx = 0, oidListSz = 0, totalSz, ret = 0;
     
    785110652            ret |= SetOjectIdValue(output, outSz, &idx,
    785210653                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
     10654    #ifdef WOLFSSL_EKU_OID
     10655        /* iterate through OID values */
     10656        if (input & EXTKEYUSE_USER) {
     10657            int i, sz;
     10658            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
     10659                sz = cert->extKeyUsageOIDSz[i];
     10660                if (sz > 0) {
     10661                    ret |= SetOjectIdValue(output, outSz, &idx,
     10662                        cert->extKeyUsageOID[i], sz);
     10663                }
     10664            }
     10665        }
     10666    #endif /* WOLFSSL_EKU_OID */
    785310667    }
    785410668    if (ret != 0)
     
    787510689    idx += oidListSz;
    787610690
     10691    (void)cert;
    787710692    return idx;
    787810693}
     
    789410709        return MEMORY_E;
    789510710
    7896     XSTRNCPY(str, in, len);
    7897     str[len] = 0x00;
     10711    XSTRNCPY(str, in, len+1);
    789810712
    789910713    nb_val = 0;
     
    803310847#endif /* WOLFSL_ALT_NAMES */
    803410848
     10849/* Encodes one attribute of the name (issuer/subject)
     10850 *
     10851 * name     structure to hold result of encoding
     10852 * nameStr  value to be encoded
     10853 * nameType type of encoding i.e CTC_UTF8
     10854 * type     id of attribute i.e ASN_COMMON_NAME
     10855 *
     10856 * returns length on success
     10857 */
     10858static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
     10859        byte type)
     10860{
     10861    word32 idx = 0;
     10862
     10863    if (nameStr) {
     10864        /* bottom up */
     10865        byte firstLen[1 + MAX_LENGTH_SZ];
     10866        byte secondLen[MAX_LENGTH_SZ];
     10867        byte sequence[MAX_SEQ_SZ];
     10868        byte set[MAX_SET_SZ];
     10869
     10870        int strLen  = (int)XSTRLEN(nameStr);
     10871        int thisLen = strLen;
     10872        int firstSz, secondSz, seqSz, setSz;
     10873
     10874        if (strLen == 0) { /* no user data for this item */
     10875            name->used = 0;
     10876            return 0;
     10877        }
     10878
     10879        /* Restrict country code size */
     10880        if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
     10881            return ASN_COUNTRY_SIZE_E;
     10882        }
     10883
     10884        secondSz = SetLength(strLen, secondLen);
     10885        thisLen += secondSz;
     10886        switch (type) {
     10887            case ASN_EMAIL_NAME: /* email */
     10888                thisLen += EMAIL_JOINT_LEN;
     10889                firstSz  = EMAIL_JOINT_LEN;
     10890                break;
     10891
     10892            case ASN_DOMAIN_COMPONENT:
     10893                thisLen += PILOT_JOINT_LEN;
     10894                firstSz  = PILOT_JOINT_LEN;
     10895                break;
     10896
     10897            default:
     10898                thisLen++;                                 /* str type */
     10899                thisLen += JOINT_LEN;
     10900                firstSz  = JOINT_LEN + 1;
     10901        }
     10902        thisLen++; /* id  type */
     10903        firstSz  = SetObjectId(firstSz, firstLen);
     10904        thisLen += firstSz;
     10905
     10906        seqSz = SetSequence(thisLen, sequence);
     10907        thisLen += seqSz;
     10908        setSz = SetSet(thisLen, set);
     10909        thisLen += setSz;
     10910
     10911        if (thisLen > (int)sizeof(name->encoded)) {
     10912            return BUFFER_E;
     10913        }
     10914
     10915        /* store it */
     10916        idx = 0;
     10917        /* set */
     10918        XMEMCPY(name->encoded, set, setSz);
     10919        idx += setSz;
     10920        /* seq */
     10921        XMEMCPY(name->encoded + idx, sequence, seqSz);
     10922        idx += seqSz;
     10923        /* asn object id */
     10924        XMEMCPY(name->encoded + idx, firstLen, firstSz);
     10925        idx += firstSz;
     10926        switch (type) {
     10927            case ASN_EMAIL_NAME:
     10928                {
     10929                    const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
     10930                                       0x01, 0x09, 0x01, 0x16 };
     10931                    /* email joint id */
     10932                    XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
     10933                    idx += (int)sizeof(EMAIL_OID);
     10934                }
     10935                break;
     10936
     10937            case ASN_DOMAIN_COMPONENT:
     10938                {
     10939                    const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
     10940                                    0x93, 0xF2, 0x2C, 0x64, 0x01
     10941                    };
     10942
     10943                    XMEMCPY(name->encoded + idx, PILOT_OID,
     10944                                                     sizeof(PILOT_OID));
     10945                    idx += (int)sizeof(PILOT_OID);
     10946                    /* id type */
     10947                    name->encoded[idx++] = type;
     10948                    /* str type */
     10949                    name->encoded[idx++] = nameType;
     10950                }
     10951                break;
     10952
     10953            default:
     10954                name->encoded[idx++] = 0x55;
     10955                name->encoded[idx++] = 0x04;
     10956                /* id type */
     10957                name->encoded[idx++] = type;
     10958                /* str type */
     10959                name->encoded[idx++] = nameType;
     10960        }
     10961        /* second length */
     10962        XMEMCPY(name->encoded + idx, secondLen, secondSz);
     10963        idx += secondSz;
     10964        /* str value */
     10965        XMEMCPY(name->encoded + idx, nameStr, strLen);
     10966        idx += strLen;
     10967
     10968        name->type = type;
     10969        name->totalLen = idx;
     10970        name->used = 1;
     10971    }
     10972    else
     10973        name->used = 0;
     10974
     10975    return idx;
     10976}
    803510977
    803610978/* encode CertName into output, return total bytes written */
     
    804310985    EncodedName  names[NAME_ENTRIES];
    804410986#endif
     10987#ifdef WOLFSSL_MULTI_ATTRIB
     10988    EncodedName addNames[CTC_MAX_ATTRIB];
     10989    int j, type;
     10990#endif
    804510991
    804610992    if (output == NULL || name == NULL)
     
    805811004
    805911005    for (i = 0; i < NAME_ENTRIES; i++) {
     11006        int ret;
    806011007        const char* nameStr = GetOneName(name, i);
    8061         if (nameStr) {
    8062             /* bottom up */
    8063             byte firstLen[1 + MAX_LENGTH_SZ];
    8064             byte secondLen[MAX_LENGTH_SZ];
    8065             byte sequence[MAX_SEQ_SZ];
    8066             byte set[MAX_SET_SZ];
    8067 
    8068             int email = i == (NAME_ENTRIES - 1) ? 1 : 0;
    8069             int strLen  = (int)XSTRLEN(nameStr);
    8070             int thisLen = strLen;
    8071             int firstSz, secondSz, seqSz, setSz;
    8072 
    8073             if (strLen == 0) { /* no user data for this item */
    8074                 names[i].used = 0;
    8075                 continue;
    8076             }
    8077 
    8078             /* Restrict country code size */
    8079             if (i == 0 && strLen != CTC_COUNTRY_SIZE) {
     11008
     11009        ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
     11010                          GetNameId(i));
     11011        if (ret < 0) {
    808011012#ifdef WOLFSSL_SMALL_STACK
    808111013                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    808211014#endif
    8083                 return ASN_COUNTRY_SIZE_E;
    8084             }
    8085 
    8086             secondSz = SetLength(strLen, secondLen);
    8087             thisLen += secondSz;
    8088             if (email) {
    8089                 thisLen += EMAIL_JOINT_LEN;
    8090                 thisLen ++;                               /* id type */
    8091                 firstSz  = SetObjectId(EMAIL_JOINT_LEN, firstLen);
    8092             }
    8093             else {
    8094                 thisLen++;                                 /* str type */
    8095                 thisLen++;                                 /* id  type */
    8096                 thisLen += JOINT_LEN;
    8097                 firstSz  = SetObjectId(JOINT_LEN + 1, firstLen);
    8098             }
    8099             thisLen += firstSz;
    8100 
    8101             seqSz = SetSequence(thisLen, sequence);
    8102             thisLen += seqSz;
    8103             setSz = SetSet(thisLen, set);
    8104             thisLen += setSz;
    8105 
    8106             if (thisLen > (int)sizeof(names[i].encoded)) {
     11015                return BUFFER_E;
     11016            }
     11017        totalBytes += ret;
     11018            }
     11019#ifdef WOLFSSL_MULTI_ATTRIB
     11020    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
     11021        if (name->name[i].sz > 0) {
     11022            int ret;
     11023            ret = wc_EncodeName(&addNames[i], name->name[i].value,
     11024                        name->name[i].type, name->name[i].id);
     11025            if (ret < 0) {
    810711026#ifdef WOLFSSL_SMALL_STACK
    810811027                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    811011029                return BUFFER_E;
    811111030            }
    8112 
    8113             /* store it */
    8114             idx = 0;
    8115             /* set */
    8116             XMEMCPY(names[i].encoded, set, setSz);
    8117             idx += setSz;
    8118             /* seq */
    8119             XMEMCPY(names[i].encoded + idx, sequence, seqSz);
    8120             idx += seqSz;
    8121             /* asn object id */
    8122             XMEMCPY(names[i].encoded + idx, firstLen, firstSz);
    8123             idx += firstSz;
    8124             if (email) {
    8125                 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
    8126                                            0x01, 0x09, 0x01, 0x16 };
    8127                 /* email joint id */
    8128                 XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
    8129                 idx += (int)sizeof(EMAIL_OID);
     11031            totalBytes += ret;
    813011032            }
    813111033            else {
    8132                 /* joint id */
    8133                 byte bType = GetNameId(i);
    8134                 names[i].encoded[idx++] = 0x55;
    8135                 names[i].encoded[idx++] = 0x04;
    8136                 /* id type */
    8137                 names[i].encoded[idx++] = bType;
    8138                 /* str type */
    8139                 names[i].encoded[idx++] = GetNameType(name, i);
    8140             }
    8141             /* second length */
    8142             XMEMCPY(names[i].encoded + idx, secondLen, secondSz);
    8143             idx += secondSz;
    8144             /* str value */
    8145             XMEMCPY(names[i].encoded + idx, nameStr, strLen);
    8146             idx += strLen;
    8147 
    8148             totalBytes += idx;
    8149             names[i].totalLen = idx;
    8150             names[i].used = 1;
    8151         }
    8152         else
    8153             names[i].used = 0;
    8154     }
     11034            addNames[i].used = 0;
     11035        }
     11036    }
     11037#endif /* WOLFSSL_MULTI_ATTRIB */
    815511038
    815611039    /* header */
     
    816511048
    816611049    for (i = 0; i < NAME_ENTRIES; i++) {
     11050    #ifdef WOLFSSL_MULTI_ATTRIB
     11051        type = GetNameId(i);
     11052
     11053        /* list all DC values before OUs */
     11054        if (type == ASN_ORGUNIT_NAME) {
     11055            type = ASN_DOMAIN_COMPONENT;
     11056            for (j = 0; j < CTC_MAX_ATTRIB; j++) {
     11057                if (name->name[j].sz > 0 && type == name->name[j].id) {
     11058                    if (outputSz < (word32)(idx+addNames[j].totalLen)) {
     11059                    #ifdef WOLFSSL_SMALL_STACK
     11060                        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11061                    #endif
     11062                        return BUFFER_E;
     11063                    }
     11064
     11065                    XMEMCPY(output + idx, addNames[j].encoded,
     11066                            addNames[j].totalLen);
     11067                    idx += addNames[j].totalLen;
     11068                }
     11069            }
     11070            type = ASN_ORGUNIT_NAME;
     11071        }
     11072
     11073        /* write all similar types to the buffer */
     11074        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
     11075            if (name->name[j].sz > 0 && type == name->name[j].id) {
     11076                if (outputSz < (word32)(idx+addNames[j].totalLen)) {
     11077                #ifdef WOLFSSL_SMALL_STACK
     11078                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11079                #endif
     11080                    return BUFFER_E;
     11081                }
     11082
     11083                XMEMCPY(output + idx, addNames[j].encoded,
     11084                        addNames[j].totalLen);
     11085                idx += addNames[j].totalLen;
     11086            }
     11087        }
     11088    #endif /* WOLFSSL_MULTI_ATTRIB */
     11089
    816711090        if (names[i].used) {
    816811091            if (outputSz < (word32)(idx+names[i].totalLen)) {
     
    829611219
    829711220    /* subject name */
    8298     der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
     11221#ifdef WOLFSSL_CERT_EXT
     11222    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
     11223        /* Use the raw subject */
     11224        int idx;
     11225
     11226        der->subjectSz = min(sizeof(der->subject),
     11227                (word32)XSTRLEN((const char*)cert->sbjRaw));
     11228        /* header */
     11229        idx = SetSequence(der->subjectSz, der->subject);
     11230        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
     11231            return SUBJECT_E;
     11232        }
     11233
     11234        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
     11235                der->subjectSz);
     11236        der->subjectSz += idx;
     11237    }
     11238    else
     11239#endif
     11240    {
     11241        /* Use the name structure */
     11242        der->subjectSz = SetName(der->subject, sizeof(der->subject),
     11243                &cert->subject);
     11244    }
    829911245    if (der->subjectSz <= 0)
    830011246        return SUBJECT_E;
    830111247
    830211248    /* issuer name */
    8303     der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
    8304              &cert->subject : &cert->issuer);
     11249#ifdef WOLFSSL_CERT_EXT
     11250    if (XSTRLEN((const char*)cert->issRaw) > 0) {
     11251        /* Use the raw issuer */
     11252        int idx;
     11253
     11254        der->issuerSz = min(sizeof(der->issuer),
     11255                (word32)XSTRLEN((const char*)cert->issRaw));
     11256        /* header */
     11257        idx = SetSequence(der->issuerSz, der->issuer);
     11258        if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
     11259            return ISSUER_E;
     11260        }
     11261
     11262        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
     11263                der->issuerSz);
     11264        der->issuerSz += idx;
     11265    }
     11266    else
     11267#endif
     11268    {
     11269        /* Use the name structure */
     11270        der->issuerSz = SetName(der->issuer, sizeof(der->issuer),
     11271                cert->selfSigned ? &cert->subject : &cert->issuer);
     11272    }
    830511273    if (der->issuerSz <= 0)
    830611274        return ISSUER_E;
     
    833811306    if (cert->skidSz) {
    833911307        /* check the provided SKID size */
    8340         if (cert->skidSz > (int)sizeof(der->skid))
     11308        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
    834111309            return SKID_E;
    834211310
     
    835611324    if (cert->akidSz) {
    835711325        /* check the provided AKID size */
    8358         if (cert->akidSz > (int)sizeof(der->akid))
     11326        if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
    835911327            return AKID_E;
    836011328
     
    838311351    /* Extended Key Usage */
    838411352    if (cert->extKeyUsage != 0){
    8385         der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
     11353        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
    838611354                                sizeof(der->extKeyUsage), cert->extKeyUsage);
    838711355        if (der->extKeyUsageSz <= 0)
     
    868711655
    868811656#ifdef WOLFSSL_SMALL_STACK
    8689     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11657    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    869011658    if (der == NULL)
    869111659        return MEMORY_E;
     
    870211670
    870311671#ifdef WOLFSSL_SMALL_STACK
    8704     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     11672    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    870511673#endif
    870611674
     
    874111709                  const byte* ntruKey, word16 keySz, WC_RNG* rng)
    874211710{
    8743     return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz);
     11711    return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);
    874411712}
    874511713
     
    888911857    if (cert->skidSz) {
    889011858        /* check the provided SKID size */
    8891         if (cert->skidSz > (int)sizeof(der->skid))
     11859        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
    889211860            return SKID_E;
    889311861
     
    891611884    /* Extended Key Usage */
    891711885    if (cert->extKeyUsage != 0){
    8918         der->extKeyUsageSz = SetExtKeyUsage(der->extKeyUsage,
     11886        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
    891911887                                sizeof(der->extKeyUsage), cert->extKeyUsage);
    892011888        if (der->extKeyUsageSz <= 0)
     
    904112009
    904212010#ifdef WOLFSSL_SMALL_STACK
    9043     der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12011    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
     12012                                                    DYNAMIC_TYPE_TMP_BUFFER);
    904412013    if (der == NULL)
    904512014        return MEMORY_E;
     
    905612025
    905712026#ifdef WOLFSSL_SMALL_STACK
    9058     XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12027    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    905912028#endif
    906012029
     
    914012109    sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,
    914112110        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap);
    9142     if (sigSz == WC_PENDING_E)
     12111    if (sigSz == WC_PENDING_E) {
     12112        /* Not free'ing certSignCtx->sig here because it could still be in use
     12113         * with async operations. */
    914312114        return sigSz;
     12115    }
    914412116
    914512117    if (sigSz >= 0) {
     
    914712119            sigSz = BUFFER_E;
    914812120        else
    9149             sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz, sType);
     12121            sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz,
     12122                                 sType);
    915012123    }
    915112124
     
    919612169
    919712170#ifdef WOLFSSL_CERT_EXT
     12171
     12172/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
     12173   The raw subject pointer will only be valid while "cert" is valid. */
     12174int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
     12175{
     12176    int rc = BAD_FUNC_ARG;
     12177    if ((subjectRaw != NULL) && (cert != NULL)) {
     12178        *subjectRaw = cert->sbjRaw;
     12179        rc = 0;
     12180    }
     12181    return rc;
     12182}
    919812183
    919912184/* Set KID from public key */
     
    925212237
    925312238    /* Compute SKID by hashing public key */
    9254 #ifdef NO_SHA
    925512239    if (kid_type == SKID_TYPE) {
    9256         ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
    9257         cert->skidSz = WC_SHA256_DIGEST_SIZE;
     12240        ret = CalcHashId(buffer, bufferSz, cert->skid);
     12241        cert->skidSz = KEYID_SIZE;
    925812242    }
    925912243    else if (kid_type == AKID_TYPE) {
    9260         ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
    9261         cert->akidSz = WC_SHA256_DIGEST_SIZE;
     12244        ret = CalcHashId(buffer, bufferSz, cert->akid);
     12245        cert->akidSz = KEYID_SIZE;
    926212246    }
    926312247    else
    926412248        ret = BAD_FUNC_ARG;
    9265 #else /* NO_SHA */
    9266     if (kid_type == SKID_TYPE) {
    9267         ret = wc_ShaHash(buffer, bufferSz, cert->skid);
    9268         cert->skidSz = WC_SHA_DIGEST_SIZE;
    9269     }
    9270     else if (kid_type == AKID_TYPE) {
    9271         ret = wc_ShaHash(buffer, bufferSz, cert->akid);
    9272         cert->akidSz = WC_SHA_DIGEST_SIZE;
    9273     }
    9274     else
    9275         ret = BAD_FUNC_ARG;
    9276 #endif /* NO_SHA */
    927712249
    927812250    XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     
    933712309
    933812310
    9339 #ifndef NO_FILESYSTEM
     12311#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
    934012312
    934112313/* Set SKID from public key file in PEM */
     
    935712329    }
    935812330
    9359     derSz = wolfSSL_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
     12331    derSz = wc_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
    936012332    if (derSz <= 0)
    936112333    {
     
    941312385            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
    941412386            wc_ecc_free(eckey);
     12387            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
    941512388            return PUBLIC_KEY_E;
    941612389        }
     
    943612409}
    943712410
    9438 #endif /* NO_FILESYSTEM */
     12411#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
    943912412
    944012413/* Set AKID from certificate contains in buffer (DER encoded) */
     
    945412427#ifdef WOLFSSL_SMALL_STACK
    945512428    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
    9456                                     NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12429                                    cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    945712430    if (decoded == NULL)
    945812431        return MEMORY_E;
     
    946012433
    946112434    /* decode certificate and get SKID that will be AKID of current cert */
    9462     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12435    InitDecodedCert(decoded, der, derSz, NULL);
    946312436    ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
    946412437    if (ret != 0) {
    946512438        FreeDecodedCert(decoded);
    946612439        #ifdef WOLFSSL_SMALL_STACK
    9467             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12440            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    946812441        #endif
    946912442        return ret;
     
    947412447        FreeDecodedCert(decoded);
    947512448        #ifdef WOLFSSL_SMALL_STACK
    9476             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12449            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    947712450        #endif
    947812451        return ASN_NO_SKID;
     
    948312456        FreeDecodedCert(decoded);
    948412457        #ifdef WOLFSSL_SMALL_STACK
    9485             XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12458            XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    948612459        #endif
    948712460        return MEMORY_E;
     
    949412467    FreeDecodedCert(decoded);
    949512468    #ifdef WOLFSSL_SMALL_STACK
    9496         XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12469        XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    949712470    #endif
    949812471
     
    951912492    }
    952012493
    9521     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
     12494    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
    952212495    if (derSz <= 0)
    952312496    {
     
    953212505}
    953312506
    9534 #endif /* NO_FILESYSTEM */
     12507#endif /* !NO_FILESYSTEM */
    953512508
    953612509/* Set KeyUsage from human readable string */
     
    954612519    cert->keyUsage = 0;
    954712520
    9548     str = (char*)XMALLOC(XSTRLEN(value)+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     12521    len = (word32)XSTRLEN(value);
     12522    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    954912523    if (str == NULL)
    955012524        return MEMORY_E;
    955112525
    9552     XMEMSET(str, 0, XSTRLEN(value)+1);
    9553     XSTRNCPY(str, value, XSTRLEN(value));
     12526    XSTRNCPY(str, value, len+1);
    955412527
    955512528    /* parse value, and set corresponding Key Usage value */
     
    960512578    cert->extKeyUsage = 0;
    960612579
    9607     str = (char*)XMALLOC(XSTRLEN(value)+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
     12580    len = (word32)XSTRLEN(value);
     12581    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    960812582    if (str == NULL)
    960912583        return MEMORY_E;
    961012584
    9611     XMEMSET(str, 0, XSTRLEN(value)+1);
    9612     XSTRNCPY(str, value, XSTRLEN(value));
     12585    XSTRNCPY(str, value, len+1);
    961312586
    961412587    /* parse value, and set corresponding Key Usage value */
     
    964712620    return ret;
    964812621}
     12622
     12623#ifdef WOLFSSL_EKU_OID
     12624/*
     12625 * cert structure to set EKU oid in
     12626 * oid  the oid in byte representation
     12627 * sz   size of oid buffer
     12628 * idx  index of array to place oid
     12629 *
     12630 * returns 0 on success
     12631 */
     12632int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
     12633        void* heap)
     12634{
     12635    byte oid[MAX_OID_SZ];
     12636    word32 oidSz = MAX_OID_SZ;
     12637
     12638    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
     12639        WOLFSSL_MSG("Either idx or sz was too large");
     12640        return BAD_FUNC_ARG;
     12641    }
     12642
     12643    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
     12644        return BUFFER_E;
     12645    }
     12646
     12647    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
     12648    cert->extKeyUsageOIDSz[idx] = oidSz;
     12649    cert->extKeyUsage |= EXTKEYUSE_USER;
     12650
     12651    return 0;
     12652}
     12653#endif /* WOLFSSL_EKU_OID */
    964912654#endif /* WOLFSSL_CERT_EXT */
    965012655
     
    966612671
    966712672#ifdef WOLFSSL_SMALL_STACK
    9668     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12673    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
    966912674                                                       DYNAMIC_TYPE_TMP_BUFFER);
    967012675    if (decoded == NULL)
     
    967212677#endif
    967312678
    9674     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12679    InitDecodedCert(decoded, der, derSz, NULL);
    967512680    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    967612681
     
    974012745    FreeDecodedCert(decoded);
    974112746#ifdef WOLFSSL_SMALL_STACK
    9742     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12747    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    974312748#endif
    974412749
     
    976212767
    976312768#ifdef WOLFSSL_SMALL_STACK
    9764     decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12769    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
    976512770                                                       DYNAMIC_TYPE_TMP_BUFFER);
    976612771    if (decoded == NULL)
     
    976812773#endif
    976912774
    9770     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12775    InitDecodedCert(decoded, der, derSz, NULL);
    977112776    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    977212777
     
    979412799
    979512800#ifdef WOLFSSL_SMALL_STACK
    9796     XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12801    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
    979712802#endif
    979812803
     
    982212827#endif
    982312828
    9824     InitDecodedCert(decoded, (byte*)der, derSz, NULL);
     12829    InitDecodedCert(decoded, der, derSz, NULL);
    982512830    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
    982612831
     
    983312838                                                         : CTC_NAME_SIZE - 1;
    983412839            XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
    9835             cn->commonName[sz] = 0;
     12840            cn->commonName[sz] = '\0';
    983612841            cn->commonNameEnc = decoded->subjectCNEnc;
    983712842        }
     
    984012845                                                        : CTC_NAME_SIZE - 1;
    984112846            XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
    9842             cn->country[sz] = 0;
     12847            cn->country[sz] = '\0';
    984312848            cn->countryEnc = decoded->subjectCEnc;
    984412849        }
     
    984712852                                                         : CTC_NAME_SIZE - 1;
    984812853            XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
    9849             cn->state[sz] = 0;
     12854            cn->state[sz] = '\0';
    985012855            cn->stateEnc = decoded->subjectSTEnc;
    985112856        }
     
    985412859                                                        : CTC_NAME_SIZE - 1;
    985512860            XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
    9856             cn->locality[sz] = 0;
     12861            cn->locality[sz] = '\0';
    985712862            cn->localityEnc = decoded->subjectLEnc;
    985812863        }
     
    986112866                                                        : CTC_NAME_SIZE - 1;
    986212867            XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
    9863             cn->org[sz] = 0;
     12868            cn->org[sz] = '\0';
    986412869            cn->orgEnc = decoded->subjectOEnc;
    986512870        }
     
    986812873                                                         : CTC_NAME_SIZE - 1;
    986912874            XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
    9870             cn->unit[sz] = 0;
     12875            cn->unit[sz] = '\0';
    987112876            cn->unitEnc = decoded->subjectOUEnc;
    987212877        }
     
    987512880                                                         : CTC_NAME_SIZE - 1;
    987612881            XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
    9877             cn->sur[sz] = 0;
     12882            cn->sur[sz] = '\0';
    987812883            cn->surEnc = decoded->subjectSNEnc;
    987912884        }
     12885        if (decoded->subjectSND) {
     12886            sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
     12887                                                         : CTC_NAME_SIZE - 1;
     12888            XSTRNCPY(cn->serialDev, decoded->subjectSND, CTC_NAME_SIZE);
     12889            cn->serialDev[sz] = '\0';
     12890            cn->serialDevEnc = decoded->subjectSNDEnc;
     12891        }
     12892    #ifdef WOLFSSL_CERT_EXT
     12893        if (decoded->subjectBC) {
     12894            sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
     12895                                                         : CTC_NAME_SIZE - 1;
     12896            XSTRNCPY(cn->busCat, decoded->subjectBC, CTC_NAME_SIZE);
     12897            cn->busCat[sz] = '\0';
     12898            cn->busCatEnc = decoded->subjectBCEnc;
     12899        }
     12900        if (decoded->subjectJC) {
     12901            sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
     12902                                                         : CTC_NAME_SIZE - 1;
     12903            XSTRNCPY(cn->joiC, decoded->subjectJC, CTC_NAME_SIZE);
     12904            cn->joiC[sz] = '\0';
     12905            cn->joiCEnc = decoded->subjectJCEnc;
     12906        }
     12907        if (decoded->subjectJS) {
     12908            sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
     12909                                                         : CTC_NAME_SIZE - 1;
     12910            XSTRNCPY(cn->joiSt, decoded->subjectJS, CTC_NAME_SIZE);
     12911            cn->joiSt[sz] = '\0';
     12912            cn->joiStEnc = decoded->subjectJSEnc;
     12913        }
     12914    #endif
    988012915        if (decoded->subjectEmail) {
    988112916            sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
    988212917               ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
    988312918            XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
    9884             cn->email[sz] = 0;
     12919            cn->email[sz] = '\0';
    988512920        }
    988612921    }
     
    989512930}
    989612931
     12932#ifdef WOLFSSL_CERT_EXT
     12933/* Set raw subject from der buffer, return 0 on success */
     12934static int SetSubjectRawFromCert(byte* sbjRaw, const byte* der, int derSz)
     12935{
     12936    int ret;
     12937#ifdef WOLFSSL_SMALL_STACK
     12938    DecodedCert* decoded;
     12939#else
     12940    DecodedCert decoded[1];
     12941#endif
     12942
     12943    if ((derSz < 0) || (sbjRaw == NULL)) {
     12944        return BAD_FUNC_ARG;
     12945    }
     12946
     12947#ifdef WOLFSSL_SMALL_STACK
     12948    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     12949                                                       DYNAMIC_TYPE_TMP_BUFFER);
     12950    if (decoded == NULL) {
     12951        return MEMORY_E;
     12952    }
     12953#endif
     12954
     12955    InitDecodedCert(decoded, der, derSz, NULL);
     12956    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
     12957
     12958    if (ret < 0) {
     12959        WOLFSSL_MSG("ParseCertRelative error");
     12960    }
     12961#ifndef IGNORE_NAME_CONSTRAINT
     12962    else {
     12963        if ((decoded->subjectRaw) &&
     12964            (decoded->subjectRawLen <= (int)sizeof(CertName))) {
     12965            XMEMCPY(sbjRaw, decoded->subjectRaw, decoded->subjectRawLen);
     12966        }
     12967        }
     12968#else
     12969    else {
     12970        /* Fields are not accessible */
     12971        ret = -1;
     12972        WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw subject");
     12973    }
     12974#endif
     12975
     12976    FreeDecodedCert(decoded);
     12977
     12978#ifdef WOLFSSL_SMALL_STACK
     12979    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     12980#endif
     12981
     12982    return ret < 0 ? ret : 0;
     12983}
     12984
     12985/* Set raw issuer from der buffer, return 0 on success */
     12986static int SetIssuerRawFromCert(byte* issuerRaw, const byte* der, int derSz)
     12987{
     12988    int ret;
     12989#ifdef WOLFSSL_SMALL_STACK
     12990    DecodedCert* decoded;
     12991#else
     12992    DecodedCert decoded[1];
     12993#endif
     12994
     12995    if ((derSz < 0) || (issuerRaw == NULL)) {
     12996        return BAD_FUNC_ARG;
     12997    }
     12998
     12999#ifdef WOLFSSL_SMALL_STACK
     13000    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
     13001                                                       DYNAMIC_TYPE_TMP_BUFFER);
     13002    if (decoded == NULL) {
     13003        return MEMORY_E;
     13004    }
     13005#endif
     13006
     13007    InitDecodedCert(decoded, der, derSz, NULL);
     13008    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
     13009
     13010    if (ret < 0) {
     13011        WOLFSSL_MSG("ParseCertRelative error");
     13012    }
     13013#ifndef IGNORE_NAME_CONSTRAINT
     13014    else {
     13015        if ((decoded->issuerRaw) &&
     13016            (decoded->issuerRawLen <= (int)sizeof(CertName))) {
     13017            XMEMCPY(issuerRaw, decoded->issuerRaw, decoded->issuerRawLen);
     13018        }
     13019    }
     13020#else
     13021    else {
     13022        /* Fields are not accessible */
     13023        ret = -1;
     13024        WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw issuer");
     13025    }
     13026#endif
     13027
     13028    FreeDecodedCert(decoded);
     13029
     13030#ifdef WOLFSSL_SMALL_STACK
     13031    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13032#endif
     13033
     13034    return ret < 0 ? ret : 0;
     13035}
     13036#endif /* WOLFSSL_CERT_EXT */
    989713037
    989813038#ifndef NO_FILESYSTEM
     
    990313043    int         ret;
    990413044    int         derSz;
    9905     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9906 
     13045    byte*       der;
     13046
     13047    if (cert == NULL) {
     13048        return BAD_FUNC_ARG;
     13049    }
     13050
     13051    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    990713052    if (der == NULL) {
    990813053        WOLFSSL_MSG("wc_SetIssuer OOF Problem");
    990913054        return MEMORY_E;
    991013055    }
    9911     derSz = wolfSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF);
     13056    derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);
    991213057    cert->selfSigned = 0;
    991313058    ret = SetNameFromCert(&cert->issuer, der, derSz);
     
    992313068    int         ret;
    992413069    int         derSz;
    9925     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9926 
     13070    byte*       der;
     13071
     13072    if (cert == NULL) {
     13073        return BAD_FUNC_ARG;
     13074    }
     13075
     13076    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    992713077    if (der == NULL) {
    992813078        WOLFSSL_MSG("wc_SetSubject OOF Problem");
    992913079        return MEMORY_E;
    993013080    }
    9931     derSz = wolfSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF);
     13081
     13082    derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);
    993213083    ret = SetNameFromCert(&cert->subject, der, derSz);
    993313084    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
     
    993613087}
    993713088
    9938 
    993913089#ifdef WOLFSSL_ALT_NAMES
    994013090
    9941 /* Set atl names from file in PEM */
     13091/* Set alt names from file in PEM */
    994213092int wc_SetAltNames(Cert* cert, const char* file)
    994313093{
    994413094    int         ret;
    994513095    int         derSz;
    9946     byte*       der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    9947 
     13096    byte*       der;
     13097
     13098    if (cert == NULL) {
     13099        return BAD_FUNC_ARG;
     13100    }
     13101
     13102    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
    994813103    if (der == NULL) {
    994913104        WOLFSSL_MSG("wc_SetAltNames OOF Problem");
    995013105        return MEMORY_E;
    995113106    }
    9952     derSz = wolfSSL_PemCertToDer(file, der, EIGHTK_BUF);
     13107    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
    995313108    ret = SetAltNamesFromCert(cert, der, derSz);
    995413109    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
     
    995913114#endif /* WOLFSSL_ALT_NAMES */
    996013115
    9961 #endif /* NO_FILESYSTEM */
     13116#endif /* !NO_FILESYSTEM */
    996213117
    996313118/* Set cert issuer from DER buffer */
    996413119int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
    996513120{
     13121    if (cert == NULL) {
     13122        return BAD_FUNC_ARG;
     13123    }
     13124
    996613125    cert->selfSigned = 0;
    996713126    return SetNameFromCert(&cert->issuer, der, derSz);
    996813127}
    996913128
    9970 
    997113129/* Set cert subject from DER buffer */
    997213130int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
    997313131{
     13132    if (cert == NULL) {
     13133        return BAD_FUNC_ARG;
     13134    }
     13135
    997413136    return SetNameFromCert(&cert->subject, der, derSz);
    997513137}
    9976 
     13138#ifdef WOLFSSL_CERT_EXT
     13139/* Set cert raw subject from DER buffer */
     13140int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
     13141{
     13142    int ret;
     13143
     13144    if (cert == NULL) {
     13145        ret = BAD_FUNC_ARG;
     13146    }
     13147    else {
     13148        ret = SetSubjectRawFromCert(cert->sbjRaw, der, derSz);
     13149    }
     13150    return ret;
     13151}
     13152
     13153/* Set cert raw issuer from DER buffer */
     13154int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
     13155{
     13156    int ret;
     13157
     13158    if (cert == NULL) {
     13159        ret = BAD_FUNC_ARG;
     13160    }
     13161    else {
     13162        ret = SetIssuerRawFromCert(cert->issRaw, der, derSz);
     13163    }
     13164    return ret;
     13165}
     13166#endif
    997713167
    997813168#ifdef WOLFSSL_ALT_NAMES
     
    1008813278        return ASN_PARSE_E;
    1008913279
     13280    if (*inOutIdx >= inSz)
     13281        return ASN_PARSE_E;
     13282
    1009013283    b = input[*inOutIdx];
    1009113284    *inOutIdx += 1;
     
    1010213295
    1010313296#ifdef WOLFSSL_SMALL_STACK
    10104     priv = (byte*)XMALLOC(ECC_MAXSIZE+1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13297    priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1010513298    if (priv == NULL)
    1010613299        return MEMORY_E;
    1010713300
    10108     pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13301    pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1010913302    if (pub == NULL) {
    10110         XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13303        XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1011113304        return MEMORY_E;
    1011213305    }
     
    1017513368
    1017613369#ifdef WOLFSSL_SMALL_STACK
    10177     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    10178     XFREE(pub,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
     13370    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13371    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
    1017913372#endif
    1018013373
     
    1018213375}
    1018313376
     13377
     13378#ifdef WOLFSSL_CUSTOM_CURVES
     13379static void ByteToHex(byte n, char* str)
     13380{
     13381    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
     13382                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
     13383
     13384    str[0] = hexChar[n >> 4];
     13385    str[1] = hexChar[n & 0xf];
     13386}
     13387
     13388/* returns 0 on success */
     13389static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
     13390                          word32 inSz, void* heap, int heapType)
     13391{
     13392    int len;
     13393    int i;
     13394    char* str;
     13395
     13396    if (*inOutIdx >= inSz) {
     13397        return BUFFER_E;
     13398    }
     13399
     13400    if (input[*inOutIdx] == ASN_INTEGER) {
     13401        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
     13402            return ASN_PARSE_E;
     13403    }
     13404    else {
     13405        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
     13406            return ASN_PARSE_E;
     13407    }
     13408
     13409    str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
     13410    for (i=0; i<len; i++)
     13411        ByteToHex(input[*inOutIdx + i], str + i*2);
     13412    str[len*2] = '\0';
     13413
     13414    *inOutIdx += len;
     13415    *out = str;
     13416
     13417    return 0;
     13418}
     13419#endif /* WOLFSSL_CUSTOM_CURVES */
    1018413420
    1018513421int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
     
    1018813424    int    length;
    1018913425    int    ret;
    10190 #ifdef ECC_CHECK_PUBLIC_KEY_OID
     13426    int    curve_id = ECC_CURVE_DEF;
    1019113427    word32 oidSum;
    10192 #endif
    1019313428
    1019413429    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
     
    1020513440        return ret;
    1020613441
     13442    if (*inOutIdx >= inSz) {
     13443        return BUFFER_E;
     13444    }
     13445
     13446    if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
     13447#ifdef WOLFSSL_CUSTOM_CURVES
     13448        ecc_set_type* curve;
     13449        int len;
     13450        char* point;
     13451
     13452        ret = 0;
     13453
     13454        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
     13455                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13456        if (curve == NULL)
     13457            ret = MEMORY_E;
     13458
     13459        if (ret == 0) {
     13460            XMEMSET(curve, 0, sizeof(*curve));
     13461            curve->name = "Custom";
     13462            curve->id = ECC_CURVE_CUSTOM;
     13463
     13464            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13465                ret = ASN_PARSE_E;
     13466        }
     13467
     13468        if (ret == 0) {
     13469            GetInteger7Bit(input, inOutIdx, inSz);
     13470            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13471                ret = ASN_PARSE_E;
     13472        }
     13473        if (ret == 0) {
     13474            SkipObjectId(input, inOutIdx, inSz);
     13475            ret = ASNToHexString(input, inOutIdx, (char**)&curve->prime, inSz,
     13476                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13477        }
     13478        if (ret == 0) {
     13479            curve->size = (int)XSTRLEN(curve->prime) / 2;
     13480
     13481            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
     13482                ret = ASN_PARSE_E;
     13483        }
     13484        if (ret == 0) {
     13485            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Af, inSz,
     13486                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13487        }
     13488        if (ret == 0) {
     13489            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Bf, inSz,
     13490                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13491        }
     13492        if (ret == 0) {
     13493            if (*inOutIdx < inSz && input[*inOutIdx] == ASN_BIT_STRING) {
     13494                len = 0;
     13495                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
     13496                *inOutIdx += len;
     13497            }
     13498        }
     13499        if (ret == 0) {
     13500            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
     13501                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13502
     13503            /* sanity check that point buffer is not smaller than the expected
     13504             * size to hold ( 0 4 || Gx || Gy )
     13505             * where Gx and Gy are each the size of curve->size * 2 */
     13506            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
     13507                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13508                ret = BUFFER_E;
     13509            }
     13510        }
     13511        if (ret == 0) {
     13512            curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
     13513                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13514            curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
     13515                                                       DYNAMIC_TYPE_ECC_BUFFER);
     13516            if (curve->Gx == NULL || curve->Gy == NULL) {
     13517                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13518                ret = MEMORY_E;
     13519            }
     13520        }
     13521        if (ret == 0) {
     13522            XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
     13523            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
     13524                                                               curve->size * 2);
     13525            ((char*)curve->Gx)[curve->size * 2] = '\0';
     13526            ((char*)curve->Gy)[curve->size * 2] = '\0';
     13527            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13528            ret = ASNToHexString(input, inOutIdx, (char**)&curve->order, inSz,
     13529                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
     13530        }
     13531        if (ret == 0) {
     13532            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
     13533
     13534            curve->oid = NULL;
     13535            curve->oidSz = 0;
     13536            curve->oidSum = 0;
     13537
     13538            if (wc_ecc_set_custom_curve(key, curve) < 0) {
     13539                ret = ASN_PARSE_E;
     13540            }
     13541            key->deallocSet = 1;
     13542            curve = NULL;
     13543        }
     13544        if (curve != NULL)
     13545            wc_ecc_free_curve(curve, key->heap);
     13546
     13547        if (ret < 0)
     13548            return ret;
     13549#else
     13550        return ASN_PARSE_E;
     13551#endif /* WOLFSSL_CUSTOM_CURVES */
     13552    }
     13553    else {
    1020713554    /* ecc params information */
    10208 #ifdef ECC_CHECK_PUBLIC_KEY_OID
    1020913555    ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
    1021013556    if (ret != 0)
    1021113557        return ret;
    10212     if (CheckCurve(oidSum) < 0)
     13558
     13559        /* get curve id */
     13560        curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
     13561        if (curve_id < 0)
    1021313562        return ECC_CURVE_OID_E;
    10214 #else
    10215     ret = SkipObjectId(input, inOutIdx, inSz);
     13563    }
     13564
     13565    /* key header */
     13566    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
    1021613567    if (ret != 0)
    1021713568        return ret;
    10218 #endif
    10219 
    10220     /* key header */
    10221     ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
    10222     if (ret != 0)
    10223         return ret;
    1022413569
    1022513570    /* This is the raw point data compressed or uncompressed. */
    10226     if (wc_ecc_import_x963(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
     13571    if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key,
     13572                                                            curve_id) != 0) {
    1022713573        return ASN_ECC_KEY_E;
     13574}
     13575
     13576    *inOutIdx += length;
    1022813577
    1022913578    return 0;
    1023013579}
    1023113580
    10232 
    10233 #ifdef WOLFSSL_KEY_GEN
    10234 
     13581#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    1023513582/* build DER formatted ECC key, include optional public key if requested,
    1023613583 * return length on success, negative on error */
     
    1035013697}
    1035113698
    10352 
    1035313699/* Write a Private ecc key, including public to DER format,
    1035413700 * length on success else < 0 */
     
    1036613712}
    1036713713
    10368 #endif /* WOLFSSL_KEY_GEN */
    10369 
     13714/* Write only private ecc key to unencrypted PKCS#8 format.
     13715 *
     13716 * If output is NULL, places required PKCS#8 buffer size in outLen and
     13717 * returns LENGTH_ONLY_E.
     13718 *
     13719 * return length on success else < 0 */
     13720int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
     13721{
     13722    int ret, tmpDerSz;
     13723    int algoID = 0;
     13724    word32 oidSz = 0;
     13725    word32 pkcs8Sz = 0;
     13726    const byte* curveOID = NULL;
     13727    byte* tmpDer = NULL;
     13728
     13729    if (key == NULL || outLen == NULL)
     13730        return BAD_FUNC_ARG;
     13731
     13732    /* set algoID, get curve OID */
     13733    algoID = ECDSAk;
     13734    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
     13735    if (ret < 0)
     13736        return ret;
     13737
     13738    /* temp buffer for plain DER key */
     13739    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13740    if (tmpDer == NULL)
     13741        return MEMORY_E;
     13742
     13743    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
     13744
     13745    tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
     13746    if (tmpDerSz < 0) {
     13747        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13748        return tmpDerSz;
     13749    }
     13750
     13751    /* get pkcs8 expected output size */
     13752    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
     13753                            curveOID, oidSz);
     13754    if (ret != LENGTH_ONLY_E) {
     13755        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13756        return ret;
     13757    }
     13758
     13759    if (output == NULL) {
     13760        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13761        *outLen = pkcs8Sz;
     13762        return LENGTH_ONLY_E;
     13763
     13764    } else if (*outLen < pkcs8Sz) {
     13765        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13766        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
     13767        return BUFFER_E;
     13768    }
     13769
     13770    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
     13771                            algoID, curveOID, oidSz);
     13772    if (ret < 0) {
     13773        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13774        return ret;
     13775    }
     13776
     13777    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     13778
     13779    *outLen = ret;
     13780    return ret;
     13781}
     13782
     13783#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
    1037013784#endif  /* HAVE_ECC */
    1037113785
     
    1038413798        return BAD_FUNC_ARG;
    1038513799
    10386     if (GetSequence(input, inOutIdx, &length, inSz) < 0)
    10387         return ASN_PARSE_E;
     13800    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
    1038813801    endKeyIdx = *inOutIdx + length;
    1038913802
     
    1040513818    if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
    1040613819        return ASN_PARSE_E;
     13820
     13821        priv = input + *inOutIdx;
     13822        *inOutIdx += privSz;
     13823    }
     13824    else {
     13825        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
     13826            return ASN_PARSE_E;
     13827
    1040713828    priv = input + *inOutIdx;
    1040813829    *inOutIdx += privSz;
     13830        endKeyIdx = *inOutIdx;
     13831    }
    1040913832
    1041013833    if (endKeyIdx == (int)*inOutIdx) {
     
    1043513858    int    length;
    1043613859    int    ret;
    10437 #ifdef ECC_CHECK_PUBLIC_KEY_OID
    10438     word32 oidSum;
    10439 #endif
    1044013860
    1044113861    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
     
    1054813968                        byte* format, int maxIdx)
    1054913969{
    10550     int    length;
     13970    int    ret, length;
     13971    const byte *datePtr = NULL;
    1055113972
    1055213973    WOLFSSL_ENTER("GetBasicDate");
    1055313974
    10554     *format = source[*idx];
    10555     *idx += 1;
    10556     if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
    10557         return ASN_TIME_E;
    10558 
    10559     if (GetLength(source, idx, &length, maxIdx) < 0)
    10560         return ASN_PARSE_E;
    10561 
    10562     if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
    10563         return ASN_DATE_SZ_E;
    10564 
    10565     XMEMCPY(date, &source[*idx], length);
    10566     *idx += length;
     13975    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
     13976    if (ret < 0)
     13977        return ret;
     13978
     13979    XMEMCPY(date, datePtr, length);
    1056713980
    1056813981    return 0;
    1056913982}
    1057013983
    10571 #endif
     13984#endif /* HAVE_OCSP || HAVE_CRL */
    1057213985
    1057313986
     
    1066714080    }
    1066814081
    10669 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     14082#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    1067014083    cs->thisDateAsn = source + idx;
    1067114084#endif
     
    1068814101        if (GetLength(source, &idx, &length, size) < 0)
    1068914102            return ASN_PARSE_E;
    10690 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     14103#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
    1069114104        cs->nextDateAsn = source + idx;
    1069214105#endif
     
    1093714350            else {
    1093814351                WOLFSSL_MSG("\tOCSP Responder key usage check failed");
    10939 
     14352    #ifdef OPENSSL_EXTRA
     14353                resp->verifyError = OCSP_BAD_ISSUER;
     14354    #else
    1094014355                FreeDecodedCert(&cert);
    1094114356                return BAD_OCSP_RESPONDER;
     14357    #endif
    1094214358            }
    1094314359        }
     
    1120714623
    1120814624        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
    11209             req->url = (byte*)XMALLOC(cert->extAuthInfoSz, req->heap,
     14625            req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,
    1121014626                                                     DYNAMIC_TYPE_OCSP_REQUEST);
    1121114627            if (req->url == NULL) {
     
    1121614632            XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
    1121714633            req->urlSz = cert->extAuthInfoSz;
     14634            req->url[req->urlSz] = 0;
    1121814635        }
    1121914636    }
     
    1124914666        if (req->serial)
    1125014667            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
     14668        req->serial = NULL;
    1125114669
    1125214670        if (req->url)
    1125314671            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
     14672        req->url = NULL;
    1125414673    }
    1125514674}
     
    1132314742}
    1132414743
    11325 #endif
     14744#endif /* HAVE_OCSP */
    1132614745
    1132714746
     
    1135314772        return ASN_PARSE_E;
    1135414773
    11355 #ifdef NO_SHA
    11356     ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
    11357 #else
    11358     ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
    11359 #endif
     14774    ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
    1136014775
    1136114776    *idx += length;
     
    1140414819                      int maxIdx)
    1140514820{
    11406     int    len;
     14821    int    ret, len;
    1140714822    word32 end;
    1140814823    byte   b;
     
    1143414849    dcrl->totalCerts++;
    1143514850
    11436 
    1143714851    /* get date */
    11438     b = buff[*idx];
    11439     *idx += 1;
    11440 
    11441     if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) {
     14852    ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
     14853    if (ret < 0) {
    1144214854        WOLFSSL_MSG("Expecting Date");
    11443         return ASN_PARSE_E;
    11444     }
    11445 
    11446     if (GetLength(buff, idx, &len, maxIdx) < 0)
    11447         return ASN_PARSE_E;
    11448 
    11449     /* skip for now */
    11450     *idx += len;
     14855        return ret;
     14856    }
    1145114857
    1145214858    if (*idx != end)  /* skip extensions */
     
    1161015016#endif /* HAVE_CRL */
    1161115017
     15018
     15019
     15020#ifdef WOLFSSL_CERT_PIV
     15021
     15022int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
     15023{
     15024    int length = 0;
     15025    word32 idx = 0;
     15026
     15027    WOLFSSL_ENTER("wc_ParseCertPIV");
     15028
     15029    if (piv == NULL || buf == NULL || totalSz == 0)
     15030        return BAD_FUNC_ARG;
     15031
     15032    XMEMSET(piv, 0, sizeof(wc_CertPIV));
     15033
     15034    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
     15035    /* Certificate (0A 82 05FA) */
     15036    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
     15037        /* Identiv Type PIV card */
     15038        piv->isIdentiv = 1;
     15039
     15040        piv->cert =   &buf[idx];
     15041        piv->certSz = length;
     15042        idx += length;
     15043
     15044        /* Nonce (0B 14) */
     15045        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
     15046            piv->nonce =   &buf[idx];
     15047            piv->nonceSz = length;
     15048            idx += length;
     15049        }
     15050
     15051        /* Signed Nonce (0C 82 0100) */
     15052        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
     15053            piv->signedNonce =   &buf[idx];
     15054            piv->signedNonceSz = length;
     15055            idx += length;
     15056        }
     15057
     15058        idx = 0;
     15059        buf = piv->cert;
     15060        totalSz = piv->certSz;
     15061    }
     15062
     15063    /* Certificate Buffer Total Size (53 82 05F6) */
     15064    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
     15065                                                   &length, totalSz) < 0) {
     15066        return ASN_PARSE_E;
     15067    }
     15068    /* PIV Certificate (70 82 05ED) */
     15069    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
     15070                                                         totalSz) < 0) {
     15071        return ASN_PARSE_E;
     15072    }
     15073
     15074    /* Capture certificate buffer pointer and length */
     15075    piv->cert =   &buf[idx];
     15076    piv->certSz = length;
     15077    idx += length;
     15078
     15079    /* PIV Certificate Info (71 01 00) */
     15080    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
     15081                                                        totalSz) >= 0) {
     15082        if (length >= 1) {
     15083            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
     15084            piv->isX509 =      (buf[idx] & ASN_PIV_CERT_INFO_ISX509);
     15085        }
     15086        idx += length;
     15087    }
     15088
     15089    /* PIV Error Detection (FE 00) */
     15090    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
     15091                                                        totalSz) >= 0) {
     15092        piv->certErrDet =   &buf[idx];
     15093        piv->certErrDetSz = length;
     15094        idx += length;
     15095    }
     15096
     15097    return 0;
     15098}
     15099
     15100#endif /* WOLFSSL_CERT_PIV */
     15101
     15102
    1161215103#undef ERROR_OUT
    1161315104
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/blake2b.c

    r352 r372  
    7171
    7272
    73 static INLINE int blake2b_set_lastnode( blake2b_state *S )
     73static WC_INLINE int blake2b_set_lastnode( blake2b_state *S )
    7474{
    7575  S->f[1] = ~0ULL;
     
    7878
    7979/* Some helper functions, not necessarily useful */
    80 static INLINE int blake2b_set_lastblock( blake2b_state *S )
     80static WC_INLINE int blake2b_set_lastblock( blake2b_state *S )
    8181{
    8282  if( S->last_node ) blake2b_set_lastnode( S );
     
    8686}
    8787
    88 static INLINE int blake2b_increment_counter( blake2b_state *S, const word64
     88static WC_INLINE int blake2b_increment_counter( blake2b_state *S, const word64
    8989                                             inc )
    9090{
     
    9494}
    9595
    96 static INLINE int blake2b_init0( blake2b_state *S )
     96static WC_INLINE int blake2b_init0( blake2b_state *S )
    9797{
    9898  int i;
     
    423423int wc_InitBlake2b(Blake2b* b2b, word32 digestSz)
    424424{
     425    if (b2b == NULL){
     426        return -1;
     427    }
    425428    b2b->digestSz = digestSz;
    426429
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/camellia.c

    r352 r372  
    15991599int wc_CamelliaCbcEncrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
    16001600{
     1601    word32 blocks;
    16011602    if (cam == NULL || out == NULL || in == NULL) {
    16021603        return BAD_FUNC_ARG;
    16031604    }
    1604     word32 blocks = sz / CAMELLIA_BLOCK_SIZE;
     1605    blocks = sz / CAMELLIA_BLOCK_SIZE;
    16051606
    16061607    while (blocks--) {
     
    16201621int wc_CamelliaCbcDecrypt(Camellia* cam, byte* out, const byte* in, word32 sz)
    16211622{
     1623    word32 blocks;
    16221624    if (cam == NULL || out == NULL || in == NULL) {
    16231625        return BAD_FUNC_ARG;
    16241626    }
    1625     word32 blocks = sz / CAMELLIA_BLOCK_SIZE;
     1627    blocks = sz / CAMELLIA_BLOCK_SIZE;
    16261628
    16271629    while (blocks--) {
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/coding.c

    r352 r372  
    3737    BAD         = 0xFF,  /* invalid encoding */
    3838    PAD         = '=',
    39     PEM_LINE_SZ = 64
     39    PEM_LINE_SZ = 64,
     40    BASE64_MIN  = 0x2B,
     41    BASE16_MIN  = 0x30,
    4042};
    4143
     
    6062    word32 j = 0;
    6163    word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );
    62     const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1;
     64    const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1;
    6365
    6466    plainSz = (plainSz * 3 + 3) / 4;
     
    8284            pad4 = 1;
    8385
    84         if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) {
     86        if (e1 < BASE64_MIN || e2 < BASE64_MIN || e3 < BASE64_MIN || e4 < BASE64_MIN) {
    8587            WOLFSSL_MSG("Bad Base64 Decode data, too small");
    8688            return ASN_INPUT_E;
     
    9294        }
    9395
    94         e1 = base64Decode[e1 - 0x2B];
    95         e2 = base64Decode[e2 - 0x2B];
    96         e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B];
    97         e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B];
     96        e1 = base64Decode[e1 - BASE64_MIN];
     97        e2 = base64Decode[e2 - BASE64_MIN];
     98        e3 = (e3 == PAD) ? 0 : base64Decode[e3 - BASE64_MIN];
     99        e4 = (e4 == PAD) ? 0 : base64Decode[e4 - BASE64_MIN];
    98100
    99101        b1 = (byte)((e1 << 2) | (e2 >> 4));
     
    345347}
    346348
    347 #endif  /* defined(WOLFSSL_BASE64_ENCODE) */
    348 
    349 
    350 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) \
    351                            || defined(HAVE_ECC_CDH)
     349#endif /* WOLFSSL_BASE64_ENCODE */
     350
     351
     352#ifdef WOLFSSL_BASE16
    352353
    353354static
     
    371372
    372373    if (inLen == 1 && *outLen && in) {
    373         byte b = in[inIdx++] - 0x30;  /* 0 starts at 0x30 */
     374        byte b = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */
    374375
    375376        /* sanity check */
     
    395396
    396397    while (inLen) {
    397         byte b  = in[inIdx++] - 0x30;  /* 0 starts at 0x30 */
    398         byte b2 = in[inIdx++] - 0x30;
     398        byte b  = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */
     399        byte b2 = in[inIdx++] - BASE16_MIN;
    399400
    400401        /* sanity checks */
     
    455456}
    456457
    457 #endif /* (OPENSSL_EXTRA) || (HAVE_WEBSERVER) || (HAVE_FIPS) */
    458 
    459 #endif /* NO_CODING */
     458#endif /* WOLFSSL_BASE16 */
     459
     460#endif /* !NO_CODING */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/des3.c

    r352 r372  
    3232#ifndef NO_DES3
    3333
     34#if defined(HAVE_FIPS) && \
     35        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     36
     37    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     38    #define FIPS_NO_WRAPPERS
     39
     40    #ifdef USE_WINDOWS_API
     41        #pragma code_seg(".fipsA$i")
     42        #pragma const_seg(".fipsB$i")
     43    #endif
     44#endif
     45
    3446#include <wolfssl/wolfcrypt/des3.h>
    3547
    3648/* fips wrapper calls, user can call direct */
    37 #ifdef HAVE_FIPS
     49#if defined(HAVE_FIPS) && \
     50    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     51
    3852    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
    3953    {
     
    108122    }
    109123
    110 #else /* build without fips */
     124#else /* else build without fips, or for FIPS v2 */
    111125
    112126
     
    12871301    };
    12881302
    1289     static INLINE void IPERM(word32* left, word32* right)
     1303    static WC_INLINE void IPERM(word32* left, word32* right)
    12901304    {
    12911305        word32 work;
     
    13131327    }
    13141328
    1315     static INLINE void FPERM(word32* left, word32* right)
     1329    static WC_INLINE void FPERM(word32* left, word32* right)
    13161330    {
    13171331        word32 work;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/dh.c

    r352 r372  
    2929#ifndef NO_DH
    3030
     31#if defined(HAVE_FIPS) && \
     32        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     33
     34    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     35    #define FIPS_NO_WRAPPERS
     36
     37    #ifdef USE_WINDOWS_API
     38        #pragma code_seg(".fipsA$m")
     39        #pragma const_seg(".fipsB$m")
     40    #endif
     41#endif
     42
    3143#include <wolfssl/wolfcrypt/dh.h>
    3244#include <wolfssl/wolfcrypt/error-crypt.h>
     
    4355    #include <wolfcrypt/src/misc.c>
    4456#endif
     57
     58
     59/*
     60Possible DH enable options:
     61 * NO_RSA:              Overall control of DH                 default: on (not defined)
     62 * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
     63                        directly effect this file, but it does speed up DH
     64                        removing the testing. It is not recommended to
     65                        disable the prime checking.           default: off
     66
     67*/
    4568
    4669
     
    89112};
    90113static const byte dh_ffdhe2048_g[] = { 0x02 };
     114#ifdef HAVE_FFDHE_Q
     115static const byte dh_ffdhe2048_q[] = {
     116    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     117    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
     118    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
     119    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
     120    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
     121    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
     122    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
     123    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
     124    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
     125    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
     126    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
     127    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
     128    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
     129    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
     130    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
     131    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
     132    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
     133    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
     134    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
     135    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
     136    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
     137    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
     138    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
     139    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
     140    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
     141    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
     142    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
     143    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
     144    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
     145    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
     146    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B,
     147    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     148};
     149#endif /* HAVE_FFDHE_Q */
    91150
    92151const DhParams* wc_Dh_ffdhe2048_Get(void)
    93152{
    94153    static const DhParams ffdhe2048 = {
     154        #ifdef HAVE_FFDHE_Q
     155            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
     156        #endif /* HAVE_FFDHE_Q */
    95157        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
    96158        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
     
    152214};
    153215static const byte dh_ffdhe3072_g[] = { 0x02 };
     216#ifdef HAVE_FFDHE_Q
     217static const byte dh_ffdhe3072_q[] = {
     218    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     219    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
     220    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
     221    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
     222    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
     223    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
     224    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
     225    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
     226    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
     227    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
     228    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
     229    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
     230    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
     231    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
     232    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
     233    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
     234    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
     235    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
     236    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
     237    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
     238    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
     239    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
     240    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
     241    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
     242    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
     243    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
     244    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
     245    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
     246    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
     247    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
     248    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
     249    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
     250    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
     251    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
     252    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
     253    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
     254    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
     255    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
     256    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
     257    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
     258    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
     259    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
     260    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
     261    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
     262    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
     263    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
     264    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B,
     265    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     266};
     267#endif /* HAVE_FFDHE_Q */
    154268
    155269const DhParams* wc_Dh_ffdhe3072_Get(void)
    156270{
    157271    static const DhParams ffdhe3072 = {
     272        #ifdef HAVE_FFDHE_Q
     273            dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q),
     274        #endif /* HAVE_FFDHE_Q */
    158275        dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p),
    159276        dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g)
     
    231348};
    232349static const byte dh_ffdhe4096_g[] = { 0x02 };
     350#ifdef HAVE_FFDHE_Q
     351static const byte dh_ffdhe4096_q[] = {
     352    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     353    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
     354    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
     355    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
     356    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
     357    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
     358    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
     359    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
     360    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
     361    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
     362    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
     363    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
     364    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
     365    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
     366    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
     367    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
     368    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
     369    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
     370    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
     371    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
     372    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
     373    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
     374    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
     375    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
     376    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
     377    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
     378    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
     379    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
     380    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
     381    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
     382    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
     383    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
     384    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
     385    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
     386    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
     387    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
     388    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
     389    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
     390    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
     391    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
     392    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
     393    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
     394    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
     395    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
     396    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
     397    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
     398    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
     399    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
     400    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
     401    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
     402    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
     403    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
     404    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
     405    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
     406    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
     407    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
     408    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
     409    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
     410    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
     411    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
     412    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
     413    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
     414    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5,
     415    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     416};
     417#endif /* HAVE_FFDHE_Q */
    233418
    234419const DhParams* wc_Dh_ffdhe4096_Get(void)
    235420{
    236421    static const DhParams ffdhe4096 = {
     422        #ifdef HAVE_FFDHE_Q
     423            dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q),
     424        #endif /* HAVE_FFDHE_Q */
    237425        dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p),
    238426        dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g)
     
    342530};
    343531static const byte dh_ffdhe6144_g[] = { 0x02 };
     532#ifdef HAVE_FFDHE_Q
     533static const byte dh_ffdhe6144_q[] = {
     534    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     535    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
     536    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
     537    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
     538    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
     539    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
     540    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
     541    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
     542    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
     543    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
     544    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
     545    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
     546    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
     547    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
     548    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
     549    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
     550    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
     551    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
     552    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
     553    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
     554    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
     555    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
     556    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
     557    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
     558    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
     559    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
     560    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
     561    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
     562    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
     563    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
     564    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
     565    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
     566    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
     567    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
     568    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
     569    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
     570    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
     571    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
     572    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
     573    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
     574    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
     575    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
     576    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
     577    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
     578    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
     579    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
     580    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
     581    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
     582    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
     583    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
     584    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
     585    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
     586    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
     587    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
     588    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
     589    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
     590    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
     591    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
     592    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
     593    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
     594    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
     595    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
     596    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
     597    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
     598    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
     599    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
     600    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
     601    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
     602    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
     603    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
     604    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
     605    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
     606    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
     607    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
     608    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
     609    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
     610    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
     611    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
     612    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
     613    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
     614    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
     615    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
     616    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
     617    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
     618    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
     619    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
     620    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
     621    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
     622    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
     623    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
     624    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
     625    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
     626    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
     627    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
     628    0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32,
     629    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     630};
     631#endif /* HAVE_FFDHE_Q */
    344632
    345633const DhParams* wc_Dh_ffdhe6144_Get(void)
    346634{
    347635    static const DhParams ffdhe6144 = {
     636        #ifdef HAVE_FFDHE_Q
     637            dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q),
     638        #endif /* HAVE_FFDHE_Q */
    348639        dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p),
    349640        dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g)
     
    485776};
    486777static const byte dh_ffdhe8192_g[] = { 0x02 };
     778#ifdef HAVE_FFDHE_Q
     779static const byte dh_ffdhe8192_q[] = {
     780    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     781    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
     782    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
     783    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
     784    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
     785    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
     786    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
     787    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
     788    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
     789    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
     790    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
     791    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
     792    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
     793    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
     794    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
     795    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
     796    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
     797    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
     798    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
     799    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
     800    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
     801    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
     802    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
     803    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
     804    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
     805    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
     806    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
     807    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
     808    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
     809    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
     810    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
     811    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
     812    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
     813    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
     814    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
     815    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
     816    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
     817    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
     818    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
     819    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
     820    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
     821    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
     822    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
     823    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
     824    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
     825    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
     826    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
     827    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
     828    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
     829    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
     830    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
     831    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
     832    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
     833    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
     834    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
     835    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
     836    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
     837    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
     838    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
     839    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
     840    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
     841    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
     842    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
     843    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
     844    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
     845    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
     846    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
     847    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
     848    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
     849    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
     850    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
     851    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
     852    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
     853    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
     854    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
     855    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
     856    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
     857    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
     858    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
     859    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
     860    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
     861    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
     862    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
     863    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
     864    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
     865    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
     866    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
     867    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
     868    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
     869    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
     870    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
     871    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
     872    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
     873    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
     874    0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55,
     875    0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C,
     876    0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32,
     877    0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1,
     878    0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F,
     879    0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77,
     880    0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14,
     881    0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32,
     882    0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81,
     883    0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2,
     884    0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41,
     885    0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE,
     886    0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28,
     887    0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11,
     888    0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A,
     889    0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7,
     890    0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96,
     891    0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E,
     892    0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD,
     893    0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC,
     894    0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50,
     895    0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18,
     896    0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B,
     897    0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4,
     898    0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37,
     899    0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18,
     900    0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F,
     901    0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F,
     902    0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86,
     903    0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E,
     904    0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7,
     905    0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46,
     906    0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26,
     907    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     908};
     909#endif /* HAVE_FFDHE_Q */
    487910
    488911const DhParams* wc_Dh_ffdhe8192_Get(void)
    489912{
    490913    static const DhParams ffdhe8192 = {
     914        #ifdef HAVE_FFDHE_Q
     915            dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q),
     916        #endif /* HAVE_FFDHE_Q */
    491917        dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p),
    492918        dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g)
     
    505931    key->heap = heap; /* for XMALLOC/XFREE in future */
    506932
    507     if (mp_init_multi(&key->p, &key->g, NULL, NULL, NULL, NULL) != MP_OKAY)
     933    if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY)
    508934        return MEMORY_E;
    509935
     
    525951
    526952
    527 void wc_FreeDhKey(DhKey* key)
     953int wc_FreeDhKey(DhKey* key)
    528954{
    529955    if (key) {
    530956        mp_clear(&key->p);
    531957        mp_clear(&key->g);
     958        mp_clear(&key->q);
    532959
    533960    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
     
    535962    #endif
    536963    }
    537 }
    538 
    539 
     964    return 0;
     965}
     966
     967
     968#ifndef WC_NO_RNG
    540969/* if defined to not use floating point values do not compile in */
    541970#ifndef WOLFSSL_DH_CONST
     
    568997
    569998
    570 static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz)
    571 {
     999#ifndef WOLFSSL_NO_DH186
     1000/* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1.
     1001 * modLen - represents L, the size of p in bits
     1002 * divLen - represents N, the size of q in bits
     1003 * return 0 on success, -1 on error */
     1004static int CheckDhLN(int modLen, int divLen)
     1005{
     1006    int ret = -1;
     1007
     1008    switch (modLen) {
     1009        /* FA */
     1010        case 1024:
     1011            if (divLen == 160)
     1012                ret = 0;
     1013            break;
     1014        /* FB, FC */
     1015        case 2048:
     1016            if (divLen == 224 || divLen == 256)
     1017                ret = 0;
     1018            break;
     1019        default:
     1020            break;
     1021    }
     1022
     1023    return ret;
     1024}
     1025
     1026
     1027/* Create DH private key
     1028 *
     1029 * Based on NIST FIPS 186-4,
     1030 * "B.1.1 Key Pair Generation Using Extra Random Bits"
     1031 *
     1032 * dh     - pointer to initialized DhKey structure, needs to have dh->q
     1033 * rng    - pointer to initialized WC_RNG structure
     1034 * priv   - output location for generated private key
     1035 * privSz - IN/OUT, size of priv buffer, size of generated private key
     1036 *
     1037 * return 0 on success, negative on error */
     1038static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
     1039                                word32* privSz)
     1040{
     1041    byte* cBuf;
     1042    int qSz, pSz, cSz, err;
     1043#ifdef WOLFSSL_SMALL_STACK
     1044    mp_int* tmpQ = NULL;
     1045    mp_int* tmpX = NULL;
     1046#else
     1047    mp_int tmpQ[1], tmpX[1];
     1048#endif
     1049
     1050    /* Parameters validated in calling functions. */
     1051
     1052    if (mp_iszero(&key->q) == MP_YES) {
     1053        WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
     1054        return BAD_FUNC_ARG;
     1055    }
     1056
     1057    qSz = mp_unsigned_bin_size(&key->q);
     1058    pSz = mp_unsigned_bin_size(&key->p);
     1059
     1060    /* verify (L,N) pair bit lengths */
     1061    if (CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
     1062        WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
     1063        return BAD_FUNC_ARG;
     1064    }
     1065
     1066    /* generate extra 64 bits so that bias from mod function is negligible */
     1067    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
     1068    cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1069    if (cBuf == NULL) {
     1070        return MEMORY_E;
     1071    }
     1072#ifdef WOLFSSL_SMALL_STACK
     1073    tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1074    if (tmpQ == NULL) {
     1075        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1076        return MEMORY_E;
     1077    }
     1078    tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1079    if (tmpX == NULL) {
     1080        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1081        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
     1082        return MEMORY_E;
     1083    }
     1084#endif
     1085
     1086
     1087    if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))
     1088                   != MP_OKAY) {
     1089        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1090#ifdef WOLFSSL_SMALL_STACK
     1091        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
     1092        XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
     1093#endif
     1094        return err;
     1095    }
     1096
     1097    do {
     1098        /* generate N+64 bits (c) from RBG into tmpX, making sure positive.
     1099         * Hash_DRBG uses SHA-256 which matches maximum
     1100         * requested_security_strength of (L,N) */
     1101        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
     1102        if (err == MP_OKAY)
     1103            err = mp_read_unsigned_bin(tmpX, cBuf, cSz);
     1104        if (err != MP_OKAY) {
     1105            mp_clear(tmpX);
     1106            mp_clear(tmpQ);
     1107            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1108#ifdef WOLFSSL_SMALL_STACK
     1109            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
     1110            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
     1111#endif
     1112            return err;
     1113        }
     1114    } while (mp_cmp_d(tmpX, 1) != MP_GT);
     1115
     1116    ForceZero(cBuf, cSz);
     1117    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
     1118
     1119    /* tmpQ = q - 1 */
     1120    if (err == MP_OKAY)
     1121        err = mp_copy(&key->q, tmpQ);
     1122
     1123    if (err == MP_OKAY)
     1124        err = mp_sub_d(tmpQ, 1, tmpQ);
     1125
     1126    /* x = c mod (q-1), tmpX holds c */
     1127    if (err == MP_OKAY)
     1128        err = mp_mod(tmpX, tmpQ, tmpX);
     1129
     1130    /* x = c mod (q-1) + 1 */
     1131    if (err == MP_OKAY)
     1132        err = mp_add_d(tmpX, 1, tmpX);
     1133
     1134    /* copy tmpX into priv */
     1135    if (err == MP_OKAY) {
     1136        pSz = mp_unsigned_bin_size(tmpX);
     1137        if (pSz > (int)*privSz) {
     1138            WOLFSSL_MSG("DH private key output buffer too small");
     1139            err = BAD_FUNC_ARG;
     1140        } else {
     1141            *privSz = pSz;
     1142            err = mp_to_unsigned_bin(tmpX, priv);
     1143        }
     1144    }
     1145
     1146    mp_forcezero(tmpX);
     1147    mp_clear(tmpX);
     1148    mp_clear(tmpQ);
     1149#ifdef WOLFSSL_SMALL_STACK
     1150    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
     1151    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
     1152#endif
     1153
     1154    return err;
     1155}
     1156#endif /* WOLFSSL_NO_DH186 */
     1157#endif /* !WC_NO_RNG */
     1158
     1159static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
     1160                             word32* privSz)
     1161{
     1162#ifndef WC_NO_RNG
    5721163    int ret = 0;
    573     word32 sz = mp_unsigned_bin_size(&key->p);
     1164    word32 sz = 0;
     1165
     1166#ifndef WOLFSSL_NO_DH186
     1167    if (mp_iszero(&key->q) == MP_NO) {
     1168
     1169        /* q param available, use NIST FIPS 186-4, "B.1.1 Key Pair
     1170         * Generation Using Extra Random Bits" */
     1171        ret = GeneratePrivateDh186(key, rng, priv, privSz);
     1172
     1173    } else
     1174#endif
     1175    {
     1176
     1177        sz = mp_unsigned_bin_size(&key->p);
    5741178
    5751179    /* Table of predetermined values from the operation
    576        2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1
     1180           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
     1181           WOLFSSL_BIT_SIZE + 1
    5771182       Sizes in table checked against RFC 3526
    5781183     */
     
    6041209        *privSz = sz;
    6051210    }
     1211    }
    6061212
    6071213    return ret;
     1214#else
     1215    (void)key;
     1216    (void)rng;
     1217    (void)priv;
     1218    (void)privSz;
     1219    return NOT_COMPILED_IN;
     1220#endif /* WC_NO_RNG */
    6081221}
    6091222
     
    6131226{
    6141227    int ret = 0;
    615     mp_int x;
    616     mp_int y;
     1228#ifndef WOLFSSL_SP_MATH
     1229#ifdef WOLFSSL_SMALL_STACK
     1230    mp_int* x = NULL;
     1231    mp_int* y = NULL;
     1232#else
     1233    mp_int x[1];
     1234    mp_int y[1];
     1235#endif
     1236#endif
    6171237
    6181238#ifdef WOLFSSL_HAVE_SP_DH
     
    6271247#endif
    6281248
    629     if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
     1249#ifndef WOLFSSL_SP_MATH
     1250#ifdef WOLFSSL_SMALL_STACK
     1251    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1252    if (x == NULL)
     1253        return MEMORY_E;
     1254    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1255    if (y == NULL) {
     1256        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1257        return MEMORY_E;
     1258    }
     1259#endif
     1260    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
     1261    #ifdef WOLFSSL_SMALL_STACK
     1262        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1263        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1264    #endif
    6301265        return MP_INIT_E;
    631 
    632     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
     1266    }
     1267
     1268    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
    6331269        ret = MP_READ_E;
    6341270
    635     if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
     1271    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
    6361272        ret = MP_EXPTMOD_E;
    6371273
    638     if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
     1274    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
    6391275        ret = MP_TO_E;
    6401276
    6411277    if (ret == 0)
    642         *pubSz = mp_unsigned_bin_size(&y);
    643 
    644     mp_clear(&y);
    645     mp_clear(&x);
     1278        *pubSz = mp_unsigned_bin_size(y);
     1279
     1280    mp_clear(y);
     1281    mp_clear(x);
     1282#ifdef WOLFSSL_SMALL_STACK
     1283    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1284    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1285#endif
     1286#else
     1287    ret = WC_KEY_SIZE_E;
     1288#endif
    6461289
    6471290    return ret;
     
    7231366
    7241367
     1368/* Check DH Public Key for invalid numbers, optionally allowing
     1369 * the public key to be checked against the large prime (q).
     1370 * Check per process in SP 800-56Ar3, section 5.6.2.3.1.
     1371 *
     1372 * key     DH key group parameters.
     1373 * pub     Public Key.
     1374 * pubSz   Public Key size.
     1375 * prime   Large prime (q), optionally NULL to skip check
     1376 * primeSz Size of large prime
     1377 *
     1378 *  returns 0 on success or error code
     1379 */
     1380int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
     1381                        const byte* prime, word32 primeSz)
     1382{
     1383    int ret = 0;
     1384#ifdef WOLFSSL_SMALL_STACK
     1385    mp_int* y = NULL;
     1386    mp_int* p = NULL;
     1387    mp_int* q = NULL;
     1388#else
     1389    mp_int y[1];
     1390    mp_int p[1];
     1391    mp_int q[1];
     1392#endif
     1393
     1394    if (key == NULL || pub == NULL) {
     1395        return BAD_FUNC_ARG;
     1396    }
     1397
     1398#ifdef WOLFSSL_SMALL_STACK
     1399    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1400    if (y == NULL)
     1401        return MEMORY_E;
     1402    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1403    if (p == NULL) {
     1404        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1405        return MEMORY_E;
     1406    }
     1407    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1408    if (q == NULL) {
     1409        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
     1410        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1411        return MEMORY_E;
     1412    }
     1413#endif
     1414
     1415    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
     1416    #ifdef WOLFSSL_SMALL_STACK
     1417        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
     1418        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
     1419        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1420    #endif
     1421        return MP_INIT_E;
     1422    }
     1423
     1424    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
     1425        ret = MP_READ_E;
     1426    }
     1427
     1428    if (ret == 0 && prime != NULL) {
     1429        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
     1430            ret = MP_READ_E;
     1431
     1432    } else if (mp_iszero(&key->q) == MP_NO) {
     1433        /* use q available in DhKey */
     1434        if (mp_copy(&key->q, q) != MP_OKAY)
     1435            ret = MP_INIT_E;
     1436    }
     1437
     1438    /* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */
     1439    /* pub (y) should not be 0 or 1 */
     1440    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
     1441        ret = MP_CMP_E;
     1442    }
     1443
     1444    /* pub (y) shouldn't be greater than or equal to p - 1 */
     1445    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
     1446        ret = MP_INIT_E;
     1447    }
     1448    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
     1449        ret = MP_SUB_E;
     1450    }
     1451    if (ret == 0 && mp_cmp(y, p) == MP_GT) {
     1452        ret = MP_CMP_E;
     1453    }
     1454
     1455    if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
     1456
     1457        /* restore key->p into p */
     1458        if (mp_copy(&key->p, p) != MP_OKAY)
     1459            ret = MP_INIT_E;
     1460    }
     1461
     1462    if (ret == 0 && prime != NULL) {
     1463#ifdef WOLFSSL_HAVE_SP_DH
     1464#ifndef WOLFSSL_SP_NO_2048
     1465        if (mp_count_bits(&key->p) == 2048) {
     1466            ret = sp_ModExp_2048(y, q, p, y);
     1467            if (ret != 0)
     1468                ret = MP_EXPTMOD_E;
     1469        }
     1470        else
     1471#endif
     1472#ifndef WOLFSSL_SP_NO_3072
     1473        if (mp_count_bits(&key->p) == 3072) {
     1474            ret = sp_ModExp_3072(y, q, p, y);
     1475            if (ret != 0)
     1476                ret = MP_EXPTMOD_E;
     1477        }
     1478        else
     1479#endif
     1480#endif
     1481
     1482        {
     1483    /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
     1484#ifndef WOLFSSL_SP_MATH
     1485            /* calculate (y^q) mod(p), store back into y */
     1486            if (ret == 0 && mp_exptmod(y, q, p, y) != MP_OKAY)
     1487                ret = MP_EXPTMOD_E;
     1488#else
     1489            ret = WC_KEY_SIZE_E;
     1490#endif
     1491        }
     1492
     1493        /* verify above == 1 */
     1494        if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
     1495            ret = MP_CMP_E;
     1496    }
     1497
     1498    mp_clear(y);
     1499    mp_clear(p);
     1500    mp_clear(q);
     1501#ifdef WOLFSSL_SMALL_STACK
     1502    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
     1503    XFREE(p, key->heap, DYNAMIC_TYPE_DH);
     1504    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1505#endif
     1506
     1507    return ret;
     1508}
     1509
     1510
    7251511/* Check DH Public Key for invalid numbers
    7261512 *
     
    7331519int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
    7341520{
     1521    return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0);
     1522}
     1523
     1524
     1525/* Check DH Private Key for invalid numbers, optionally allowing
     1526 * the private key to be checked against the large prime (q).
     1527 * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
     1528 *
     1529 * key     DH key group parameters.
     1530 * priv    Private Key.
     1531 * privSz  Private Key size.
     1532 * prime   Large prime (q), optionally NULL to skip check
     1533 * primeSz Size of large prime
     1534 *
     1535 *  returns 0 on success or error code
     1536 */
     1537int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
     1538                         const byte* prime, word32 primeSz)
     1539{
    7351540    int ret = 0;
    736 
    737     mp_int x;
    738     mp_int y;
    739 
    740     if (key == NULL || pub == NULL) {
     1541#ifdef WOLFSSL_SMALL_STACK
     1542    mp_int* x = NULL;
     1543    mp_int* q = NULL;
     1544#else
     1545    mp_int x[1];
     1546    mp_int q[1];
     1547#endif
     1548
     1549    if (key == NULL || priv == NULL) {
    7411550        return BAD_FUNC_ARG;
    7421551    }
    7431552
    744     if (mp_init_multi(&x, &y, NULL, NULL, NULL, NULL) != MP_OKAY) {
     1553#ifdef WOLFSSL_SMALL_STACK
     1554    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1555    if (x == NULL)
     1556        return MEMORY_E;
     1557    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1558    if (q == NULL) {
     1559        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1560        return MEMORY_E;
     1561    }
     1562#endif
     1563
     1564    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
     1565    #ifdef WOLFSSL_SMALL_STACK
     1566        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
     1567        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1568    #endif
    7451569        return MP_INIT_E;
    7461570    }
    7471571
    748     if (mp_read_unsigned_bin(&x, pub, pubSz) != MP_OKAY) {
     1572    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
    7491573        ret = MP_READ_E;
    7501574    }
    7511575
    752     /* pub should not be 0 or 1 */
    753     if (ret == 0 && mp_cmp_d(&x, 2) == MP_LT) {
     1576    if (ret == 0) {
     1577        if (prime != NULL) {
     1578            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
     1579                ret = MP_READ_E;
     1580        }
     1581        else if (mp_iszero(&key->q) == MP_NO) {
     1582            /* use q available in DhKey */
     1583            if (mp_copy(&key->q, q) != MP_OKAY)
     1584                ret = MP_INIT_E;
     1585        }
     1586    }
     1587
     1588    /* priv (x) should not be 0 */
     1589    if (ret == 0) {
     1590        if (mp_cmp_d(x, 0) == MP_EQ)
    7541591        ret = MP_CMP_E;
    7551592    }
    7561593
    757     /* pub shouldn't be greater than or equal to p - 1 */
    758     if (ret == 0 && mp_copy(&key->p, &y) != MP_OKAY) {
     1594    if (ret == 0) {
     1595        if (mp_iszero(q) == MP_NO) {
     1596            /* priv (x) shouldn't be greater than q - 1 */
     1597            if (ret == 0) {
     1598                if (mp_copy(&key->q, q) != MP_OKAY)
    7591599        ret = MP_INIT_E;
    7601600    }
    761     if (ret == 0 && mp_sub_d(&y, 2, &y) != MP_OKAY) {
     1601            if (ret == 0) {
     1602                if (mp_sub_d(q, 1, q) != MP_OKAY)
    7621603        ret = MP_SUB_E;
    7631604    }
    764     if (ret == 0 && mp_cmp(&x, &y) == MP_GT) {
     1605            if (ret == 0) {
     1606                if (mp_cmp(x, q) == MP_GT)
     1607                    ret = DH_CHECK_PRIV_E;
     1608            }
     1609        }
     1610    }
     1611
     1612    mp_clear(x);
     1613    mp_clear(q);
     1614#ifdef WOLFSSL_SMALL_STACK
     1615    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
     1616    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1617#endif
     1618
     1619    return ret;
     1620}
     1621
     1622
     1623/* Check DH Private Key for invalid numbers
     1624 *
     1625 * key    DH key group parameters.
     1626 * priv   Private Key.
     1627 * privSz Private Key size.
     1628 *
     1629 *  returns 0 on success or error code
     1630 */
     1631int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
     1632{
     1633    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
     1634}
     1635
     1636
     1637/* Check DH Keys for pair-wise consistency per process in
     1638 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
     1639 *
     1640 * key    DH key group parameters.
     1641 * pub    Public Key.
     1642 * pubSz  Public Key size.
     1643 * priv   Private Key.
     1644 * privSz Private Key size.
     1645 *
     1646 *  returns 0 on success or error code
     1647 */
     1648int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
     1649                      const byte* priv, word32 privSz)
     1650{
     1651#ifdef WOLFSSL_SMALL_STACK
     1652    mp_int* publicKey = NULL;
     1653    mp_int* privateKey = NULL;
     1654    mp_int* checkKey = NULL;
     1655#else
     1656    mp_int publicKey[1];
     1657    mp_int privateKey[1];
     1658    mp_int checkKey[1];
     1659#endif
     1660    int ret = 0;
     1661
     1662    if (key == NULL || pub == NULL || priv == NULL)
     1663        return BAD_FUNC_ARG;
     1664
     1665#ifdef WOLFSSL_SMALL_STACK
     1666    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1667    if (publicKey == NULL)
     1668        return MEMORY_E;
     1669    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1670    if (privateKey == NULL) {
     1671        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
     1672        return MEMORY_E;
     1673    }
     1674    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1675    if (checkKey == NULL) {
     1676        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
     1677        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
     1678        return MEMORY_E;
     1679    }
     1680#endif
     1681
     1682    if (mp_init_multi(publicKey, privateKey, checkKey,
     1683                      NULL, NULL, NULL) != MP_OKAY) {
     1684
     1685    #ifdef WOLFSSL_SMALL_STACK
     1686        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
     1687        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
     1688        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
     1689    #endif
     1690        return MP_INIT_E;
     1691    }
     1692
     1693    /* Load the private and public keys into big integers. */
     1694    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
     1695        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
     1696
     1697        ret = MP_READ_E;
     1698    }
     1699
     1700    /* Calculate checkKey = g^privateKey mod p */
     1701    if (ret == 0) {
     1702#ifdef WOLFSSL_HAVE_SP_DH
     1703#ifndef WOLFSSL_SP_NO_2048
     1704        if (mp_count_bits(&key->p) == 2048) {
     1705            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
     1706            if (ret != 0)
     1707                ret = MP_EXPTMOD_E;
     1708        }
     1709        else
     1710#endif
     1711#ifndef WOLFSSL_SP_NO_3072
     1712        if (mp_count_bits(&key->p) == 3072) {
     1713            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
     1714            if (ret != 0)
     1715                ret = MP_EXPTMOD_E;
     1716        }
     1717        else
     1718#endif
     1719#endif
     1720        {
     1721#ifndef WOLFSSL_SP_MATH
     1722            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
     1723                ret = MP_EXPTMOD_E;
     1724#else
     1725            ret = WC_KEY_SIZE_E;
     1726#endif
     1727        }
     1728    }
     1729
     1730    /* Compare the calculated public key to the supplied check value. */
     1731    if (ret == 0) {
     1732        if (mp_cmp(checkKey, publicKey) != MP_EQ)
    7651733        ret = MP_CMP_E;
    7661734    }
    7671735
    768     mp_clear(&y);
    769     mp_clear(&x);
     1736    mp_forcezero(privateKey);
     1737    mp_clear(privateKey);
     1738    mp_clear(publicKey);
     1739    mp_clear(checkKey);
     1740#ifdef WOLFSSL_SMALL_STACK
     1741    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
     1742    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
     1743    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
     1744#endif
    7701745
    7711746    return ret;
     
    8011776{
    8021777    int ret = 0;
    803     mp_int x;
    804     mp_int y;
    805     mp_int z;
     1778#ifdef WOLFSSL_SMALL_STACK
     1779    mp_int* y = NULL;
     1780#ifndef WOLFSSL_SP_MATH
     1781    mp_int* x = NULL;
     1782    mp_int* z = NULL;
     1783#endif
     1784#else
     1785    mp_int y[1];
     1786#ifndef WOLFSSL_SP_MATH
     1787    mp_int x[1];
     1788    mp_int z[1];
     1789#endif
     1790#endif
     1791
     1792#ifdef WOLFSSL_VALIDATE_FFC_IMPORT
     1793    if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
     1794        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
     1795        return DH_CHECK_PRIV_E;
     1796    }
    8061797
    8071798    if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
     
    8091800        return DH_CHECK_PUB_E;
    8101801    }
     1802#endif
     1803
     1804#ifdef WOLFSSL_SMALL_STACK
     1805    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1806    if (y == NULL)
     1807        return MEMORY_E;
     1808#ifndef WOLFSSL_SP_MATH
     1809    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1810    if (x == NULL) {
     1811        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1812        return MEMORY_E;
     1813    }
     1814    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
     1815    if (z == NULL) {
     1816        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1817        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1818        return MEMORY_E;
     1819    }
     1820#endif
     1821#endif
    8111822
    8121823#ifdef WOLFSSL_HAVE_SP_DH
    8131824#ifndef WOLFSSL_SP_NO_2048
    8141825    if (mp_count_bits(&key->p) == 2048) {
    815         if (mp_init(&y) != MP_OKAY)
     1826        if (mp_init(y) != MP_OKAY)
    8161827            return MP_INIT_E;
    8171828
    818         if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
     1829        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
    8191830            ret = MP_READ_E;
    8201831
    8211832        if (ret == 0)
    822             ret = sp_DhExp_2048(&y, priv, privSz, &key->p, agree, agreeSz);
    823 
    824         mp_clear(&y);
     1833            ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz);
     1834
     1835        mp_clear(y);
     1836    #ifdef WOLFSSL_SMALL_STACK
     1837    #ifndef WOLFSSL_SP_MATH
     1838        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
     1839        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1840    #endif
     1841        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1842    #endif
    8251843        return ret;
    8261844    }
     
    8281846#ifndef WOLFSSL_SP_NO_3072
    8291847    if (mp_count_bits(&key->p) == 3072) {
    830         if (mp_init(&y) != MP_OKAY)
     1848        if (mp_init(y) != MP_OKAY)
    8311849            return MP_INIT_E;
    8321850
    833         if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
     1851        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
    8341852            ret = MP_READ_E;
    8351853
    8361854        if (ret == 0)
    837             ret = sp_DhExp_3072(&y, priv, privSz, &key->p, agree, agreeSz);
    838 
    839         mp_clear(&y);
     1855            ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz);
     1856
     1857        mp_clear(y);
     1858    #ifdef WOLFSSL_SMALL_STACK
     1859    #ifndef WOLFSSL_SP_MATH
     1860        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
     1861        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1862    #endif
     1863        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1864    #endif
    8401865        return ret;
    8411866    }
     
    8431868#endif
    8441869
    845     if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
     1870#ifndef WOLFSSL_SP_MATH
     1871    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
     1872    #ifdef WOLFSSL_SMALL_STACK
     1873        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
     1874        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1875        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1876    #endif
    8461877        return MP_INIT_E;
    847 
    848     if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
     1878    }
     1879
     1880    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
    8491881        ret = MP_READ_E;
    8501882
    851     if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
     1883    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
    8521884        ret = MP_READ_E;
    8531885
    854     if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
     1886    if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY)
    8551887        ret = MP_EXPTMOD_E;
    8561888
    857     if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
     1889    /* make sure z is not one (SP800-56A, 5.7.1.1) */
     1890    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
     1891        ret = MP_VAL;
     1892
     1893    if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY)
    8581894        ret = MP_TO_E;
    8591895
    8601896    if (ret == 0)
    861         *agreeSz = mp_unsigned_bin_size(&z);
    862 
    863     mp_clear(&z);
    864     mp_clear(&y);
    865     mp_forcezero(&x);
     1897        *agreeSz = mp_unsigned_bin_size(z);
     1898
     1899    mp_clear(z);
     1900    mp_clear(y);
     1901    mp_forcezero(x);
     1902#endif
     1903
     1904#ifdef WOLFSSL_SMALL_STACK
     1905#ifndef WOLFSSL_SP_MATH
     1906    XFREE(z, key->heap, DYNAMIC_TYPE_DH);
     1907    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
     1908#endif
     1909    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
     1910#endif
    8661911
    8671912    return ret;
     
    9261971
    9271972
     1973static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
     1974                   word32 gSz, const byte* q, word32 qSz, int trusted,
     1975                   WC_RNG* rng)
     1976{
     1977    int ret = 0;
     1978    mp_int* keyP = NULL;
     1979    mp_int* keyG = NULL;
     1980    mp_int* keyQ = NULL;
     1981
     1982    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
     1983        ret = BAD_FUNC_ARG;
     1984    }
     1985
     1986    if (ret == 0) {
     1987    /* may have leading 0 */
     1988    if (p[0] == 0) {
     1989        pSz--; p++;
     1990    }
     1991
     1992    if (g[0] == 0) {
     1993        gSz--; g++;
     1994    }
     1995
     1996        if (q != NULL) {
     1997            if (q[0] == 0) {
     1998                qSz--; q++;
     1999            }
     2000        }
     2001
     2002    if (mp_init(&key->p) != MP_OKAY)
     2003            ret = MP_INIT_E;
     2004    }
     2005
     2006    if (ret == 0) {
     2007        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
     2008            ret = ASN_DH_KEY_E;
     2009        else
     2010            keyP = &key->p;
     2011    }
     2012
     2013#ifndef WOLFSSL_SP_MATH
     2014    if (ret == 0 && !trusted) {
     2015        int isPrime = 0;
     2016        if (rng != NULL)
     2017            ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);
     2018        else
     2019            ret = mp_prime_is_prime(keyP, 8, &isPrime);
     2020
     2021        if (ret == 0 && isPrime == 0)
     2022            ret = DH_CHECK_PUB_E;
     2023    }
     2024#else
     2025    (void)trusted;
     2026    (void)rng;
     2027#endif
     2028
     2029    if (ret == 0 && mp_init(&key->g) != MP_OKAY)
     2030        ret = MP_INIT_E;
     2031    if (ret == 0) {
     2032        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
     2033            ret = ASN_DH_KEY_E;
     2034        else
     2035            keyG = &key->g;
     2036    }
     2037
     2038    if (ret == 0 && q != NULL) {
     2039        if (mp_init(&key->q) != MP_OKAY)
     2040            ret = MP_INIT_E;
     2041    }
     2042    if (ret == 0 && q != NULL) {
     2043        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
     2044            ret = MP_INIT_E;
     2045        else
     2046            keyQ = &key->q;
     2047}
     2048
     2049    if (ret != 0 && key != NULL) {
     2050        if (keyQ)
     2051            mp_clear(keyQ);
     2052        if (keyG)
     2053            mp_clear(keyG);
     2054        if (keyP)
     2055            mp_clear(keyP);
     2056    }
     2057
     2058    return ret;
     2059}
     2060
     2061
     2062int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
     2063                   word32 gSz, const byte* q, word32 qSz, int trusted,
     2064                   WC_RNG* rng)
     2065{
     2066    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
     2067}
     2068
     2069
     2070int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
     2071                   word32 gSz, const byte* q, word32 qSz)
     2072{
     2073    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
     2074}
     2075
     2076
    9282077/* not in asn anymore since no actual asn types used */
    9292078int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
    9302079                word32 gSz)
    9312080{
    932     if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
    933         return BAD_FUNC_ARG;
    934     }
    935 
    936     /* may have leading 0 */
    937     if (p[0] == 0) {
    938         pSz--; p++;
    939     }
    940 
    941     if (g[0] == 0) {
    942         gSz--; g++;
    943     }
    944 
    945     if (mp_init(&key->p) != MP_OKAY)
    946         return MP_INIT_E;
    947     if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
    948         mp_clear(&key->p);
    949         return ASN_DH_KEY_E;
    950     }
    951 
    952     if (mp_init(&key->g) != MP_OKAY) {
    953         mp_clear(&key->p);
    954         return MP_INIT_E;
    955     }
    956     if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
    957         mp_clear(&key->g);
    958         mp_clear(&key->p);
    959         return ASN_DH_KEY_E;
    960     }
    961 
    962     return 0;
    963 }
     2081    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
     2082}
     2083
     2084
     2085#ifdef WOLFSSL_KEY_GEN
     2086
     2087/* modulus_size in bits */
     2088int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
     2089{
     2090    mp_int  tmp, tmp2;
     2091    int     groupSz = 0, bufSz = 0,
     2092            primeCheckCount = 0,
     2093            primeCheck = MP_NO,
     2094            ret = 0;
     2095    unsigned char *buf = NULL;
     2096
     2097    if (rng == NULL || dh == NULL)
     2098        ret = BAD_FUNC_ARG;
     2099
     2100    /* set group size in bytes from modulus size
     2101     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
     2102     */
     2103    if (ret == 0) {
     2104        switch (modSz) {
     2105            case 1024:
     2106                groupSz = 20;
     2107                break;
     2108            case 2048:
     2109            case 3072:
     2110                groupSz = 32;
     2111                break;
     2112            default:
     2113                ret = BAD_FUNC_ARG;
     2114                break;
     2115        }
     2116    }
     2117
     2118    if (ret == 0) {
     2119        /* modulus size in bytes */
     2120        modSz /= WOLFSSL_BIT_SIZE;
     2121        bufSz = modSz - groupSz;
     2122
     2123        /* allocate ram */
     2124        buf = (unsigned char *)XMALLOC(bufSz,
     2125                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
     2126        if (buf == NULL)
     2127            ret = MEMORY_E;
     2128    }
     2129
     2130    /* make a random string that will be multplied against q */
     2131    if (ret == 0)
     2132        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
     2133
     2134    if (ret == 0) {
     2135        /* force magnitude */
     2136        buf[0] |= 0xC0;
     2137        /* force even */
     2138        buf[bufSz - 1] &= ~1;
     2139
     2140        if (mp_init_multi(&tmp, &tmp2, &dh->p, &dh->q, &dh->g, 0)
     2141                != MP_OKAY) {
     2142            ret = MP_INIT_E;
     2143        }
     2144    }
     2145
     2146    if (ret == 0) {
     2147        if (mp_read_unsigned_bin(&tmp2, buf, bufSz) != MP_OKAY)
     2148            ret = MP_READ_E;
     2149    }
     2150
     2151    /* make our prime q */
     2152    if (ret == 0) {
     2153        if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY)
     2154            ret = PRIME_GEN_E;
     2155    }
     2156
     2157    /* p = random * q */
     2158    if (ret == 0) {
     2159        if (mp_mul(&dh->q, &tmp2, &dh->p) != MP_OKAY)
     2160            ret = MP_MUL_E;
     2161    }
     2162
     2163    /* p = random * q + 1, so q is a prime divisor of p-1 */
     2164    if (ret == 0) {
     2165        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
     2166            ret = MP_ADD_E;
     2167    }
     2168
     2169    /* tmp = 2q  */
     2170    if (ret == 0) {
     2171        if (mp_add(&dh->q, &dh->q, &tmp) != MP_OKAY)
     2172            ret = MP_ADD_E;
     2173    }
     2174
     2175    /* loop until p is prime */
     2176    if (ret == 0) {
     2177        do {
     2178            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
     2179                ret = PRIME_GEN_E;
     2180
     2181            if (primeCheck != MP_YES) {
     2182                /* p += 2q */
     2183                if (mp_add(&tmp, &dh->p, &dh->p) != MP_OKAY)
     2184                    ret = MP_ADD_E;
     2185                else
     2186                    primeCheckCount++;
     2187            }
     2188        } while (ret == 0 && primeCheck == MP_NO);
     2189    }
     2190
     2191    /* tmp2 += (2*loop_check_prime)
     2192     * to have p = (q * tmp2) + 1 prime
     2193     */
     2194    if (primeCheckCount) {
     2195        if (mp_add_d(&tmp2, 2 * primeCheckCount, &tmp2) != MP_OKAY)
     2196            ret = MP_ADD_E;
     2197    }
     2198
     2199    /* find a value g for which g^tmp2 != 1 */
     2200    if (mp_set(&dh->g, 1) != MP_OKAY)
     2201        ret = MP_ZERO_E;
     2202
     2203    if (ret == 0) {
     2204        do {
     2205            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
     2206                ret = MP_ADD_E;
     2207            else if (mp_exptmod(&dh->g, &tmp2, &dh->p, &tmp) != MP_OKAY)
     2208                ret = MP_EXPTMOD_E;
     2209        } while (ret == 0 && mp_cmp_d(&tmp, 1) == MP_EQ);
     2210    }
     2211
     2212    /* at this point tmp generates a group of order q mod p */
     2213    mp_exch(&tmp, &dh->g);
     2214
     2215    /* clear the parameters if there was an error */
     2216    if (ret != 0) {
     2217        mp_clear(&dh->q);
     2218        mp_clear(&dh->p);
     2219        mp_clear(&dh->g);
     2220    }
     2221
     2222    ForceZero(buf, bufSz);
     2223    XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
     2224    mp_clear(&tmp);
     2225    mp_clear(&tmp2);
     2226
     2227    return ret;
     2228}
     2229
     2230
     2231/* Export raw DH parameters from DhKey structure
     2232 *
     2233 * dh   - pointer to initialized DhKey structure
     2234 * p    - output location for DH (p) parameter
     2235 * pSz  - [IN/OUT] size of output buffer for p, size of p
     2236 * q    - output location for DH (q) parameter
     2237 * qSz  - [IN/OUT] size of output buffer for q, size of q
     2238 * g    - output location for DH (g) parameter
     2239 * gSz  - [IN/OUT] size of output buffer for g, size of g
     2240 *
     2241 * If p, q, and g pointers are all passed in as NULL, the function
     2242 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
     2243 * q, and g. In this case, the function will return LENGTH_ONLY_E.
     2244 *
     2245 * returns 0 on success, negative upon failure
     2246 */
     2247int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
     2248                         byte* q, word32* qSz, byte* g, word32* gSz)
     2249{
     2250    int ret = 0;
     2251    word32 pLen = 0, qLen = 0, gLen = 0;
     2252
     2253    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
     2254        ret = BAD_FUNC_ARG;
     2255
     2256    /* get required output buffer sizes */
     2257    if (ret == 0) {
     2258        pLen = mp_unsigned_bin_size(&dh->p);
     2259        qLen = mp_unsigned_bin_size(&dh->q);
     2260        gLen = mp_unsigned_bin_size(&dh->g);
     2261
     2262        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
     2263        if (p == NULL && q == NULL && g == NULL) {
     2264            *pSz = pLen;
     2265            *qSz = qLen;
     2266            *gSz = gLen;
     2267            ret = LENGTH_ONLY_E;
     2268        }
     2269    }
     2270
     2271    if (ret == 0) {
     2272        if (p == NULL || q == NULL || g == NULL)
     2273            ret = BAD_FUNC_ARG;
     2274    }
     2275
     2276    /* export p */
     2277    if (ret == 0) {
     2278        if (*pSz < pLen) {
     2279            WOLFSSL_MSG("Output buffer for DH p parameter too small, "
     2280                        "required size placed into pSz");
     2281            *pSz = pLen;
     2282            ret = BUFFER_E;
     2283        }
     2284    }
     2285
     2286    if (ret == 0) {
     2287        *pSz = pLen;
     2288        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
     2289            ret = MP_TO_E;
     2290    }
     2291
     2292    /* export q */
     2293    if (ret == 0) {
     2294        if (*qSz < qLen) {
     2295            WOLFSSL_MSG("Output buffer for DH q parameter too small, "
     2296                        "required size placed into qSz");
     2297            *qSz = qLen;
     2298            ret = BUFFER_E;
     2299        }
     2300    }
     2301
     2302    if (ret == 0) {
     2303        *qSz = qLen;
     2304        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
     2305            ret = MP_TO_E;
     2306    }
     2307
     2308    /* export g */
     2309    if (ret == 0) {
     2310        if (*gSz < gLen) {
     2311            WOLFSSL_MSG("Output buffer for DH g parameter too small, "
     2312                        "required size placed into gSz");
     2313            *gSz = gLen;
     2314            ret = BUFFER_E;
     2315        }
     2316    }
     2317
     2318    if (ret == 0) {
     2319        *gSz = gLen;
     2320        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
     2321            ret = MP_TO_E;
     2322    }
     2323
     2324    return ret;
     2325}
     2326
     2327#endif /* WOLFSSL_KEY_GEN */
    9642328
    9652329#endif /* NO_DH */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/dsa.c

    r352 r372  
    9898}
    9999
     100
     101/* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2.
     102 * modLen - represents L, the size of p (prime modulus) in bits
     103 * divLen - represents N, the size of q (prime divisor) in bits
     104 * return 0 on success, -1 on error */
     105static int CheckDsaLN(int modLen, int divLen)
     106{
     107    int ret = -1;
     108
     109    switch (modLen) {
     110        case 1024:
     111            if (divLen == 160)
     112                ret = 0;
     113            break;
     114        case 2048:
     115            if (divLen == 224 || divLen == 256)
     116                ret = 0;
     117            break;
     118        case 3072:
     119            if (divLen == 256)
     120                ret = 0;
     121            break;
     122        default:
     123            break;
     124    }
     125
     126    return ret;
     127}
     128
     129
    100130#ifdef WOLFSSL_KEY_GEN
    101131
     132/* Create DSA key pair (&dsa->x, &dsa->y)
     133 *
     134 * Based on NIST FIPS 186-4,
     135 * "B.1.1 Key Pair Generation Using Extra Random Bits"
     136 *
     137 * rng - pointer to initialized WC_RNG structure
     138 * dsa - pointer to initialized DsaKey structure, will hold generated key
     139 *
     140 * return 0 on success, negative on error */
    102141int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)
    103142{
    104     unsigned char *buf;
    105     int qsize, err;
     143    byte* cBuf;
     144    int qSz, pSz, cSz, err;
     145    mp_int tmpQ;
    106146
    107147    if (rng == NULL || dsa == NULL)
    108148        return BAD_FUNC_ARG;
    109149
    110     qsize = mp_unsigned_bin_size(&dsa->q);
    111     if (qsize == 0)
    112         return BAD_FUNC_ARG;
    113 
    114     /* allocate ram */
    115     buf = (unsigned char *)XMALLOC(qsize, dsa->heap,
    116                                    DYNAMIC_TYPE_TMP_BUFFER);
    117     if (buf == NULL)
     150    qSz = mp_unsigned_bin_size(&dsa->q);
     151    pSz = mp_unsigned_bin_size(&dsa->p);
     152
     153    /* verify (L,N) pair bit lengths */
     154    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0)
     155        return BAD_FUNC_ARG;
     156
     157    /* generate extra 64 bits so that bias from mod function is negligible */
     158    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
     159    cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
     160    if (cBuf == NULL) {
    118161        return MEMORY_E;
    119 
    120     if (mp_init(&dsa->x) != MP_OKAY) {
    121         XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
    122         return MP_INIT_E;
     162    }
     163
     164    if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL))
     165                   != MP_OKAY) {
     166        XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
     167        return err;
    123168    }
    124169
    125170    do {
    126         /* make a random exponent mod q */
    127         err = wc_RNG_GenerateBlock(rng, buf, qsize);
     171        /* generate N+64 bits (c) from RBG into &dsa->x, making sure positive.
     172         * Hash_DRBG uses SHA-256 which matches maximum
     173         * requested_security_strength of (L,N) */
     174        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
    128175        if (err != MP_OKAY) {
    129176            mp_clear(&dsa->x);
    130             XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
     177            mp_clear(&dsa->y);
     178            mp_clear(&tmpQ);
     179            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
    131180            return err;
    132181        }
    133182
    134         err = mp_read_unsigned_bin(&dsa->x, buf, qsize);
     183        err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz);
    135184        if (err != MP_OKAY) {
    136185            mp_clear(&dsa->x);
    137             XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
     186            mp_clear(&dsa->y);
     187            mp_clear(&tmpQ);
     188            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
    138189            return err;
    139190        }
    140191    } while (mp_cmp_d(&dsa->x, 1) != MP_GT);
    141192
    142     XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
    143 
    144     if (mp_init(&dsa->y) != MP_OKAY) {
    145         mp_clear(&dsa->x);
    146         return MP_INIT_E;
    147     }
     193    XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
     194
     195    /* tmpQ = q - 1 */
     196    if (err == MP_OKAY)
     197        err = mp_copy(&dsa->q, &tmpQ);
     198
     199    if (err == MP_OKAY)
     200        err = mp_sub_d(&tmpQ, 1, &tmpQ);
     201
     202    /* x = c mod (q-1), &dsa->x holds c */
     203    if (err == MP_OKAY)
     204        err = mp_mod(&dsa->x, &tmpQ, &dsa->x);
     205
     206    /* x = c mod (q-1) + 1 */
     207    if (err == MP_OKAY)
     208        err = mp_add_d(&dsa->x, 1, &dsa->x);
    148209
    149210    /* public key : y = g^x mod p */
     211    if (err == MP_OKAY)
    150212    err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y);
     213
     214    if (err == MP_OKAY)
     215        dsa->type = DSA_PRIVATE;
     216
    151217    if (err != MP_OKAY) {
    152218        mp_clear(&dsa->x);
    153219        mp_clear(&dsa->y);
    154         return err;
    155     }
    156 
    157     dsa->type = DSA_PRIVATE;
    158 
    159     return MP_OKAY;
    160 }
     220    }
     221    mp_clear(&tmpQ);
     222
     223    return err;
     224}
     225
    161226
    162227/* modulus_size in bits */
     
    185250        default:
    186251            return BAD_FUNC_ARG;
    187             break;
    188252    }
    189253
    190254    /* modulus size in bytes */
    191     msize = modulus_size / 8;
     255    msize = modulus_size / WOLFSSL_BIT_SIZE;
    192256
    193257    /* allocate ram */
     
    273337    /* loop until p is prime */
    274338    while (check_prime == MP_NO) {
    275         err = mp_prime_is_prime(&dsa->p, 8, &check_prime);
     339        err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng);
    276340        if (err != MP_OKAY) {
    277341            mp_clear(&dsa->q);
     
    362426
    363427
     428static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
     429                          const char* g, int trusted, WC_RNG* rng)
     430{
     431    int err;
     432    word32 pSz, qSz;
     433
     434    if (dsa == NULL || p == NULL || q == NULL || g == NULL)
     435        return BAD_FUNC_ARG;
     436
     437    /* read p */
     438    err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX);
     439    if (err == MP_OKAY && !trusted) {
     440        int isPrime = 1;
     441        if (rng == NULL)
     442            err = mp_prime_is_prime(&dsa->p, 8, &isPrime);
     443        else
     444            err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng);
     445
     446        if (err == MP_OKAY) {
     447            if (!isPrime)
     448                err = DH_CHECK_PUB_E;
     449        }
     450    }
     451
     452    /* read q */
     453    if (err == MP_OKAY)
     454        err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX);
     455
     456    /* read g */
     457    if (err == MP_OKAY)
     458        err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX);
     459
     460    /* verify (L,N) pair bit lengths */
     461    pSz = mp_unsigned_bin_size(&dsa->p);
     462    qSz = mp_unsigned_bin_size(&dsa->q);
     463
     464    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
     465        WOLFSSL_MSG("Invalid DSA p or q parameter size");
     466        err = BAD_FUNC_ARG;
     467    }
     468
     469    if (err != MP_OKAY) {
     470        mp_clear(&dsa->p);
     471        mp_clear(&dsa->q);
     472        mp_clear(&dsa->g);
     473    }
     474
     475    return err;
     476}
     477
     478
     479/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
     480 * input parameters (p,q,g) should be represented as ASCII hex values.
     481 *
     482 * dsa  - pointer to initialized DsaKey structure
     483 * p    - DSA (p) parameter, ASCII hex string
     484 * pSz  - length of p
     485 * q    - DSA (q) parameter, ASCII hex string
     486 * qSz  - length of q
     487 * g    - DSA (g) parameter, ASCII hex string
     488 * gSz  - length of g
     489 *
     490 * returns 0 on success, negative upon failure
     491 */
     492int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,
     493                          const char* g)
     494{
     495    return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL);
     496}
     497
     498
     499/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),
     500 * input parameters (p,q,g) should be represented as ASCII hex values. Check
     501 * that the p value is probably prime.
     502 *
     503 * dsa  - pointer to initialized DsaKey structure
     504 * p    - DSA (p) parameter, ASCII hex string
     505 * pSz  - length of p
     506 * q    - DSA (q) parameter, ASCII hex string
     507 * qSz  - length of q
     508 * g    - DSA (g) parameter, ASCII hex string
     509 * gSz  - length of g
     510 * trusted - trust that p is OK
     511 * rng  - random number generator for the prime test
     512 *
     513 * returns 0 on success, negative upon failure
     514 */
     515int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q,
     516                          const char* g, int trusted, WC_RNG* rng)
     517{
     518    return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng);
     519}
     520
     521
     522/* Export raw DSA parameters from DsaKey structure
     523 *
     524 * dsa  - pointer to initialized DsaKey structure
     525 * p    - output location for DSA (p) parameter
     526 * pSz  - [IN/OUT] size of output buffer for p, size of p
     527 * q    - output location for DSA (q) parameter
     528 * qSz  - [IN/OUT] size of output buffer for q, size of q
     529 * g    - output location for DSA (g) parameter
     530 * gSz  - [IN/OUT] size of output buffer for g, size of g
     531 *
     532 * If p, q, and g pointers are all passed in as NULL, the function
     533 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
     534 * q, and g. In this case, the function will return LENGTH_ONLY_E.
     535 *
     536 * returns 0 on success, negative upon failure
     537 */
     538int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,
     539                          byte* q, word32* qSz, byte* g, word32* gSz)
     540{
     541    int err;
     542    word32 pLen, qLen, gLen;
     543
     544    if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
     545        return BAD_FUNC_ARG;
     546
     547    /* get required output buffer sizes */
     548    pLen = mp_unsigned_bin_size(&dsa->p);
     549    qLen = mp_unsigned_bin_size(&dsa->q);
     550    gLen = mp_unsigned_bin_size(&dsa->g);
     551
     552    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
     553    if (p == NULL && q == NULL && g == NULL) {
     554        *pSz = pLen;
     555        *qSz = qLen;
     556        *gSz = gLen;
     557        return LENGTH_ONLY_E;
     558    }
     559
     560    if (p == NULL || q == NULL || g == NULL)
     561        return BAD_FUNC_ARG;
     562
     563    /* export p */
     564    if (*pSz < pLen) {
     565        WOLFSSL_MSG("Output buffer for DSA p parameter too small, "
     566                    "required size placed into pSz");
     567        *pSz = pLen;
     568        return BUFFER_E;
     569    }
     570    *pSz = pLen;
     571    err = mp_to_unsigned_bin(&dsa->p, p);
     572
     573    /* export q */
     574    if (err == MP_OKAY) {
     575        if (*qSz < qLen) {
     576            WOLFSSL_MSG("Output buffer for DSA q parameter too small, "
     577                        "required size placed into qSz");
     578            *qSz = qLen;
     579            return BUFFER_E;
     580        }
     581        *qSz = qLen;
     582        err = mp_to_unsigned_bin(&dsa->q, q);
     583    }
     584
     585    /* export g */
     586    if (err == MP_OKAY) {
     587        if (*gSz < gLen) {
     588            WOLFSSL_MSG("Output buffer for DSA g parameter too small, "
     589                        "required size placed into gSz");
     590            *gSz = gLen;
     591            return BUFFER_E;
     592        }
     593        *gSz = gLen;
     594        err = mp_to_unsigned_bin(&dsa->g, g);
     595    }
     596
     597    return err;
     598}
     599
     600
     601/* Export raw DSA key (x, y) from DsaKey structure
     602 *
     603 * dsa  - pointer to initialized DsaKey structure
     604 * x    - output location for private key
     605 * xSz  - [IN/OUT] size of output buffer for x, size of x
     606 * y    - output location for public key
     607 * ySz  - [IN/OUT] size of output buffer for y, size of y
     608 *
     609 * If x and y pointers are all passed in as NULL, the function
     610 * will set xSz and ySz to the required output buffer sizes for x
     611 * and y. In this case, the function will return LENGTH_ONLY_E.
     612 *
     613 * returns 0 on success, negative upon failure
     614 */
     615int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)
     616{
     617    int err;
     618    word32 xLen, yLen;
     619
     620    if (dsa == NULL || xSz == NULL || ySz == NULL)
     621        return BAD_FUNC_ARG;
     622
     623    /* get required output buffer sizes */
     624    xLen = mp_unsigned_bin_size(&dsa->x);
     625    yLen = mp_unsigned_bin_size(&dsa->y);
     626
     627    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
     628    if (x == NULL && y == NULL) {
     629        *xSz = xLen;
     630        *ySz = yLen;
     631        return LENGTH_ONLY_E;
     632    }
     633
     634    if (x == NULL || y == NULL)
     635        return BAD_FUNC_ARG;
     636
     637    /* export x */
     638    if (*xSz < xLen) {
     639        WOLFSSL_MSG("Output buffer for DSA private key (x) too small, "
     640                    "required size placed into xSz");
     641        *xSz = xLen;
     642        return BUFFER_E;
     643    }
     644    *xSz = xLen;
     645    err = mp_to_unsigned_bin(&dsa->x, x);
     646
     647    /* export y */
     648    if (err == MP_OKAY) {
     649        if (*ySz < yLen) {
     650            WOLFSSL_MSG("Output buffer to DSA public key (y) too small, "
     651                        "required size placed into ySz");
     652            *ySz = yLen;
     653            return BUFFER_E;
     654        }
     655        *ySz = yLen;
     656        err = mp_to_unsigned_bin(&dsa->y, y);
     657    }
     658
     659    return err;
     660}
     661
     662
    364663int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
    365664{
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/ecc.c

    r352 r372  
    9494
    9595
     96#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     97    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     98    #define FIPS_NO_WRAPPERS
     99
     100        #ifdef USE_WINDOWS_API
     101                #pragma code_seg(".fipsA$f")
     102                #pragma const_seg(".fipsB$f")
     103        #endif
     104#endif
     105
    96106#include <wolfssl/wolfcrypt/ecc.h>
    97107#include <wolfssl/wolfcrypt/asn.h>
     
    113123#endif
    114124
     125#ifdef WOLF_CRYPTO_DEV
     126    #include <wolfssl/wolfcrypt/cryptodev.h>
     127#endif
     128
    115129#ifdef NO_INLINE
    116130    #include <wolfssl/wolfcrypt/misc.h>
     
    124138#endif
    125139
    126 #ifdef USE_FAST_MATH
     140#ifdef WOLFSSL_SP_MATH
     141    #define GEN_MEM_ERR MP_MEM
     142#elif defined(USE_FAST_MATH)
    127143    #define GEN_MEM_ERR FP_MEM
    128144#else
     
    186202#endif
    187203
    188 
    189204/* The encoded OID's for ECC curves */
    190205#ifdef ECC112
    191206    #ifndef NO_ECC_SECP
    192         static const ecc_oid_t ecc_oid_secp112r1[] = {
    193207        #ifdef HAVE_OID_ENCODING
    194             1,3,132,0,6
     208            #define CODED_SECP112R1    {1,3,132,0,6}
     209            #define CODED_SECP112R1_SZ 5
    195210        #else
    196             0x2B,0x81,0x04,0x00,0x06
     211            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
     212            #define CODED_SECP112R1_SZ 5
    197213        #endif
    198         };
     214        #ifndef USE_WINDOWS_API
     215            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
     216        #else
     217            #define ecc_oid_secp112r1 CODED_SECP112R1
     218        #endif
     219        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
    199220    #endif /* !NO_ECC_SECP */
    200221    #ifdef HAVE_ECC_SECPR2
    201         static const ecc_oid_t ecc_oid_secp112r2[] = {
    202222        #ifdef HAVE_OID_ENCODING
    203             1,3,132,0,7
     223            #define CODED_SECP112R2    {1,3,132,0,7}
     224            #define CODED_SECP112R2_SZ 5
    204225        #else
    205             0x2B,0x81,0x04,0x00,0x07
     226            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
     227            #define CODED_SECP112R2_SZ 5
    206228        #endif
    207         };
     229        #ifndef USE_WINDOWS_API
     230            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
     231        #else
     232            #define ecc_oid_secp112r2 CODED_SECP112R2
     233        #endif
     234        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
    208235    #endif /* HAVE_ECC_SECPR2 */
    209236#endif /* ECC112 */
    210237#ifdef ECC128
    211238    #ifndef NO_ECC_SECP
    212         static const ecc_oid_t ecc_oid_secp128r1[] = {
    213239        #ifdef HAVE_OID_ENCODING
    214             1,3,132,0,28
     240            #define CODED_SECP128R1    {1,3,132,0,28}
     241            #define CODED_SECP128R1_SZ 5
    215242        #else
    216             0x2B,0x81,0x04,0x00,0x1C
     243            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
     244            #define CODED_SECP128R1_SZ 5
    217245        #endif
    218         };
     246        #ifndef USE_WINDOWS_API
     247            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
     248        #else
     249            #define ecc_oid_secp128r1 CODED_SECP128R1
     250        #endif
     251        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
    219252    #endif /* !NO_ECC_SECP */
    220253    #ifdef HAVE_ECC_SECPR2
    221         static const ecc_oid_t ecc_oid_secp128r2[] = {
    222254        #ifdef HAVE_OID_ENCODING
    223             1,3,132,0,29
     255            #define CODED_SECP128R2    {1,3,132,0,29}
     256            #define CODED_SECP128R2_SZ 5
    224257        #else
    225             0x2B,0x81,0x04,0x00,0x1D
     258            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
     259            #define CODED_SECP128R2_SZ 5
    226260        #endif
    227         };
     261        #ifndef USE_WINDOWS_API
     262            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
     263        #else
     264            #define ecc_oid_secp128r2 CODED_SECP128R2
     265        #endif
     266        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
    228267    #endif /* HAVE_ECC_SECPR2 */
    229268#endif /* ECC128 */
    230269#ifdef ECC160
    231270    #ifndef NO_ECC_SECP
    232         static const ecc_oid_t ecc_oid_secp160r1[] = {
    233271        #ifdef HAVE_OID_ENCODING
    234             1,3,132,0,8
     272            #define CODED_SECP160R1    {1,3,132,0,8}
     273            #define CODED_SECP160R1_SZ 5
    235274        #else
    236             0x2B,0x81,0x04,0x00,0x08
     275            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
     276            #define CODED_SECP160R1_SZ 5
    237277        #endif
    238         };
     278        #ifndef USE_WINDOWS_API
     279            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
     280        #else
     281            #define ecc_oid_secp160r1 CODED_SECP160R1
     282        #endif
     283        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
    239284    #endif /* !NO_ECC_SECP */
    240285    #ifdef HAVE_ECC_SECPR2
    241         static const ecc_oid_t ecc_oid_secp160r2[] = {
    242286        #ifdef HAVE_OID_ENCODING
    243             1,3,132,0,30
     287            #define CODED_SECP160R2    {1,3,132,0,30}
     288            #define CODED_SECP160R1_SZ 5
    244289        #else
    245             0x2B,0x81,0x04,0x00,0x1E
     290            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
     291            #define CODED_SECP160R2_SZ 5
    246292        #endif
    247         };
     293        #ifndef USE_WINDOWS_API
     294            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
     295        #else
     296            #define ecc_oid_secp160r2 CODED_SECP160R2
     297        #endif
     298        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
    248299    #endif /* HAVE_ECC_SECPR2 */
    249300    #ifdef HAVE_ECC_KOBLITZ
    250         static const ecc_oid_t ecc_oid_secp160k1[] = {
    251301        #ifdef HAVE_OID_ENCODING
    252             1,3,132,0,9
     302            #define CODED_SECP160K1    {1,3,132,0,9}
     303            #define CODED_SECP160K1_SZ 5
    253304        #else
    254             0x2B,0x81,0x04,0x00,0x09
     305            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
     306            #define CODED_SECP160K1_SZ 5
    255307        #endif
    256         };
     308        #ifndef USE_WINDOWS_API
     309            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
     310        #else
     311            #define ecc_oid_secp160k1 CODED_SECP160K1
     312        #endif
     313        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
    257314    #endif /* HAVE_ECC_KOBLITZ */
    258315    #ifdef HAVE_ECC_BRAINPOOL
    259         static const ecc_oid_t ecc_oid_brainpoolp160r1[] = {
    260316        #ifdef HAVE_OID_ENCODING
    261             1,3,36,3,3,2,8,1,1,1
     317            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
     318            #define CODED_BRAINPOOLP160R1_SZ 10
    262319        #else
    263             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01
     320            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
     321            #define CODED_BRAINPOOLP160R1_SZ 9
    264322        #endif
    265         };
     323        #ifndef USE_WINDOWS_API
     324            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
     325        #else
     326            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
     327        #endif
     328        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
    266329    #endif /* HAVE_ECC_BRAINPOOL */
    267330#endif /* ECC160 */
    268331#ifdef ECC192
    269332    #ifndef NO_ECC_SECP
    270         static const ecc_oid_t ecc_oid_secp192r1[] = {
    271333        #ifdef HAVE_OID_ENCODING
    272             1,2,840,10045,3,1,1
     334            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
     335            #define CODED_SECP192R1_SZ 7
    273336        #else
    274             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01
     337            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
     338            #define CODED_SECP192R1_SZ 8
    275339        #endif
    276         };
     340        #ifndef USE_WINDOWS_API
     341            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
     342        #else
     343            #define ecc_oid_secp192r1 CODED_SECP192R1
     344        #endif
     345        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
    277346    #endif /* !NO_ECC_SECP */
    278347    #ifdef HAVE_ECC_SECPR2
    279         static const ecc_oid_t ecc_oid_prime192v2[] = {
    280348        #ifdef HAVE_OID_ENCODING
    281             1,2,840,10045,3,1,2
     349            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
     350            #define CODED_PRIME192V2_SZ 7
    282351        #else
    283             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02
     352            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
     353            #define CODED_PRIME192V2_SZ 8
    284354        #endif
    285         };
     355        #ifndef USE_WINDOWS_API
     356            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
     357        #else
     358            #define ecc_oid_prime192v2 CODED_PRIME192V2
     359        #endif
     360        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
    286361    #endif /* HAVE_ECC_SECPR2 */
    287362    #ifdef HAVE_ECC_SECPR3
    288         static const ecc_oid_t ecc_oid_prime192v3[] = {
    289363        #ifdef HAVE_OID_ENCODING
    290             1,2,840,10045,3,1,3
     364            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
     365            #define CODED_PRIME192V3_SZ 7
    291366        #else
    292             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03
     367            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
     368            #define CODED_PRIME192V3_SZ 8
    293369        #endif
    294         };
     370        #ifndef USE_WINDOWS_API
     371            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
     372        #else
     373            #define ecc_oid_prime192v3 CODED_PRIME192V3
     374        #endif
     375        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
    295376    #endif /* HAVE_ECC_SECPR3 */
    296377    #ifdef HAVE_ECC_KOBLITZ
    297         static const ecc_oid_t ecc_oid_secp192k1[] = {
    298378        #ifdef HAVE_OID_ENCODING
    299             1,3,132,0,31
     379            #define CODED_SECP192K1    {1,3,132,0,31}
     380            #define CODED_SECP192K1_SZ 5
    300381        #else
    301             0x2B,0x81,0x04,0x00,0x1F
     382            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
     383            #define CODED_SECP192K1_SZ 5
    302384        #endif
    303         };
     385        #ifndef USE_WINDOWS_API
     386            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
     387        #else
     388            #define ecc_oid_secp192k1 CODED_SECP192K1
     389        #endif
     390        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
    304391    #endif /* HAVE_ECC_KOBLITZ */
    305392    #ifdef HAVE_ECC_BRAINPOOL
    306         static const ecc_oid_t ecc_oid_brainpoolp192r1[] = {
    307393        #ifdef HAVE_OID_ENCODING
    308             1,3,36,3,3,2,8,1,1,3
     394            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
     395            #define CODED_BRAINPOOLP192R1_SZ 10
    309396        #else
    310             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03
     397            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
     398            #define CODED_BRAINPOOLP192R1_SZ 9
    311399        #endif
    312         };
     400        #ifndef USE_WINDOWS_API
     401            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
     402        #else
     403            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
     404        #endif
     405        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
    313406    #endif /* HAVE_ECC_BRAINPOOL */
    314407#endif /* ECC192 */
    315408#ifdef ECC224
    316409    #ifndef NO_ECC_SECP
    317         static const ecc_oid_t ecc_oid_secp224r1[] = {
    318410        #ifdef HAVE_OID_ENCODING
    319             1,3,132,0,33
     411            #define CODED_SECP224R1    {1,3,132,0,33}
     412            #define CODED_SECP224R1_SZ 5
    320413        #else
    321             0x2B,0x81,0x04,0x00,0x21
     414            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
     415            #define CODED_SECP224R1_SZ 5
    322416        #endif
    323         };
     417        #ifndef USE_WINDOWS_API
     418            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
     419        #else
     420            #define ecc_oid_secp224r1 CODED_SECP224R1
     421        #endif
     422        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
    324423    #endif /* !NO_ECC_SECP */
    325424    #ifdef HAVE_ECC_KOBLITZ
    326         static const ecc_oid_t ecc_oid_secp224k1[] = {
    327425        #ifdef HAVE_OID_ENCODING
    328             1,3,132,0,32
     426            #define CODED_SECP224K1    {1,3,132,0,32}
     427            #define CODED_SECP224K1_SZ 5
    329428        #else
    330             0x2B,0x81,0x04,0x00,0x20
     429            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
     430            #define CODED_SECP224K1_SZ 5
    331431        #endif
    332         };
     432        #ifndef USE_WINDOWS_API
     433            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
     434        #else
     435            #define ecc_oid_secp224k1 CODED_SECP224K1
     436        #endif
     437        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
    333438    #endif /* HAVE_ECC_KOBLITZ */
    334439    #ifdef HAVE_ECC_BRAINPOOL
    335         static const ecc_oid_t ecc_oid_brainpoolp224r1[] = {
    336440        #ifdef HAVE_OID_ENCODING
    337             1,3,36,3,3,2,8,1,1,5
     441            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
     442            #define CODED_BRAINPOOLP224R1_SZ 10
    338443        #else
    339             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05
     444            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
     445            #define CODED_BRAINPOOLP224R1_SZ 9
    340446        #endif
    341         };
     447        #ifndef USE_WINDOWS_API
     448            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
     449        #else
     450            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
     451        #endif
     452        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
    342453    #endif /* HAVE_ECC_BRAINPOOL */
    343454#endif /* ECC224 */
    344455#ifdef ECC239
    345456    #ifndef NO_ECC_SECP
    346         static const ecc_oid_t ecc_oid_prime239v1[] = {
    347457        #ifdef HAVE_OID_ENCODING
    348             1,2,840,10045,3,1,4
     458            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
     459            #define CODED_PRIME239V1_SZ 7
    349460        #else
    350             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04
     461            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
     462            #define CODED_PRIME239V1_SZ 8
    351463        #endif
    352         };
     464        #ifndef USE_WINDOWS_API
     465            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
     466        #else
     467            #define ecc_oid_prime239v1 CODED_PRIME239V1
     468        #endif
     469        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
    353470    #endif /* !NO_ECC_SECP */
    354471    #ifdef HAVE_ECC_SECPR2
    355         static const ecc_oid_t ecc_oid_prime239v2[] = {
    356472        #ifdef HAVE_OID_ENCODING
    357             1,2,840,10045,3,1,5
     473            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
     474            #define CODED_PRIME239V2_SZ 7
    358475        #else
    359             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05
     476            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
     477            #define CODED_PRIME239V2_SZ 8
    360478        #endif
    361         };
     479        #ifndef USE_WINDOWS_API
     480            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
     481        #else
     482            #define ecc_oid_prime239v2 CODED_PRIME239V2
     483        #endif
     484        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
    362485    #endif /* HAVE_ECC_SECPR2 */
    363486    #ifdef HAVE_ECC_SECPR3
    364         static const ecc_oid_t ecc_oid_prime239v3[] = {
    365487        #ifdef HAVE_OID_ENCODING
    366             1,2,840,10045,3,1,6
     488            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
     489            #define CODED_PRIME239V3_SZ 7
    367490        #else
    368             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06
     491            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
     492            #define CODED_PRIME239V3_SZ 8
    369493        #endif
    370         };
     494        #ifndef USE_WINDOWS_API
     495            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
     496        #else
     497            #define ecc_oid_prime239v3 CODED_PRIME239V3
     498        #endif
     499        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
    371500    #endif /* HAVE_ECC_SECPR3 */
    372501#endif /* ECC239 */
    373502#ifdef ECC256
    374503    #ifndef NO_ECC_SECP
    375         static const ecc_oid_t ecc_oid_secp256r1[] = {
    376504        #ifdef HAVE_OID_ENCODING
    377             1,2,840,10045,3,1,7
     505            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
     506            #define CODED_SECP256R1_SZ 7
    378507        #else
    379             0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07
     508            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
     509            #define CODED_SECP256R1_SZ 8
    380510        #endif
    381         };
     511        #ifndef USE_WINDOWS_API
     512            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
     513        #else
     514            #define ecc_oid_secp256r1 CODED_SECP256R1
     515        #endif
     516        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
    382517    #endif /* !NO_ECC_SECP */
    383518    #ifdef HAVE_ECC_KOBLITZ
    384         static const ecc_oid_t ecc_oid_secp256k1[] = {
    385519        #ifdef HAVE_OID_ENCODING
    386             1,3,132,0,10
     520            #define CODED_SECP256K1    {1,3,132,0,10}
     521            #define CODED_SECP256K1_SZ 5
    387522        #else
    388             0x2B,0x81,0x04,0x00,0x0A
     523            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
     524            #define CODED_SECP256K1_SZ 5
    389525        #endif
    390         };
     526        #ifndef USE_WINDOWS_API
     527            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
     528        #else
     529            #define ecc_oid_secp256k1 CODED_SECP256K1
     530        #endif
     531        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
    391532    #endif /* HAVE_ECC_KOBLITZ */
    392533    #ifdef HAVE_ECC_BRAINPOOL
    393         static const ecc_oid_t ecc_oid_brainpoolp256r1[] = {
    394534        #ifdef HAVE_OID_ENCODING
    395             1,3,36,3,3,2,8,1,1,7
     535            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
     536            #define CODED_BRAINPOOLP256R1_SZ 10
    396537        #else
    397             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07
     538            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
     539            #define CODED_BRAINPOOLP256R1_SZ 9
    398540        #endif
    399         };
     541        #ifndef USE_WINDOWS_API
     542            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
     543        #else
     544            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
     545        #endif
     546        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
    400547    #endif /* HAVE_ECC_BRAINPOOL */
    401548#endif /* ECC256 */
    402549#ifdef ECC320
    403550    #ifdef HAVE_ECC_BRAINPOOL
    404         static const ecc_oid_t ecc_oid_brainpoolp320r1[] = {
    405551        #ifdef HAVE_OID_ENCODING
    406             1,3,36,3,3,2,8,1,1,9
     552            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
     553            #define CODED_BRAINPOOLP320R1_SZ 10
    407554        #else
    408             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09
     555            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
     556            #define CODED_BRAINPOOLP320R1_SZ 9
    409557        #endif
    410         };
     558        #ifndef USE_WINDOWS_API
     559            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
     560        #else
     561            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
     562        #endif
     563        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
    411564    #endif /* HAVE_ECC_BRAINPOOL */
    412565#endif /* ECC320 */
    413566#ifdef ECC384
    414567    #ifndef NO_ECC_SECP
    415         static const ecc_oid_t ecc_oid_secp384r1[] = {
    416568        #ifdef HAVE_OID_ENCODING
    417             1,3,132,0,34
     569            #define CODED_SECP384R1    {1,3,132,0,34}
     570            #define CODED_SECP384R1_SZ 5
    418571        #else
    419             0x2B,0x81,0x04,0x00,0x22
     572            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
     573            #define CODED_SECP384R1_SZ 5
    420574        #endif
    421         };
     575        #ifndef USE_WINDOWS_API
     576            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
     577            #define CODED_SECP384R1_OID ecc_oid_secp384r1
     578        #else
     579                        #define ecc_oid_secp384r1 CODED_SECP384R1
     580        #endif
     581        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
    422582    #endif /* !NO_ECC_SECP */
    423583    #ifdef HAVE_ECC_BRAINPOOL
    424         static const ecc_oid_t ecc_oid_brainpoolp384r1[] = {
    425584        #ifdef HAVE_OID_ENCODING
    426             1,3,36,3,3,2,8,1,1,11
     585            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
     586            #define CODED_BRAINPOOLP384R1_SZ 10
    427587        #else
    428             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B
     588            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
     589            #define CODED_BRAINPOOLP384R1_SZ 9
    429590        #endif
    430         };
     591        #ifndef USE_WINDOWS_API
     592            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
     593        #else
     594            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
     595        #endif
     596        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
    431597    #endif /* HAVE_ECC_BRAINPOOL */
    432598#endif /* ECC384 */
    433599#ifdef ECC512
    434600    #ifdef HAVE_ECC_BRAINPOOL
    435         static const ecc_oid_t ecc_oid_brainpoolp512r1[] = {
    436601        #ifdef HAVE_OID_ENCODING
    437             1,3,36,3,3,2,8,1,1,13
     602            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
     603            #define CODED_BRAINPOOLP512R1_SZ 10
    438604        #else
    439             0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D
     605            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
     606            #define CODED_BRAINPOOLP512R1_SZ 9
    440607        #endif
    441         };
     608        #ifndef USE_WINDOWS_API
     609            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
     610        #else
     611            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
     612        #endif
     613        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
    442614    #endif /* HAVE_ECC_BRAINPOOL */
    443615#endif /* ECC512 */
    444616#ifdef ECC521
    445617    #ifndef NO_ECC_SECP
    446         static const ecc_oid_t ecc_oid_secp521r1[] = {
    447618        #ifdef HAVE_OID_ENCODING
    448             1,3,132,0,35
     619            #define CODED_SECP521R1     {1,3,132,0,35}
     620            #define CODED_SECP521R1_SZ 5
    449621        #else
    450             0x2B,0x81,0x04,0x00,0x23
     622            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
     623            #define CODED_SECP521R1_SZ 5
    451624        #endif
    452         };
     625        #ifndef USE_WINDOWS_API
     626            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
     627        #else
     628            #define ecc_oid_secp521r1 CODED_SECP521R1
     629        #endif
     630        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
    453631    #endif /* !NO_ECC_SECP */
    454632#endif /* ECC521 */
     
    472650        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
    473651        ecc_oid_secp112r1,              /* oid/oidSz  */
    474         sizeof(ecc_oid_secp112r1) / sizeof(ecc_oid_t),
     652        ecc_oid_secp112r1_sz,
    475653        ECC_SECP112R1_OID,              /* oid sum    */
    476654        1,                              /* cofactor   */
     
    489667        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
    490668        ecc_oid_secp112r2,              /* oid/oidSz  */
    491         sizeof(ecc_oid_secp112r2) / sizeof(ecc_oid_t),
     669        ecc_oid_secp112r2_sz,
    492670        ECC_SECP112R2_OID,              /* oid sum    */
    493671        4,                              /* cofactor   */
     
    508686        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
    509687        ecc_oid_secp128r1,                  /* oid/oidSz  */
    510         sizeof(ecc_oid_secp128r1) / sizeof(ecc_oid_t),
     688        ecc_oid_secp128r1_sz,
    511689        ECC_SECP128R1_OID,                  /* oid sum    */
    512690        1,                                  /* cofactor   */
     
    525703        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
    526704        ecc_oid_secp128r2,                  /* oid/oidSz  */
    527         sizeof(ecc_oid_secp128r2) / sizeof(ecc_oid_t),
     705        ecc_oid_secp128r2_sz,
    528706        ECC_SECP128R2_OID,                  /* oid sum    */
    529707        4,                                  /* cofactor   */
     
    544722        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
    545723        ecc_oid_secp160r1,                          /* oid/oidSz  */
    546         sizeof(ecc_oid_secp160r1) / sizeof(ecc_oid_t),
     724        ecc_oid_secp160r1_sz,
    547725        ECC_SECP160R1_OID,                          /* oid sum    */
    548726        1,                                          /* cofactor   */
     
    561739        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
    562740        ecc_oid_secp160r2,                          /* oid/oidSz  */
    563         sizeof(ecc_oid_secp160r2) / sizeof(ecc_oid_t),
     741        ecc_oid_secp160r2_sz,
    564742        ECC_SECP160R2_OID,                          /* oid sum    */
    565743        1,                                          /* cofactor   */
     
    578756        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
    579757        ecc_oid_secp160k1,                          /* oid/oidSz  */
    580         sizeof(ecc_oid_secp160k1) / sizeof(ecc_oid_t),
     758        ecc_oid_secp160k1_sz,
    581759        ECC_SECP160K1_OID,                          /* oid sum    */
    582760        1,                                          /* cofactor   */
     
    595773        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
    596774        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
    597         sizeof(ecc_oid_brainpoolp160r1) / sizeof(ecc_oid_t),
     775        ecc_oid_brainpoolp160r1_sz,
    598776        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
    599777        1,                                          /* cofactor   */
     
    614792        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
    615793        ecc_oid_secp192r1,                                  /* oid/oidSz  */
    616         sizeof(ecc_oid_secp192r1) / sizeof(ecc_oid_t),
     794        ecc_oid_secp192r1_sz,
    617795        ECC_SECP192R1_OID,                                  /* oid sum    */
    618796        1,                                                  /* cofactor   */
     
    631809        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
    632810        ecc_oid_prime192v2,                                 /* oid/oidSz  */
    633         sizeof(ecc_oid_prime192v2) / sizeof(ecc_oid_t),
     811        ecc_oid_prime192v2_sz,
    634812        ECC_PRIME192V2_OID,                                 /* oid sum    */
    635813        1,                                                  /* cofactor   */
     
    648826        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
    649827        ecc_oid_prime192v3,                                 /* oid/oidSz  */
    650         sizeof(ecc_oid_prime192v3) / sizeof(ecc_oid_t),
     828        ecc_oid_prime192v3_sz,
    651829        ECC_PRIME192V3_OID,                                 /* oid sum    */
    652830        1,                                                  /* cofactor   */
     
    665843        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
    666844        ecc_oid_secp192k1,                                  /* oid/oidSz  */
    667         sizeof(ecc_oid_secp192k1) / sizeof(ecc_oid_t),
     845        ecc_oid_secp192k1_sz,
    668846        ECC_SECP192K1_OID,                                  /* oid sum    */
    669847        1,                                                  /* cofactor   */
     
    682860        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
    683861        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
    684         sizeof(ecc_oid_brainpoolp192r1) / sizeof(ecc_oid_t),
     862        ecc_oid_brainpoolp192r1_sz,
    685863        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
    686864        1,                                                  /* cofactor   */
     
    701879        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
    702880        ecc_oid_secp224r1,                                          /* oid/oidSz  */
    703         sizeof(ecc_oid_secp224r1) / sizeof(ecc_oid_t),
     881        ecc_oid_secp224r1_sz,
    704882        ECC_SECP224R1_OID,                                          /* oid sum    */
    705883        1,                                                          /* cofactor   */
     
    718896        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
    719897        ecc_oid_secp224k1,                                          /* oid/oidSz  */
    720         sizeof(ecc_oid_secp224k1) / sizeof(ecc_oid_t),
     898        ecc_oid_secp224k1_sz,
    721899        ECC_SECP224K1_OID,                                          /* oid sum    */
    722900        1,                                                          /* cofactor   */
     
    735913        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
    736914        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
    737         sizeof(ecc_oid_brainpoolp224r1) / sizeof(ecc_oid_t),
     915        ecc_oid_brainpoolp224r1_sz,
    738916        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
    739917        1,                                                          /* cofactor   */
     
    754932        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
    755933        ecc_oid_prime239v1,                                             /* oid/oidSz  */
    756         sizeof(ecc_oid_prime239v1) / sizeof(ecc_oid_t),
     934        ecc_oid_prime239v1_sz,
    757935        ECC_PRIME239V1_OID,                                             /* oid sum    */
    758936        1,                                                              /* cofactor   */
     
    771949        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
    772950        ecc_oid_prime239v2,                                             /* oid/oidSz  */
    773         sizeof(ecc_oid_prime239v2) / sizeof(ecc_oid_t),
     951        ecc_oid_prime239v2_sz,
    774952        ECC_PRIME239V2_OID,                                             /* oid sum    */
    775953        1,                                                              /* cofactor   */
     
    788966        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
    789967        ecc_oid_prime239v3,                                             /* oid/oidSz  */
    790         sizeof(ecc_oid_prime239v3) / sizeof(ecc_oid_t),
     968        ecc_oid_prime239v3_sz,
    791969        ECC_PRIME239V3_OID,                                             /* oid sum    */
    792970        1,                                                              /* cofactor   */
     
    807985        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
    808986        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
    809         sizeof(ecc_oid_secp256r1) / sizeof(ecc_oid_t),
     987        ecc_oid_secp256r1_sz,
    810988        ECC_SECP256R1_OID,                                                  /* oid sum    */
    811989        1,                                                                  /* cofactor   */
     
    8241002        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
    8251003        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
    826         sizeof(ecc_oid_secp256k1) / sizeof(ecc_oid_t),
     1004        ecc_oid_secp256k1_sz,
    8271005        ECC_SECP256K1_OID,                                                  /* oid sum    */
    8281006        1,                                                                  /* cofactor   */
     
    8411019        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
    8421020        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
    843         sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t),
     1021        ecc_oid_brainpoolp256r1_sz,
    8441022        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
    8451023        1,                                                                  /* cofactor   */
     
    8591037        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
    8601038        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
    861         ecc_oid_brainpoolp320r1, sizeof(ecc_oid_brainpoolp320r1) / sizeof(ecc_oid_t),       /* oid/oidSz  */
     1039        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
    8621040        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
    8631041        1,                                                                                  /* cofactor   */
     
    8771055        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
    8781056        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
    879         ecc_oid_secp384r1, sizeof(ecc_oid_secp384r1) / sizeof(ecc_oid_t),                                   /* oid/oidSz  */
     1057        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
    8801058        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
    8811059        1,                                                                                                  /* cofactor   */
     
    8931071        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
    8941072        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
    895         ecc_oid_brainpoolp384r1, sizeof(ecc_oid_brainpoolp384r1) / sizeof(ecc_oid_t),                       /* oid/oidSz  */
     1073        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
    8961074        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
    8971075        1,                                                                                                  /* cofactor   */
     
    9111089        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
    9121090        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
    913         ecc_oid_brainpoolp512r1, sizeof(ecc_oid_brainpoolp512r1) / sizeof(ecc_oid_t),                                                       /* oid/oidSz  */
     1091        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
    9141092        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
    9151093        1,                                                                                                                                  /* cofactor   */
     
    9291107        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
    9301108        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
    931         ecc_oid_secp521r1, sizeof(ecc_oid_secp521r1) / sizeof(ecc_oid_t),                                                                      /* oid/oidSz  */
     1109        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
    9321110        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
    9331111        1,                                                                                                                                     /* cofactor   */
     
    9401118        1, /* non-zero */
    9411119        ECC_CURVE_CUSTOM,
    942         NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    943         NULL, 0, 0, 0
     1120        #ifndef USE_WINDOWS_API
     1121            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     1122        #else
     1123            {0},{0},{0},{0},{0},{0},{0},{0},
     1124        #endif
     1125        0, 0, 0
    9441126    },
    9451127#endif
    9461128{
    947    0, -1,
    948    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    949    NULL, 0, 0, 0
     1129        0,
     1130        ECC_CURVE_INVALID,
     1131        #ifndef USE_WINDOWS_API
     1132            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     1133        #else
     1134            {0},{0},{0},{0},{0},{0},{0},{0},
     1135        #endif
     1136        0, 0, 0
    9501137}
    9511138};
    9521139#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
     1140
    9531141
    9541142#ifdef HAVE_OID_ENCODING
     
    9701158#else
    9711159
     1160#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
    9721161static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
    9731162        mp_int* prime, mp_int* order);
    974 #ifdef ECC_SHAMIR
    975 static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
    976                        ecc_point* C, mp_int* a, mp_int* modulus, void* heap);
    9771163#endif
    9781164
     
    10381224    #endif
    10391225
    1040     #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL;
     1226    #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL
     1227    #define ALLOC_CURVE_SPECS(intcount)
     1228    #define FREE_CURVE_SPECS()
     1229#elif defined(WOLFSSL_SMALL_STACK)
     1230    #define DECLARE_CURVE_SPECS(curve, intcount)                        \
     1231        mp_int* spec_ints = NULL;                                       \
     1232        ecc_curve_spec curve_lcl;                                       \
     1233        ecc_curve_spec* curve = &curve_lcl;                             \
     1234        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
     1235        curve->spec_count = intcount
     1236
     1237    #define ALLOC_CURVE_SPECS(intcount)                                 \
     1238        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
     1239                            DYNAMIC_TYPE_ECC);                          \
     1240        if (spec_ints == NULL)                                          \
     1241            return MEMORY_E;                                            \
     1242        curve->spec_ints = spec_ints
     1243    #define FREE_CURVE_SPECS()                                          \
     1244        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
    10411245#else
    1042     #define DECLARE_CURVE_SPECS(intcount) \
     1246    #define DECLARE_CURVE_SPECS(curve, intcount) \
    10431247        mp_int spec_ints[(intcount)]; \
    10441248        ecc_curve_spec curve_lcl; \
     
    10461250        XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
    10471251        curve->spec_ints = spec_ints; \
    1048         curve->spec_count = intcount;
     1252        curve->spec_count = intcount
     1253    #define ALLOC_CURVE_SPECS(intcount)
     1254    #define FREE_CURVE_SPECS()
    10491255#endif /* ECC_CACHE_CURVE */
    10501256
     
    11001306        curve->load_mask |= mask;
    11011307
    1102         err = mp_read_radix(*dst, src, 16);
     1308        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
    11031309
    11041310    #ifdef HAVE_WOLF_BIGINT
     
    11691375
    11701376    /* determine items to load */
    1171     load_items = (~curve->load_mask & load_mask);
     1377    load_items = (((byte)~(word32)curve->load_mask) & load_mask);
    11721378    curve->load_mask |= load_items;
    11731379
     
    12931499}
    12941500
     1501
     1502#ifdef ALT_ECC_SIZE
     1503static void alt_fp_init(mp_int* a)
     1504{
     1505    a->size = FP_SIZE_ECC;
     1506    mp_zero(a);
     1507}
     1508#endif /* ALT_ECC_SIZE */
     1509
     1510
    12951511#ifndef WOLFSSL_ATECC508A
     1512
     1513#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
    12961514
    12971515/**
     
    13081526                             mp_int* a, mp_int* modulus, mp_digit mp)
    13091527{
    1310    mp_int t1, t2;
     1528#ifndef WOLFSSL_SP_MATH
     1529#ifdef WOLFSSL_SMALL_STACK
     1530   mp_int* t1 = NULL;
     1531   mp_int* t2 = NULL;
    13111532#ifdef ALT_ECC_SIZE
    1312    mp_int rx, ry, rz;
     1533   mp_int* rx = NULL;
     1534   mp_int* ry = NULL;
     1535   mp_int* rz = NULL;
     1536#endif
     1537#else
     1538   mp_int  t1[1], t2[1];
     1539#ifdef ALT_ECC_SIZE
     1540   mp_int  rx[1], ry[1], rz[1];
     1541#endif
    13131542#endif
    13141543   mp_int *x, *y, *z;
     
    13261555   }
    13271556
    1328    if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     1557#ifdef WOLFSSL_SMALL_STACK
     1558#ifdef WOLFSSL_SMALL_STACK_CACHE
     1559   if (R->key != NULL) {
     1560       t1 = R->key->t1;
     1561       t2 = R->key->t2;
     1562#ifdef ALT_ECC_SIZE
     1563       rx = R->key->x;
     1564       ry = R->key->y;
     1565       rz = R->key->z;
     1566#endif
     1567   }
     1568   else
     1569#endif /* WOLFSSL_SMALL_STACK_CACHE */
     1570   {
     1571       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1572       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1573       if (t1 == NULL || t2 == NULL) {
     1574           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1575           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1576           return MEMORY_E;
     1577       }
     1578#ifdef ALT_ECC_SIZE
     1579       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1580       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1581       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1582       if (rx == NULL || ry == NULL || rz == NULL) {
     1583           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1584           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1585           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1586           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1587           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1588           return MEMORY_E;
     1589       }
     1590#endif
     1591   }
     1592#endif /* WOLFSSL_SMALL_STACK */
     1593
     1594   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     1595#ifdef WOLFSSL_SMALL_STACK
     1596   #ifdef WOLFSSL_SMALL_STACK_CACHE
     1597       if (R->key == NULL)
     1598   #endif
     1599       {
     1600       #ifdef ALT_ECC_SIZE
     1601          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1602          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1603          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1604       #endif
     1605          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1606          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1607       }
     1608#endif
    13291609      return err;
    13301610   }
     
    13321612   /* should we dbl instead? */
    13331613   if (err == MP_OKAY)
    1334        err = mp_sub(modulus, Q->y, &t1);
     1614       err = mp_sub(modulus, Q->y, t1);
    13351615   if (err == MP_OKAY) {
    13361616       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
    13371617            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
    1338             (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) {
    1339            mp_clear(&t1);
    1340            mp_clear(&t2);
     1618            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
     1619           mp_clear(t1);
     1620           mp_clear(t2);
     1621    #ifdef WOLFSSL_SMALL_STACK
     1622       #ifdef WOLFSSL_SMALL_STACK_CACHE
     1623           if (R->key == NULL)
     1624       #endif
     1625           {
     1626            #ifdef ALT_ECC_SIZE
     1627               XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1628               XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1629               XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1630            #endif
     1631               XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1632               XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1633           }
     1634        #endif
    13411635          return ecc_projective_dbl_point(P, R, a, modulus, mp);
    13421636       }
     
    13511645#ifdef ALT_ECC_SIZE
    13521646   /* Use local stack variable */
    1353    x = &rx;
    1354    y = &ry;
    1355    z = &rz;
     1647   x = rx;
     1648   y = ry;
     1649   z = rz;
    13561650
    13571651   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
     
    13761670       if (!mp_iszero(Q->z)) {
    13771671           /* T1 = Z' * Z' */
    1378            err = mp_sqr(Q->z, &t1);
     1672           err = mp_sqr(Q->z, t1);
    13791673           if (err == MP_OKAY)
    1380                err = mp_montgomery_reduce(&t1, modulus, mp);
     1674               err = mp_montgomery_reduce(t1, modulus, mp);
    13811675
    13821676           /* X = X * T1 */
    13831677           if (err == MP_OKAY)
    1384                err = mp_mul(&t1, x, x);
     1678               err = mp_mul(t1, x, x);
    13851679           if (err == MP_OKAY)
    13861680               err = mp_montgomery_reduce(x, modulus, mp);
     
    13881682           /* T1 = Z' * T1 */
    13891683           if (err == MP_OKAY)
    1390                err = mp_mul(Q->z, &t1, &t1);
     1684               err = mp_mul(Q->z, t1, t1);
    13911685           if (err == MP_OKAY)
    1392                err = mp_montgomery_reduce(&t1, modulus, mp);
     1686               err = mp_montgomery_reduce(t1, modulus, mp);
    13931687
    13941688           /* Y = Y * T1 */
    13951689           if (err == MP_OKAY)
    1396                err = mp_mul(&t1, y, y);
     1690               err = mp_mul(t1, y, y);
    13971691           if (err == MP_OKAY)
    13981692               err = mp_montgomery_reduce(y, modulus, mp);
     
    14021696   /* T1 = Z*Z */
    14031697   if (err == MP_OKAY)
    1404        err = mp_sqr(z, &t1);
    1405    if (err == MP_OKAY)
    1406        err = mp_montgomery_reduce(&t1, modulus, mp);
     1698       err = mp_sqr(z, t1);
     1699   if (err == MP_OKAY)
     1700       err = mp_montgomery_reduce(t1, modulus, mp);
    14071701
    14081702   /* T2 = X' * T1 */
    14091703   if (err == MP_OKAY)
    1410        err = mp_mul(Q->x, &t1, &t2);
    1411    if (err == MP_OKAY)
    1412        err = mp_montgomery_reduce(&t2, modulus, mp);
     1704       err = mp_mul(Q->x, t1, t2);
     1705   if (err == MP_OKAY)
     1706       err = mp_montgomery_reduce(t2, modulus, mp);
    14131707
    14141708   /* T1 = Z * T1 */
    14151709   if (err == MP_OKAY)
    1416        err = mp_mul(z, &t1, &t1);
    1417    if (err == MP_OKAY)
    1418        err = mp_montgomery_reduce(&t1, modulus, mp);
     1710       err = mp_mul(z, t1, t1);
     1711   if (err == MP_OKAY)
     1712       err = mp_montgomery_reduce(t1, modulus, mp);
    14191713
    14201714   /* T1 = Y' * T1 */
    14211715   if (err == MP_OKAY)
    1422        err = mp_mul(Q->y, &t1, &t1);
    1423    if (err == MP_OKAY)
    1424        err = mp_montgomery_reduce(&t1, modulus, mp);
     1716       err = mp_mul(Q->y, t1, t1);
     1717   if (err == MP_OKAY)
     1718       err = mp_montgomery_reduce(t1, modulus, mp);
    14251719
    14261720   /* Y = Y - T1 */
    14271721   if (err == MP_OKAY)
    1428        err = mp_sub(y, &t1, y);
     1722       err = mp_sub(y, t1, y);
    14291723   if (err == MP_OKAY) {
    14301724       if (mp_isneg(y))
     
    14331727   /* T1 = 2T1 */
    14341728   if (err == MP_OKAY)
    1435        err = mp_add(&t1, &t1, &t1);
     1729       err = mp_add(t1, t1, t1);
    14361730   if (err == MP_OKAY) {
    1437        if (mp_cmp(&t1, modulus) != MP_LT)
    1438            err = mp_sub(&t1, modulus, &t1);
     1731       if (mp_cmp(t1, modulus) != MP_LT)
     1732           err = mp_sub(t1, modulus, t1);
    14391733   }
    14401734   /* T1 = Y + T1 */
    14411735   if (err == MP_OKAY)
    1442        err = mp_add(&t1, y, &t1);
     1736       err = mp_add(t1, y, t1);
    14431737   if (err == MP_OKAY) {
    1444        if (mp_cmp(&t1, modulus) != MP_LT)
    1445            err = mp_sub(&t1, modulus, &t1);
     1738       if (mp_cmp(t1, modulus) != MP_LT)
     1739           err = mp_sub(t1, modulus, t1);
    14461740   }
    14471741   /* X = X - T2 */
    14481742   if (err == MP_OKAY)
    1449        err = mp_sub(x, &t2, x);
     1743       err = mp_sub(x, t2, x);
    14501744   if (err == MP_OKAY) {
    14511745       if (mp_isneg(x))
     
    14541748   /* T2 = 2T2 */
    14551749   if (err == MP_OKAY)
    1456        err = mp_add(&t2, &t2, &t2);
     1750       err = mp_add(t2, t2, t2);
    14571751   if (err == MP_OKAY) {
    1458        if (mp_cmp(&t2, modulus) != MP_LT)
    1459            err = mp_sub(&t2, modulus, &t2);
     1752       if (mp_cmp(t2, modulus) != MP_LT)
     1753           err = mp_sub(t2, modulus, t2);
    14601754   }
    14611755   /* T2 = X + T2 */
    14621756   if (err == MP_OKAY)
    1463        err = mp_add(&t2, x, &t2);
     1757       err = mp_add(t2, x, t2);
    14641758   if (err == MP_OKAY) {
    1465        if (mp_cmp(&t2, modulus) != MP_LT)
    1466            err = mp_sub(&t2, modulus, &t2);
     1759       if (mp_cmp(t2, modulus) != MP_LT)
     1760           err = mp_sub(t2, modulus, t2);
    14671761   }
    14681762
     
    14841778   /* T1 = T1 * X  */
    14851779   if (err == MP_OKAY)
    1486        err = mp_mul(&t1, x, &t1);
    1487    if (err == MP_OKAY)
    1488        err = mp_montgomery_reduce(&t1, modulus, mp);
     1780       err = mp_mul(t1, x, t1);
     1781   if (err == MP_OKAY)
     1782       err = mp_montgomery_reduce(t1, modulus, mp);
    14891783
    14901784   /* X = X * X */
     
    14961790   /* T2 = T2 * x */
    14971791   if (err == MP_OKAY)
    1498        err = mp_mul(&t2, x, &t2);
    1499    if (err == MP_OKAY)
    1500        err = mp_montgomery_reduce(&t2, modulus, mp);
     1792       err = mp_mul(t2, x, t2);
     1793   if (err == MP_OKAY)
     1794       err = mp_montgomery_reduce(t2, modulus, mp);
    15011795
    15021796   /* T1 = T1 * X  */
    15031797   if (err == MP_OKAY)
    1504        err = mp_mul(&t1, x, &t1);
    1505    if (err == MP_OKAY)
    1506        err = mp_montgomery_reduce(&t1, modulus, mp);
     1798       err = mp_mul(t1, x, t1);
     1799   if (err == MP_OKAY)
     1800       err = mp_montgomery_reduce(t1, modulus, mp);
    15071801
    15081802   /* X = Y*Y */
     
    15141808   /* X = X - T2 */
    15151809   if (err == MP_OKAY)
    1516        err = mp_sub(x, &t2, x);
     1810       err = mp_sub(x, t2, x);
    15171811   if (err == MP_OKAY) {
    15181812       if (mp_isneg(x))
     
    15211815   /* T2 = T2 - X */
    15221816   if (err == MP_OKAY)
    1523        err = mp_sub(&t2, x, &t2);
     1817       err = mp_sub(t2, x, t2);
    15241818   if (err == MP_OKAY) {
    1525        if (mp_isneg(&t2))
    1526            err = mp_add(&t2, modulus, &t2);
     1819       if (mp_isneg(t2))
     1820           err = mp_add(t2, modulus, t2);
    15271821   }
    15281822   /* T2 = T2 - X */
    15291823   if (err == MP_OKAY)
    1530        err = mp_sub(&t2, x, &t2);
     1824       err = mp_sub(t2, x, t2);
    15311825   if (err == MP_OKAY) {
    1532        if (mp_isneg(&t2))
    1533            err = mp_add(&t2, modulus, &t2);
     1826       if (mp_isneg(t2))
     1827           err = mp_add(t2, modulus, t2);
    15341828   }
    15351829   /* T2 = T2 * Y */
    15361830   if (err == MP_OKAY)
    1537        err = mp_mul(&t2, y, &t2);
    1538    if (err == MP_OKAY)
    1539        err = mp_montgomery_reduce(&t2, modulus, mp);
     1831       err = mp_mul(t2, y, t2);
     1832   if (err == MP_OKAY)
     1833       err = mp_montgomery_reduce(t2, modulus, mp);
    15401834
    15411835   /* Y = T2 - T1 */
    15421836   if (err == MP_OKAY)
    1543        err = mp_sub(&t2, &t1, y);
     1837       err = mp_sub(t2, t1, y);
    15441838   if (err == MP_OKAY) {
    15451839       if (mp_isneg(y))
     
    15661860
    15671861   /* clean up */
    1568    mp_clear(&t1);
    1569    mp_clear(&t2);
     1862   mp_clear(t1);
     1863   mp_clear(t2);
     1864#ifdef WOLFSSL_SMALL_STACK
     1865#ifdef WOLFSSL_SMALL_STACK_CACHE
     1866   if (R->key == NULL)
     1867#endif
     1868   {
     1869   #ifdef ALT_ECC_SIZE
     1870      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1871      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1872      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1873   #endif
     1874      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1875      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1876   }
     1877#endif
    15701878
    15711879   return err;
     1880#else
     1881    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
     1882        return ECC_BAD_ARG_E;
     1883    }
     1884
     1885    (void)a;
     1886    (void)mp;
     1887
     1888    return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
     1889                                     R->x, R->y, R->z);
     1890#endif
    15721891}
    15731892
     
    16021921                                       mp_int* modulus, mp_digit mp)
    16031922{
    1604    mp_int t1, t2;
     1923#ifndef WOLFSSL_SP_MATH
     1924#ifdef WOLFSSL_SMALL_STACK
     1925   mp_int* t1 = NULL;
     1926   mp_int* t2 = NULL;
    16051927#ifdef ALT_ECC_SIZE
    1606    mp_int rx, ry, rz;
     1928   mp_int* rx = NULL;
     1929   mp_int* ry = NULL;
     1930   mp_int* rz = NULL;
     1931#endif
     1932#else
     1933   mp_int  t1[1], t2[1];
     1934#ifdef ALT_ECC_SIZE
     1935   mp_int  rx[1], ry[1], rz[1];
     1936#endif
    16071937#endif
    16081938   mp_int *x, *y, *z;
     
    16121942       return ECC_BAD_ARG_E;
    16131943
    1614    if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     1944#ifdef WOLFSSL_SMALL_STACK
     1945#ifdef WOLFSSL_SMALL_STACK_CACHE
     1946   if (R->key != NULL) {
     1947       t1 = R->key->t1;
     1948       t2 = R->key->t2;
     1949   #ifdef ALT_ECC_SIZE
     1950       rx = R->key->x;
     1951       ry = R->key->y;
     1952       rz = R->key->z;
     1953   #endif
     1954   }
     1955   else
     1956#endif /* WOLFSSL_SMALL_STACK_CACHE */
     1957   {
     1958       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1959       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1960       if (t1 == NULL || t2 == NULL) {
     1961           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1962           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1963           return MEMORY_E;
     1964       }
     1965    #ifdef ALT_ECC_SIZE
     1966       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1967       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1968       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     1969       if (rx == NULL || ry == NULL || rz == NULL) {
     1970           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1971           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1972           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1973           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1974           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1975           return MEMORY_E;
     1976       }
     1977    #endif
     1978    }
     1979#endif
     1980
     1981   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     1982#ifdef WOLFSSL_SMALL_STACK
     1983#ifdef WOLFSSL_SMALL_STACK_CACHE
     1984    if (R->key == NULL)
     1985#endif
     1986    {
     1987    #ifdef ALT_ECC_SIZE
     1988       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     1989       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     1990       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     1991    #endif
     1992       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     1993       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     1994     }
     1995#endif
    16151996      return err;
    16161997   }
     
    16202001#ifdef ALT_ECC_SIZE
    16212002   /* Use local stack variable */
    1622    x = &rx;
    1623    y = &ry;
    1624    z = &rz;
     2003   x = rx;
     2004   y = ry;
     2005   z = rz;
    16252006
    16262007   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
    1627        mp_clear(&t1);
    1628        mp_clear(&t2);
     2008       mp_clear(t1);
     2009       mp_clear(t2);
     2010    #ifdef WOLFSSL_SMALL_STACK
     2011    #ifdef WOLFSSL_SMALL_STACK_CACHE
     2012       if (R->key == NULL)
     2013    #endif
     2014       {
     2015       #ifdef ALT_ECC_SIZE
     2016          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     2017          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     2018          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     2019       #endif
     2020          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2021          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2022       }
     2023    #endif
    16292024       return err;
    16302025   }
     
    16452040   /* T1 = Z * Z */
    16462041   if (err == MP_OKAY)
    1647        err = mp_sqr(z, &t1);
    1648    if (err == MP_OKAY)
    1649        err = mp_montgomery_reduce(&t1, modulus, mp);
     2042       err = mp_sqr(z, t1);
     2043   if (err == MP_OKAY)
     2044       err = mp_montgomery_reduce(t1, modulus, mp);
    16502045
    16512046   /* Z = Y * Z */
     
    16672062   if (err == MP_OKAY) {
    16682063      /* Use a and prime to determine if a == 3 */
    1669       err = mp_submod(modulus, a, modulus, &t2);
    1670    }
    1671    if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
     2064      err = mp_submod(modulus, a, modulus, t2);
     2065   }
     2066   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
    16722067      /* use "a" in calc */
    16732068
    16742069      /* T2 = T1 * T1 */
    16752070      if (err == MP_OKAY)
    1676           err = mp_sqr(&t1, &t2);
     2071          err = mp_sqr(t1, t2);
    16772072      if (err == MP_OKAY)
    1678           err = mp_montgomery_reduce(&t2, modulus, mp);
     2073          err = mp_montgomery_reduce(t2, modulus, mp);
    16792074      /* T1 = T2 * a */
    16802075      if (err == MP_OKAY)
    1681           err = mp_mulmod(&t2, a, modulus, &t1);
     2076          err = mp_mulmod(t2, a, modulus, t1);
    16822077      /* T2 = X * X */
    16832078      if (err == MP_OKAY)
    1684           err = mp_sqr(x, &t2);
     2079          err = mp_sqr(x, t2);
    16852080      if (err == MP_OKAY)
    1686           err = mp_montgomery_reduce(&t2, modulus, mp);
     2081          err = mp_montgomery_reduce(t2, modulus, mp);
    16872082      /* T1 = T2 + T1 */
    16882083      if (err == MP_OKAY)
    1689           err = mp_add(&t1, &t2, &t1);
     2084          err = mp_add(t1, t2, t1);
    16902085      if (err == MP_OKAY) {
    1691          if (mp_cmp(&t1, modulus) != MP_LT)
    1692             err = mp_sub(&t1, modulus, &t1);
     2086         if (mp_cmp(t1, modulus) != MP_LT)
     2087            err = mp_sub(t1, modulus, t1);
    16932088      }
    16942089      /* T1 = T2 + T1 */
    16952090      if (err == MP_OKAY)
    1696           err = mp_add(&t1, &t2, &t1);
     2091          err = mp_add(t1, t2, t1);
    16972092      if (err == MP_OKAY) {
    1698           if (mp_cmp(&t1, modulus) != MP_LT)
    1699               err = mp_sub(&t1, modulus, &t1);
     2093          if (mp_cmp(t1, modulus) != MP_LT)
     2094              err = mp_sub(t1, modulus, t1);
    17002095      }
    17012096      /* T1 = T2 + T1 */
    17022097      if (err == MP_OKAY)
    1703           err = mp_add(&t1, &t2, &t1);
     2098          err = mp_add(t1, t2, t1);
    17042099      if (err == MP_OKAY) {
    1705          if (mp_cmp(&t1, modulus) != MP_LT)
    1706             err = mp_sub(&t1, modulus, &t1);
     2100         if (mp_cmp(t1, modulus) != MP_LT)
     2101            err = mp_sub(t1, modulus, t1);
    17072102      }
    17082103   }
     
    17152110      /* T2 = X - T1 */
    17162111      if (err == MP_OKAY)
    1717           err = mp_sub(x, &t1, &t2);
     2112          err = mp_sub(x, t1, t2);
    17182113      if (err == MP_OKAY) {
    1719           if (mp_isneg(&t2))
    1720               err = mp_add(&t2, modulus, &t2);
     2114          if (mp_isneg(t2))
     2115              err = mp_add(t2, modulus, t2);
    17212116      }
    17222117      /* T1 = X + T1 */
    17232118      if (err == MP_OKAY)
    1724           err = mp_add(&t1, x, &t1);
     2119          err = mp_add(t1, x, t1);
    17252120      if (err == MP_OKAY) {
    1726           if (mp_cmp(&t1, modulus) != MP_LT)
    1727               err = mp_sub(&t1, modulus, &t1);
     2121          if (mp_cmp(t1, modulus) != MP_LT)
     2122              err = mp_sub(t1, modulus, t1);
    17282123      }
    17292124      /* T2 = T1 * T2 */
    17302125      if (err == MP_OKAY)
    1731           err = mp_mul(&t1, &t2, &t2);
     2126          err = mp_mul(t1, t2, t2);
    17322127      if (err == MP_OKAY)
    1733           err = mp_montgomery_reduce(&t2, modulus, mp);
     2128          err = mp_montgomery_reduce(t2, modulus, mp);
    17342129
    17352130      /* T1 = 2T2 */
    17362131      if (err == MP_OKAY)
    1737           err = mp_add(&t2, &t2, &t1);
     2132          err = mp_add(t2, t2, t1);
    17382133      if (err == MP_OKAY) {
    1739           if (mp_cmp(&t1, modulus) != MP_LT)
    1740               err = mp_sub(&t1, modulus, &t1);
     2134          if (mp_cmp(t1, modulus) != MP_LT)
     2135              err = mp_sub(t1, modulus, t1);
    17412136      }
    17422137      /* T1 = T1 + T2 */
    17432138      if (err == MP_OKAY)
    1744           err = mp_add(&t1, &t2, &t1);
     2139          err = mp_add(t1, t2, t1);
    17452140      if (err == MP_OKAY) {
    1746           if (mp_cmp(&t1, modulus) != MP_LT)
    1747               err = mp_sub(&t1, modulus, &t1);
     2141          if (mp_cmp(t1, modulus) != MP_LT)
     2142              err = mp_sub(t1, modulus, t1);
    17482143      }
    17492144   }
     
    17642159   /* T2 = Y * Y */
    17652160   if (err == MP_OKAY)
    1766        err = mp_sqr(y, &t2);
    1767    if (err == MP_OKAY)
    1768        err = mp_montgomery_reduce(&t2, modulus, mp);
     2161       err = mp_sqr(y, t2);
     2162   if (err == MP_OKAY)
     2163       err = mp_montgomery_reduce(t2, modulus, mp);
    17692164
    17702165   /* T2 = T2/2 */
    17712166   if (err == MP_OKAY) {
    1772        if (mp_isodd(&t2) == MP_YES)
    1773            err = mp_add(&t2, modulus, &t2);
    1774    }
    1775    if (err == MP_OKAY)
    1776        err = mp_div_2(&t2, &t2);
     2167       if (mp_isodd(t2) == MP_YES)
     2168           err = mp_add(t2, modulus, t2);
     2169   }
     2170   if (err == MP_OKAY)
     2171       err = mp_div_2(t2, t2);
    17772172
    17782173   /* Y = Y * X */
     
    17842179   /* X = T1 * T1 */
    17852180   if (err == MP_OKAY)
    1786        err = mp_sqr(&t1, x);
     2181       err = mp_sqr(t1, x);
    17872182   if (err == MP_OKAY)
    17882183       err = mp_montgomery_reduce(x, modulus, mp);
     
    18122207   /* Y = Y * T1 */
    18132208   if (err == MP_OKAY)
    1814        err = mp_mul(y, &t1, y);
     2209       err = mp_mul(y, t1, y);
    18152210   if (err == MP_OKAY)
    18162211       err = mp_montgomery_reduce(y, modulus, mp);
     
    18182213   /* Y = Y - T2 */
    18192214   if (err == MP_OKAY)
    1820        err = mp_sub(y, &t2, y);
     2215       err = mp_sub(y, t2, y);
    18212216   if (err == MP_OKAY) {
    18222217       if (mp_isneg(y))
     
    18342229
    18352230   /* clean up */
    1836    mp_clear(&t1);
    1837    mp_clear(&t2);
     2231   mp_clear(t1);
     2232   mp_clear(t2);
     2233
     2234#ifdef WOLFSSL_SMALL_STACK
     2235#ifdef WOLFSSL_SMALL_STACK_CACHE
     2236   if (R->key == NULL)
     2237#endif
     2238   {
     2239    #ifdef ALT_ECC_SIZE
     2240       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     2241       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     2242       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     2243    #endif
     2244       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2245       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2246    }
     2247#endif
    18382248
    18392249   return err;
     2250#else
     2251    if (P == NULL || R == NULL || modulus == NULL)
     2252        return ECC_BAD_ARG_E;
     2253
     2254    (void)a;
     2255    (void)mp;
     2256
     2257    return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
     2258#endif
    18402259}
    18412260
     
    18502269int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
    18512270{
    1852    mp_int t1, t2;
     2271#ifndef WOLFSSL_SP_MATH
     2272#ifdef WOLFSSL_SMALL_STACK
     2273   mp_int* t1 = NULL;
     2274   mp_int* t2 = NULL;
    18532275#ifdef ALT_ECC_SIZE
    1854    mp_int rx, ry, rz;
    1855 #endif
     2276   mp_int* rx = NULL;
     2277   mp_int* ry = NULL;
     2278   mp_int* rz = NULL;
     2279#endif
     2280#else
     2281   mp_int  t1[1], t2[1];
     2282#ifdef ALT_ECC_SIZE
     2283   mp_int  rx[1], ry[1], rz[1];
     2284#endif
     2285#endif /* WOLFSSL_SMALL_STACK */
    18562286   mp_int *x, *y, *z;
    18572287   int    err;
     
    18702300   }
    18712301
    1872    if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     2302#ifdef WOLFSSL_SMALL_STACK
     2303#ifdef WOLFSSL_SMALL_STACK_CACHE
     2304   if (P->key != NULL) {
     2305       t1 = P->key->t1;
     2306       t2 = P->key->t2;
     2307   #ifdef ALT_ECC_SIZE
     2308       rx = P->key->x;
     2309       ry = P->key->y;
     2310       rz = P->key->z;
     2311   #endif
     2312   }
     2313   else
     2314#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2315   {
     2316       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2317       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2318       if (t1 == NULL || t2 == NULL) {
     2319           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2320           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2321           return MEMORY_E;
     2322       }
     2323#ifdef ALT_ECC_SIZE
     2324       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2325       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2326       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2327       if (rx == NULL || ry == NULL || rz == NULL) {
     2328           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     2329           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     2330           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     2331           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2332           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2333           return MEMORY_E;
     2334       }
     2335#endif
     2336   }
     2337#endif /* WOLFSSL_SMALL_STACK */
     2338
     2339   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     2340#ifdef WOLFSSL_SMALL_STACK
     2341#ifdef WOLFSSL_SMALL_STACK_CACHE
     2342      if (P->key == NULL)
     2343#endif
     2344      {
     2345      #ifdef ALT_ECC_SIZE
     2346         XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     2347         XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     2348         XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     2349      #endif
     2350         XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2351         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2352      }
     2353#endif
    18732354      return MEMORY_E;
    18742355   }
     
    18762357#ifdef ALT_ECC_SIZE
    18772358   /* Use local stack variable */
    1878    x = &rx;
    1879    y = &ry;
    1880    z = &rz;
     2359   x = rx;
     2360   y = ry;
     2361   z = rz;
    18812362
    18822363   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
     
    19062387   /* get 1/z */
    19072388   if (err == MP_OKAY)
    1908        err = mp_invmod(z, modulus, &t1);
     2389       err = mp_invmod(z, modulus, t1);
    19092390
    19102391   /* get 1/z^2 and 1/z^3 */
    19112392   if (err == MP_OKAY)
    1912        err = mp_sqr(&t1, &t2);
    1913    if (err == MP_OKAY)
    1914        err = mp_mod(&t2, modulus, &t2);
    1915    if (err == MP_OKAY)
    1916        err = mp_mul(&t1, &t2, &t1);
    1917    if (err == MP_OKAY)
    1918        err = mp_mod(&t1, modulus, &t1);
     2393       err = mp_sqr(t1, t2);
     2394   if (err == MP_OKAY)
     2395       err = mp_mod(t2, modulus, t2);
     2396   if (err == MP_OKAY)
     2397       err = mp_mul(t1, t2, t1);
     2398   if (err == MP_OKAY)
     2399       err = mp_mod(t1, modulus, t1);
    19192400
    19202401   /* multiply against x/y */
    19212402   if (err == MP_OKAY)
    1922        err = mp_mul(x, &t2, x);
     2403       err = mp_mul(x, t2, x);
    19232404   if (err == MP_OKAY)
    19242405       err = mp_montgomery_reduce(x, modulus, mp);
    19252406   if (err == MP_OKAY)
    1926        err = mp_mul(y, &t1, y);
     2407       err = mp_mul(y, t1, y);
    19272408   if (err == MP_OKAY)
    19282409       err = mp_montgomery_reduce(y, modulus, mp);
     
    19442425
    19452426   /* clean up */
    1946    mp_clear(&t1);
    1947    mp_clear(&t2);
     2427   mp_clear(t1);
     2428   mp_clear(t2);
     2429
     2430#ifdef WOLFSSL_SMALL_STACK
     2431#ifdef WOLFSSL_SMALL_STACK_CACHE
     2432   if (P->key == NULL)
     2433#endif
     2434   {
     2435   #ifdef ALT_ECC_SIZE
     2436      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
     2437      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
     2438      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
     2439   #endif
     2440      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     2441      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     2442}
     2443#endif
    19482444
    19492445   return err;
    1950 }
     2446#else
     2447    if (P == NULL || modulus == NULL)
     2448        return ECC_BAD_ARG_E;
     2449
     2450    (void)mp;
     2451
     2452    return sp_ecc_map_256(P->x, P->y, P->z);
     2453#endif
     2454}
     2455
     2456#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
    19512457
    19522458#if !defined(FREESCALE_LTC_ECC)
    19532459
     2460#if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
    19542461/**
    19552462   Perform a point multiplication
     
    19732480#endif
    19742481{
     2482#ifndef WOLFSSL_SP_MATH
    19752483#ifndef ECC_TIMING_RESISTANT
    19762484   /* size of sliding window, don't change this! */
     
    19842492   ecc_point     *tG, *M[M_POINTS];
    19852493   int           i, err;
    1986    mp_int        mu;
     2494#ifdef WOLFSSL_SMALL_STACK
     2495   mp_int*       mu = NULL;
     2496#ifdef WOLFSSL_SMALL_STACK_CACHE
     2497   ecc_key       key;
     2498#endif
     2499#else
     2500   mp_int        mu[1];
     2501#endif
    19872502   mp_digit      mp;
    19882503   mp_digit      buf;
     
    19962511   tG = NULL;
    19972512   XMEMSET(M, 0, sizeof(M));
     2513#ifdef WOLFSSL_SMALL_STACK
     2514   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2515   if (mu == NULL)
     2516       return MEMORY_E;
     2517#endif
     2518#ifdef WOLFSSL_SMALL_STACK_CACHE
     2519   key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2520   key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2521#ifdef ALT_ECC_SIZE
     2522   key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2523   key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2524   key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2525#endif
     2526   if (key.t1 == NULL || key.t2 == NULL
     2527#ifdef ALT_ECC_SIZE
     2528      || key.x == NULL || key.y == NULL || key.z == NULL
     2529#endif
     2530   ) {
     2531#ifdef ALT_ECC_SIZE
     2532       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     2533       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     2534       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     2535#endif
     2536       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     2537       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     2538       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2539       return MEMORY_E;
     2540   }
     2541#endif /* WOLFSSL_SMALL_STACK_CACHE */
    19982542
    19992543   /* init montgomery reduction */
    20002544   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
     2545#ifdef WOLFSSL_SMALL_STACK_CACHE
     2546#ifdef ALT_ECC_SIZE
     2547       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     2548       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     2549       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     2550#endif
     2551       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     2552       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     2553#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2554#ifdef WOLFSSL_SMALL_STACK
     2555       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2556#endif
    20012557       return err;
    20022558   }
    20032559
    2004    if ((err = mp_init(&mu)) != MP_OKAY) {
     2560   if ((err = mp_init(mu)) != MP_OKAY) {
     2561#ifdef WOLFSSL_SMALL_STACK_CACHE
     2562#ifdef ALT_ECC_SIZE
     2563       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     2564       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     2565       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     2566#endif
     2567       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     2568       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     2569#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2570#ifdef WOLFSSL_SMALL_STACK
     2571       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2572#endif
    20052573       return err;
    20062574   }
    2007    if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) {
    2008        mp_clear(&mu);
     2575   if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {
     2576       mp_clear(mu);
     2577#ifdef WOLFSSL_SMALL_STACK_CACHE
     2578#ifdef ALT_ECC_SIZE
     2579       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     2580       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     2581       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     2582#endif
     2583       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     2584       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     2585#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2586#ifdef WOLFSSL_SMALL_STACK
     2587       XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2588#endif
    20092589       return err;
    20102590   }
     
    20142594      M[i] = wc_ecc_new_point_h(heap);
    20152595      if (M[i] == NULL) {
    2016          mp_clear(&mu);
     2596         mp_clear(mu);
    20172597         err = MEMORY_E; goto exit;
    20182598      }
     2599#ifdef WOLFSSL_SMALL_STACK_CACHE
     2600      M[i]->key = &key;
     2601#endif
    20192602  }
    20202603
     
    20262609   /* tG = G  and convert to montgomery */
    20272610   if (err == MP_OKAY) {
    2028        if (mp_cmp_d(&mu, 1) == MP_EQ) {
     2611       if (mp_cmp_d(mu, 1) == MP_EQ) {
    20292612           err = mp_copy(G->x, tG->x);
    20302613           if (err == MP_OKAY)
     
    20332616               err = mp_copy(G->z, tG->z);
    20342617       } else {
    2035            err = mp_mulmod(G->x, &mu, modulus, tG->x);
     2618           err = mp_mulmod(G->x, mu, modulus, tG->x);
    20362619           if (err == MP_OKAY)
    2037                err = mp_mulmod(G->y, &mu, modulus, tG->y);
     2620               err = mp_mulmod(G->y, mu, modulus, tG->y);
    20382621           if (err == MP_OKAY)
    2039                err = mp_mulmod(G->z, &mu, modulus, tG->z);
     2622               err = mp_mulmod(G->z, mu, modulus, tG->z);
    20402623       }
    20412624   }
    20422625
    20432626   /* done with mu */
    2044    mp_clear(&mu);
    2045 
     2627   mp_clear(mu);
     2628
     2629#ifdef WOLFSSL_SMALL_STACK_CACHE
     2630   R->key = &key;
     2631#endif
    20462632#ifndef ECC_TIMING_RESISTANT
    20472633
     
    23052891       wc_ecc_del_point_h(M[i], heap);
    23062892   }
     2893#ifdef WOLFSSL_SMALL_STACK_CACHE
     2894   R->key = NULL;
     2895#ifdef ALT_ECC_SIZE
     2896   XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     2897   XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     2898   XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     2899#endif
     2900   XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     2901   XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     2902#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2903#ifdef WOLFSSL_SMALL_STACK
     2904   XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2905#endif
    23072906
    23082907   return err;
    2309 }
     2908#else
     2909   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
     2910       return ECC_BAD_ARG_E;
     2911}
     2912
     2913   (void)a;
     2914
     2915   return sp_ecc_mulmod_256(k, G, R, map, heap);
     2916#endif
     2917}
     2918
     2919#endif /* !FP_ECC || !WOLFSSL_SP_MATH */
    23102920
    23112921#endif /* !FREESCALE_LTC_ECC */
     
    23272937}
    23282938
    2329 
    2330 #ifdef ALT_ECC_SIZE
    2331 
    2332 static void alt_fp_init(fp_int* a)
    2333 {
    2334     a->size = FP_SIZE_ECC;
    2335     fp_zero(a);
    2336 }
    2337 
    2338 #endif /* ALT_ECC_SIZE */
    2339 
     2939#endif /* !WOLFSSL_ATECC508A */
    23402940
    23412941/**
     
    23462946{
    23472947   ecc_point* p;
     2948
     2949   (void)heap;
    23482950
    23492951   p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
     
    24553057}
    24563058
    2457 #endif /* !WOLFSSL_ATECC508A */
    2458 
    24593059
    24603060/** Returns whether an ECC idx is valid or not
     
    25883188{
    25893189    int err = MP_OKAY;
    2590     mp_int a, b;
     3190#ifdef WOLFSSL_SMALL_STACK
     3191    mp_int* a = NULL;
     3192    mp_int* b = NULL;
     3193#else
     3194    mp_int  a[1], b[1];
     3195#endif
    25913196
    25923197    if (param == NULL || curveParam == NULL)
    25933198        return BAD_FUNC_ARG;
    25943199
    2595     if ((err = mp_init_multi(&a, &b, NULL, NULL, NULL, NULL)) != MP_OKAY)
     3200#ifdef WOLFSSL_SMALL_STACK
     3201    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     3202    if (a == NULL)
     3203        return MEMORY_E;
     3204    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     3205    if (b == NULL) {
     3206        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
     3207        return MEMORY_E;
     3208    }
     3209#endif
     3210
     3211    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     3212    #ifdef WOLFSSL_SMALL_STACK
     3213        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
     3214        XFREE(b, NULL, DYNAMIC_TYPE_ECC);
     3215    #endif
    25963216        return err;
     3217    }
    25973218
    25983219    if (err == MP_OKAY)
    2599         err = mp_read_unsigned_bin(&a, param, paramSz);
     3220        err = mp_read_unsigned_bin(a, param, paramSz);
    26003221
    26013222    if (err == MP_OKAY)
    2602         err = mp_read_radix(&b, curveParam, 16);
     3223        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
    26033224
    26043225    if (err == MP_OKAY) {
    2605         if (mp_cmp(&a, &b) != MP_EQ) {
     3226        if (mp_cmp(a, b) != MP_EQ) {
    26063227            err = -1;
    26073228        } else {
     
    26103231    }
    26113232
    2612     mp_clear(&a);
    2613     mp_clear(&b);
     3233    mp_clear(a);
     3234    mp_clear(b);
     3235#ifdef WOLFSSL_SMALL_STACK
     3236    XFREE(b, NULL, DYNAMIC_TYPE_ECC);
     3237    XFREE(a, NULL, DYNAMIC_TYPE_ECC);
     3238#endif
    26143239
    26153240    return err;
     
    26723297}
    26733298
     3299/* Returns the curve id that corresponds to a given OID,
     3300 * as listed in ecc_sets[] of ecc.c.
     3301 *
     3302 * oid   OID, from ecc_sets[].name in ecc.c
     3303 * len   OID len, from ecc_sets[].name in ecc.c
     3304 * return curve id, from ecc_sets[] on success, negative on error
     3305 */
     3306int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
     3307{
     3308    int curve_idx;
     3309
     3310    if (oid == NULL)
     3311        return BAD_FUNC_ARG;
     3312
     3313    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
     3314        if (ecc_sets[curve_idx].oid && ecc_sets[curve_idx].oidSz == len &&
     3315                              XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0) {
     3316            break;
     3317        }
     3318    }
     3319    if (ecc_sets[curve_idx].size == 0) {
     3320        WOLFSSL_MSG("ecc_set curve name not found");
     3321        return ECC_CURVE_INVALID;
     3322    }
     3323
     3324    return ecc_sets[curve_idx].id;
     3325}
     3326
     3327
     3328#ifdef WOLFSSL_ASYNC_CRYPT
     3329static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
     3330{
     3331   if (key == NULL || mp == NULL)
     3332      return BAD_FUNC_ARG;
     3333   if (*mp == NULL) {
     3334      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
     3335      if (*mp == NULL) {
     3336         return MEMORY_E;
     3337      }
     3338      XMEMSET(*mp, 0, sizeof(mp_int));
     3339   }
     3340   return 0;
     3341}
     3342static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
     3343{
     3344   if (key && mp && *mp) {
     3345      mp_clear(*mp);
     3346      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
     3347      *mp = NULL;
     3348   }
     3349}
     3350
     3351static int wc_ecc_alloc_async(ecc_key* key)
     3352{
     3353    int err = wc_ecc_alloc_mpint(key, &key->r);
     3354    if (err == 0)
     3355        err = wc_ecc_alloc_mpint(key, &key->s);
     3356    return err;
     3357}
     3358
     3359static void wc_ecc_free_async(ecc_key* key)
     3360{
     3361    wc_ecc_free_mpint(key, &key->r);
     3362    wc_ecc_free_mpint(key, &key->s);
     3363#ifdef HAVE_CAVIUM_V
     3364    wc_ecc_free_mpint(key, &key->e);
     3365    wc_ecc_free_mpint(key, &key->signK);
     3366#endif /* HAVE_CAVIUM_V */
     3367}
     3368#endif /* WOLFSSL_ASYNC_CRYPT */
     3369
    26743370
    26753371#ifdef HAVE_ECC_DHE
     
    26933389   }
    26943390
     3391#ifdef WOLF_CRYPTO_DEV
     3392    if (private_key->devId != INVALID_DEVID) {
     3393        err = wc_CryptoDev_Ecdh(private_key, public_key, out, outlen);
     3394        if (err != NOT_COMPILED_IN)
     3395            return err;
     3396    }
     3397#endif
     3398
    26953399   /* type valid? */
    26963400   if (private_key->type != ECC_PRIVATEKEY &&
     
    27113415
    27123416#ifdef WOLFSSL_ATECC508A
    2713    err = atcatls_ecdh(private_key->slot, public_key->pubkey, out);
    2714    if (err != ATCA_SUCCESS) {
    2715       err = BAD_COND_E;
    2716    }
     3417   /* For SECP256R1 use hardware */
     3418   if (private_key->dp->id == ECC_SECP256R1) {
     3419       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
    27173420   *outlen = private_key->dp->size;
     3421   }
     3422   else {
     3423      err = NOT_COMPILED_IN;
     3424   }
     3425
    27183426#else
     3427
    27193428   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
    27203429#endif /* WOLFSSL_ATECC508A */
     
    27303439{
    27313440    int err;
     3441#ifndef WOLFSSL_SP_MATH
    27323442    ecc_point* result = NULL;
    27333443    word32 x = 0;
     3444#endif
    27343445    mp_int* k = &private_key->k;
    27353446#ifdef HAVE_ECC_CDH
     
    27633474#endif
    27643475#endif
     3476#ifdef WOLFSSL_SP_MATH
     3477    {
     3478        err = WC_KEY_SIZE_E;
     3479
     3480        (void)curve;
     3481    }
     3482#else
    27653483    {
    27663484        /* make new point */
     
    27923510        wc_ecc_del_point_h(result, private_key->heap);
    27933511    }
     3512#endif
    27943513#ifdef HAVE_ECC_CDH
    27953514    if (k == &k_lcl)
     
    28073526    int err;
    28083527
    2809 #ifdef HAVE_CAVIUM
    2810     /* TODO: Not implemented - use software for now */
    2811     err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);
    2812 
    2813 #elif defined(HAVE_INTEL_QA)
     3528#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
     3529#ifdef HAVE_CAVIUM_V
     3530    /* verify the curve is supported by hardware */
     3531    if (NitroxEccIsCurveSupported(private_key))
     3532#endif
     3533    {
     3534        word32 keySz = private_key->dp->size;
     3535
    28143536    /* sync public key x/y */
    2815     err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
     3537        err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);
     3538        if (err == MP_OKAY)
     3539            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
     3540        if (err == MP_OKAY)
     3541            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
     3542    #ifdef HAVE_CAVIUM_V
     3543        /* allocate buffer for output */
    28163544    if (err == MP_OKAY)
    2817         err = wc_mp_to_bigint(&private_key->k, &private_key->k.raw);
     3545            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
    28183546    if (err == MP_OKAY)
    2819         err = wc_mp_to_bigint(point->x, &point->x->raw);
     3547            err = wc_bigint_alloc(&private_key->e->raw,
     3548                NitroxEccGetSize(private_key)*2);
    28203549    if (err == MP_OKAY)
    2821         err = wc_mp_to_bigint(point->y, &point->y->raw);
     3550            err = NitroxEcdh(private_key,
     3551                &private_key->k.raw, &point->x->raw, &point->y->raw,
     3552                private_key->e->raw.buf, &private_key->e->raw.len,
     3553                &curve->prime->raw);
     3554    #else
     3555        if (err == MP_OKAY)
     3556            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
    28223557    if (err == MP_OKAY)
    28233558        err = IntelQaEcdh(&private_key->asyncDev,
     
    28263561            &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
    28273562            private_key->dp->cofactor);
    2828 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
     3563    #endif
     3564        return err;
     3565    }
     3566#elif defined(WOLFSSL_ASYNC_CRYPT_TEST)
    28293567    if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {
    28303568        WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;
     
    28353573        return WC_PENDING_E;
    28363574    }
     3575#endif
     3576
     3577    /* use sync in other cases */
    28373578    err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);
    2838 #endif
    28393579
    28403580    return err;
     
    28463586{
    28473587    int err;
    2848     DECLARE_CURVE_SPECS(2)
     3588    DECLARE_CURVE_SPECS(curve, 2);
    28493589
    28503590    if (private_key == NULL || point == NULL || out == NULL ||
     
    28533593    }
    28543594
     3595    ALLOC_CURVE_SPECS(2);
     3596
    28553597    /* load curve info */
    28563598    err = wc_ecc_curve_load(private_key->dp, &curve,
    28573599        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
    2858     if (err != MP_OKAY)
     3600    if (err != MP_OKAY) {
     3601        FREE_CURVE_SPECS();
    28593602        return err;
     3603    }
    28603604
    28613605#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     
    28723616
    28733617    wc_ecc_curve_free(curve);
     3618    FREE_CURVE_SPECS();
    28743619
    28753620    return err;
     
    29183663        case ECC_STATE_SHARED_SEC_RES:
    29193664            private_key->state = ECC_STATE_SHARED_SEC_RES;
     3665        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     3666            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
     3667            #ifdef HAVE_CAVIUM_V
     3668                /* verify the curve is supported by hardware */
     3669                if (NitroxEccIsCurveSupported(private_key)) {
     3670                    /* copy output */
     3671                    *outlen = private_key->dp->size;
     3672                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
     3673                }
     3674            #endif /* HAVE_CAVIUM_V */
     3675            }
     3676        #endif /* WOLFSSL_ASYNC_CRYPT */
    29203677            err = 0;
    29213678            break;
     
    29313688    }
    29323689
     3690    /* cleanup */
     3691#ifdef WOLFSSL_ASYNC_CRYPT
     3692    wc_ecc_free_async(private_key);
     3693#endif
    29333694    private_key->state = ECC_STATE_NONE;
    29343695
     
    29523713}
    29533714
     3715#ifndef WOLFSSL_SP_MATH
    29543716/* generate random and ensure its greater than 0 and less than order */
    29553717static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
    29563718{
     3719#ifndef WC_NO_RNG
    29573720    int err;
    2958 #ifdef WOLFSSL_SMALL_STACK
    2959     byte* buf;
     3721#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     3722    DECLARE_VAR(buf, byte, ECC_MAXSIZE_GEN, rng->heap);
    29603723#else
    29613724    byte  buf[ECC_MAXSIZE_GEN];
    2962 #endif
    2963 
    2964 #ifdef WOLFSSL_SMALL_STACK
    2965     buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_ECC_BUFFER);
    2966     if (buf == NULL)
    2967         return MEMORY_E;
    29683725#endif
    29693726
     
    29783735    if (err == 0)
    29793736        err = mp_read_unsigned_bin(k, (byte*)buf, size);
    2980 
    2981     /* quick sanity check to make sure we're not dealing with a 0 key */
    2982     if (err == MP_OKAY) {
    2983         if (mp_iszero(k) == MP_YES)
    2984           err = MP_ZERO_E;
    2985     }
    29863737
    29873738    /* the key should be smaller than the order of base point */
     
    29923743    }
    29933744
     3745    /* quick sanity check to make sure we're not dealing with a 0 key */
     3746    if (err == MP_OKAY) {
     3747        if (mp_iszero(k) == MP_YES)
     3748          err = MP_ZERO_E;
     3749    }
     3750
    29943751    ForceZero(buf, ECC_MAXSIZE);
    2995 #ifdef WOLFSSL_SMALL_STACK
    2996     XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     3752#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     3753    FREE_VAR(buf, rng->heap);
    29973754#endif
    29983755
    29993756    return err;
    3000 }
     3757#else
     3758    (void)rng;
     3759    (void)size;
     3760    (void)k;
     3761    (void)order;
     3762    return NOT_COMPILED_IN;
     3763#endif /* !WC_NO_RNG */
     3764}
     3765#endif /* WOLFSSL_SP_MATH */
    30013766#endif /* !WOLFSSL_ATECC508A */
    30023767
    3003 static INLINE void wc_ecc_reset(ecc_key* key)
     3768static WC_INLINE void wc_ecc_reset(ecc_key* key)
    30043769{
    30053770    /* make sure required key variables are reset */
     
    30263791    int err = MP_OKAY;
    30273792#ifndef WOLFSSL_ATECC508A
     3793#ifndef WOLFSSL_SP_MATH
    30283794    ecc_point* base = NULL;
     3795#endif
    30293796    ecc_point* pub;
    3030     DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
    3031 #endif
     3797    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
     3798#endif /* !WOLFSSL_ATECC508A */
    30323799
    30333800    if (key == NULL) {
     
    30363803
    30373804#ifndef WOLFSSL_ATECC508A
     3805
    30383806    /* if ecc_point passed in then use it as output for public key point */
    30393807    if (pubOut != NULL) {
     
    30523820    }
    30533821    else {
     3822        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
     3823
    30543824        /* load curve info */
    30553825        if (err == MP_OKAY)
     
    30803850#endif
    30813851#endif
     3852#ifdef WOLFSSL_SP_MATH
     3853        err = WC_KEY_SIZE_E;
     3854#else
    30823855    {
    30833856        if (err == MP_OKAY) {
     
    31023875        wc_ecc_del_point_h(base, key->heap);
    31033876    }
     3877#endif
    31043878
    31053879#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
     
    31223896    if (curveIn == NULL) {
    31233897        wc_ecc_curve_free(curve);
    3124     }
    3125 
     3898        FREE_CURVE_SPECS();
     3899    }
     3900
     3901#else
     3902    (void)curveIn;
    31263903#endif /* WOLFSSL_ATECC508A */
    31273904
     
    31563933    int            err;
    31573934#ifndef WOLFSSL_ATECC508A
    3158     DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
    3159 #endif
     3935#ifndef WOLFSSL_SP_MATH
     3936    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
     3937#endif
     3938#endif /* !WOLFSSL_ATECC508A */
    31603939
    31613940    if (key == NULL || rng == NULL) {
     
    31703949        return err;
    31713950    }
     3951
     3952#ifdef WOLF_CRYPTO_DEV
     3953    if (key->devId != INVALID_DEVID) {
     3954        err = wc_CryptoDev_MakeEccKey(rng, keysize, key, curve_id);
     3955        if (err != NOT_COMPILED_IN)
     3956            return err;
     3957    }
     3958#endif
    31723959
    31733960#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     
    31883975    #endif
    31893976    }
    3190 #endif /* WOLFSSL_ASYNC_CRYPT */
     3977#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
    31913978
    31923979#ifdef WOLFSSL_ATECC508A
    31933980    key->type = ECC_PRIVATEKEY;
    3194     err = atcatls_create_key(key->slot, key->pubkey);
    3195     if (err != ATCA_SUCCESS)
    3196         err = BAD_COND_E;
     3981   key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
     3982   err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
     3983
     3984   /* populate key->pubkey */
     3985   if (err == 0 && key->pubkey.x) {
     3986       err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
     3987                                  ECC_MAX_CRYPTO_HW_SIZE);
     3988   }
     3989   if (err == 0 && key->pubkey.y) {
     3990       err = mp_read_unsigned_bin(key->pubkey.y,
     3991                                  key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
     3992                                  ECC_MAX_CRYPTO_HW_SIZE);
     3993   }
    31973994#else
    31983995
     
    32064003    else
    32074004#endif
    3208 #endif
    3209     {
     4005#endif /* WOLFSSL_HAVE_SP_ECC */
     4006
     4007   { /* software key gen */
     4008#ifdef WOLFSSL_SP_MATH
     4009        err = WC_KEY_SIZE_E;
     4010#else
     4011        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
     4012
    32104013        /* setup the key variables */
    32114014        err = mp_init(&key->k);
     
    32344037        /* cleanup allocations */
    32354038        wc_ecc_curve_free(curve);
    3236     }
     4039        FREE_CURVE_SPECS();
     4040#endif /* WOLFSSL_SP_MATH */
     4041    }
     4042
     4043#ifdef HAVE_WOLF_BIGINT
     4044    if (err == MP_OKAY)
     4045         err = wc_mp_to_bigint(&key->k, &key->k.raw);
     4046    if (err == MP_OKAY)
     4047         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
     4048    if (err == MP_OKAY)
     4049         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
     4050    if (err == MP_OKAY)
     4051         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
     4052#endif
    32374053
    32384054#endif /* WOLFSSL_ATECC508A */
     
    33114127}
    33124128
    3313 static INLINE int wc_ecc_alloc_rs(ecc_key* key, mp_int** r, mp_int** s)
    3314 {
    3315     int err = 0;
    3316 
    3317 #ifndef WOLFSSL_ASYNC_CRYPT
    3318     (void)key;
    3319 #endif
    3320 
    3321     if (*r == NULL) {
    3322     #ifdef WOLFSSL_ASYNC_CRYPT
    3323         *r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
    3324         if (*r == NULL) {
    3325             return MEMORY_E;
    3326         }
    3327         key->r = *r;
    3328     #endif
    3329     }
    3330     if (*s == NULL) {
    3331     #ifdef WOLFSSL_ASYNC_CRYPT
    3332         *s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
    3333         if (*s == NULL) {
    3334             XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT);
    3335             return MEMORY_E;
    3336         }
    3337         key->s = *s;
    3338     #endif
    3339     }
    3340 
    3341     /* initialize mp_int */
    3342     if (*r)
    3343         XMEMSET(*r, 0, sizeof(mp_int));
    3344     if (*s)
    3345         XMEMSET(*s, 0, sizeof(mp_int));
    3346 
    3347     return err;
    3348 }
    3349 
    3350 static INLINE void wc_ecc_free_rs(ecc_key* key, mp_int** r, mp_int** s)
    3351 {
    3352     if (*r) {
    3353         mp_clear(*r);
    3354 
    3355     #ifdef WOLFSSL_ASYNC_CRYPT
    3356         XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT);
    3357         key->r = NULL;
    3358     #endif
    3359         *r = NULL;
    3360     }
    3361     if (*s) {
    3362         mp_clear(*s);
    3363 
    3364     #ifdef WOLFSSL_ASYNC_CRYPT
    3365         XFREE(*s, key->heap, DYNAMIC_TYPE_BIGINT);
    3366         key->s = NULL;
    3367     #endif
    3368         *s = NULL;
    3369     }
    3370     (void)key;
    3371 }
    3372 
    33734129/* Setup dynamic pointers if using normal math for proper freeing */
    33744130int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
     
    33874143    key->state = ECC_STATE_NONE;
    33884144
     4145#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV)
     4146    key->devId = devId;
     4147#else
     4148    (void)devId;
     4149#endif
     4150
    33894151#ifdef WOLFSSL_ATECC508A
    3390     key->slot = atmel_ecc_alloc();
    3391     if (key->slot == ATECC_INVALID_SLOT) {
    3392         return ECC_BAD_ARG_E;
    3393     }
     4152    key->slot = ATECC_INVALID_SLOT;
    33944153#else
    33954154#ifdef ALT_ECC_SIZE
     
    34204179    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
    34214180                                                            key->heap, devId);
    3422 #else
    3423     (void)devId;
    34244181#endif
    34254182
     
    34314188    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
    34324189}
     4190
     4191#ifdef HAVE_PKCS11
     4192int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
     4193                   int devId)
     4194{
     4195    int ret = 0;
     4196
     4197    if (key == NULL)
     4198        ret = BAD_FUNC_ARG;
     4199    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
     4200        ret = BUFFER_E;
     4201
     4202    if (ret == 0)
     4203        ret = wc_ecc_init_ex(key, heap, devId);
     4204
     4205    if (ret == 0 && id != NULL && len != 0) {
     4206        XMEMCPY(key->id, id, len);
     4207        key->idLen = len;
     4208    }
     4209
     4210    return ret;
     4211}
     4212#endif
    34334213
    34344214int wc_ecc_set_flags(ecc_key* key, word32 flags)
     
    34444224
    34454225#ifndef NO_ASN
     4226
     4227#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
     4228static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
     4229    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
     4230    ecc_key* key)
     4231{
     4232    int err;
     4233
     4234#ifdef PLUTON_CRYPTO_ECC
     4235    if (key->devId != INVALID_DEVID) /* use hardware */
     4236#endif
     4237    {
     4238        word32 keysize = (word32)key->dp->size;
     4239
     4240        /* Check args */
     4241        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || inlen != keysize ||
     4242                                                *outlen < keysize*2) {
     4243            return ECC_BAD_ARG_E;
     4244        }
     4245
     4246    #if defined(WOLFSSL_ATECC508A)
     4247        key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
     4248        if (key->slot == ATECC_INVALID_SLOT) {
     4249            return ECC_BAD_ARG_E;
     4250        }
     4251
     4252        /* Sign: Result is 32-bytes of R then 32-bytes of S */
     4253        err = atmel_ecc_sign(key->slot, in, out);
     4254        if (err != 0) {
     4255           return err;
     4256        }
     4257    #elif defined(PLUTON_CRYPTO_ECC)
     4258        {
     4259            /* perform ECC sign */
     4260            word32 raw_sig_size = *outlen;
     4261            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
     4262            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
     4263               return BAD_COND_E;
     4264            }
     4265        }
     4266    #endif
     4267
     4268        /* Load R and S */
     4269        err = mp_read_unsigned_bin(r, &out[0], keysize);
     4270        if (err != MP_OKAY) {
     4271            return err;
     4272        }
     4273        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
     4274        if (err != MP_OKAY) {
     4275            return err;
     4276        }
     4277
     4278        /* Check for zeros */
     4279        if (mp_iszero(r) || mp_iszero(s)) {
     4280            return MP_ZERO_E;
     4281        }
     4282    }
     4283#ifdef PLUTON_CRYPTO_ECC
     4284    else {
     4285        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
     4286    }
     4287#endif
     4288    (void)rng;
     4289
     4290    return err;
     4291}
     4292#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */
     4293
    34464294/**
    34474295 Sign a message digest
     
    34584306    int err;
    34594307    mp_int *r = NULL, *s = NULL;
    3460 #ifndef WOLFSSL_ASYNC_CRYPT
     4308#if !defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_SMALL_STACK)
    34614309    mp_int r_lcl, s_lcl;
    3462     r = &r_lcl;
    3463     s = &s_lcl;
    34644310#endif
    34654311
     
    34684314        return ECC_BAD_ARG_E;
    34694315    }
     4316
     4317#ifdef WOLF_CRYPTO_DEV
     4318    if (key->devId != INVALID_DEVID) {
     4319        err = wc_CryptoDev_EccSign(in, inlen, out, outlen, rng, key);
     4320        if (err != NOT_COMPILED_IN)
     4321            return err;
     4322    }
     4323#endif
     4324
     4325#ifdef WOLFSSL_ASYNC_CRYPT
     4326    err = wc_ecc_alloc_async(key);
     4327    if (err != 0)
     4328        return err;
     4329    r = key->r;
     4330    s = key->s;
     4331#elif !defined(WOLFSSL_SMALL_STACK)
     4332    r = &r_lcl;
     4333    s = &s_lcl;
     4334#else
     4335    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     4336    if (r == NULL)
     4337        return MEMORY_E;
     4338    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     4339    if (s == NULL) {
     4340        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
     4341        return MEMORY_E;
     4342    }
     4343#endif
    34704344
    34714345    switch(key->state) {
     
    34744348            key->state = ECC_STATE_SIGN_DO;
    34754349
    3476             err = wc_ecc_alloc_rs(key, &r, &s);
    3477             if (err != 0)
    3478                 break;
    3479 
    34804350            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
    34814351                break;
    34824352            }
    34834353
    3484         #ifdef WOLFSSL_ATECC508A
    3485             /* Check args */
    3486             if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) {
    3487                 return ECC_BAD_ARG_E;
    3488             }
    3489 
    3490             /* Sign: Result is 32-bytes of R then 32-bytes of S */
    3491             err = atcatls_sign(key->slot, in, out);
    3492             if (err != ATCA_SUCCESS) {
    3493                return BAD_COND_E;
    3494            }
    3495 
    3496             /* Load R and S */
    3497             err = mp_read_unsigned_bin(r, &out[0], ATECC_KEY_SIZE);
    3498             if (err != MP_OKAY) {
    3499                 return err;
    3500             }
    3501             err = mp_read_unsigned_bin(s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE);
    3502             if (err != MP_OKAY) {
    3503                 return err;
    3504             }
    3505 
    3506             /* Check for zeros */
    3507             if (mp_iszero(r) || mp_iszero(s)) {
    3508                 return MP_ZERO_E;
    3509             }
    3510 
     4354        /* hardware crypto */
     4355        #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
     4356            err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
    35114357        #else
    3512 
    35134358            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
     4359        #endif
    35144360            if (err < 0) {
    35154361                break;
    35164362            }
    35174363
    3518         #endif /* WOLFSSL_ATECC508A */
    35194364            FALL_THROUGH;
    35204365
     
    35234368
    35244369        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
    3525             /* restore r/s */
    3526             r = key->r;
    3527             s = key->s;
    3528 
    35294370            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
    3530                 /* only do this if not simulator, since it overwrites result */
     4371                #ifdef HAVE_CAVIUM_V
     4372                    /* Nitrox requires r and s in sep buffer, so split it */
     4373                    NitroxEccRsSplit(key, &r->raw, &s->raw);
     4374                #endif
    35314375                #ifndef WOLFSSL_ASYNC_CRYPT_TEST
     4376                    /* only do this if not simulator, since it overwrites result */
    35324377                    wc_bigint_to_mp(&r->raw, r);
    35334378                    wc_bigint_to_mp(&s->raw, s);
     
    35394384            err = StoreECC_DSA_Sig(out, outlen, r, s);
    35404385
    3541             /* always free r/s */
     4386            /* done with R/S */
    35424387            mp_clear(r);
    35434388            mp_clear(s);
     4389        #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK)
     4390            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
     4391            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
     4392        #endif
    35444393            break;
    35454394
    35464395        default:
    35474396            err = BAD_STATE_E;
     4397            break;
    35484398    }
    35494399
     
    35554405
    35564406    /* cleanup */
    3557     wc_ecc_free_rs(key, &r, &s);
     4407#ifdef WOLFSSL_ASYNC_CRYPT
     4408    wc_ecc_free_async(key);
     4409#endif
    35584410    key->state = ECC_STATE_NONE;
    35594411
     
    35764428{
    35774429   int    err;
    3578    mp_int e;
    3579    DECLARE_CURVE_SPECS(1)
     4430#ifndef WOLFSSL_SP_MATH
     4431   mp_int* e;
     4432#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
     4433                                                   !defined(WOLFSSL_SMALL_STACK)
     4434   mp_int  e_lcl;
     4435#endif
     4436   DECLARE_CURVE_SPECS(curve, 1);
     4437#endif /* !WOLFSSL_SP_MATH */
    35804438
    35814439   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
     
    35924450   }
    35934451
     4452#ifdef WOLFSSL_SP_MATH
     4453    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
     4454        return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
     4455    else
     4456        return WC_KEY_SIZE_E;
     4457#else
    35944458#ifdef WOLFSSL_HAVE_SP_ECC
    35954459    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
     
    36034467#endif
    36044468    }
    3605 #endif
     4469#endif /* WOLFSSL_HAVE_SP_ECC */
     4470
    36064471
    36074472#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
     
    36214486#endif
    36224487
     4488   ALLOC_CURVE_SPECS(1);
     4489
     4490#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
     4491   err = wc_ecc_alloc_mpint(key, &key->e);
     4492   if (err != 0) {
     4493      FREE_CURVE_SPECS();
     4494      return err;
     4495   }
     4496   e = key->e;
     4497#elif !defined(WOLFSSL_SMALL_STACK)
     4498   e = &e_lcl;
     4499#else
     4500   e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     4501   if (e == NULL) {
     4502      FREE_CURVE_SPECS();
     4503      return MEMORY_E;
     4504   }
     4505#endif
     4506
    36234507   /* get the hash and load it as a bignum into 'e' */
    36244508   /* init the bignums */
    3625    if ((err = mp_init(&e)) != MP_OKAY) {
     4509   if ((err = mp_init(e)) != MP_OKAY) {
     4510   #ifdef WOLFSSL_SMALL_STACK
     4511      XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
     4512   #endif
     4513      FREE_CURVE_SPECS();
    36264514      return err;
    36274515   }
     
    36384526       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
    36394527           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
    3640        err = mp_read_unsigned_bin(&e, (byte*)in, inlen);
     4528       err = mp_read_unsigned_bin(e, (byte*)in, inlen);
    36414529
    36424530       /* may still need bit truncation too */
    36434531       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
    3644            mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
     4532           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
    36454533   }
    36464534
     
    36484536   if (err == MP_OKAY) {
    36494537       int loop_check = 0;
    3650        ecc_key pubkey;
     4538   #ifdef WOLFSSL_SMALL_STACK
     4539       ecc_key* pubkey = NULL;
     4540   #else
     4541       ecc_key  pubkey[1];
     4542   #endif
    36514543
    36524544   #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
    36534545        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
    3654         #ifdef HAVE_CAVIUM
    3655             /* TODO: Not implemented */
    3656         #elif defined(HAVE_INTEL_QA)
    3657            mp_int k;
    3658 
    3659            err = mp_init(&k);
     4546        #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
     4547        #ifdef HAVE_CAVIUM_V
     4548            if (NitroxEccIsCurveSupported(key))
     4549        #endif
     4550            {
     4551               word32 keySz = key->dp->size;
     4552               mp_int* k;
     4553            #ifdef HAVE_CAVIUM_V
     4554               err = wc_ecc_alloc_mpint(key, &key->signK);
     4555               if (err != 0)
     4556                  return err;
     4557               k = key->signK;
     4558            #else
     4559               mp_int k_lcl;
     4560               k = &k_lcl;
     4561            #endif
     4562
     4563               err = mp_init(k);
     4564
    36604565           /* make sure r and s are allocated */
     4566           #ifdef HAVE_CAVIUM_V
     4567               /* Nitrox V needs single buffer for R and S */
     4568               if (err == MP_OKAY)
     4569                   err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
     4570               /* Nitrox V only needs Prime and Order */
     4571               if (err == MP_OKAY)
     4572                   err = wc_ecc_curve_load(key->dp, &curve,
     4573                        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
     4574           #else
    36614575           if (err == MP_OKAY)
    36624576               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
    36634577           if (err == MP_OKAY)
     4578                   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
     4579           #endif
     4580               if (err == MP_OKAY)
    36644581               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
     4582
    36654583           /* load e and k */
    36664584           if (err == MP_OKAY)
    3667                err = wc_mp_to_bigint(&e, &e.raw);
     4585                   err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
    36684586           if (err == MP_OKAY)
    3669                err = wc_mp_to_bigint(&key->k, &key->k.raw);
     4587                   err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
    36704588           if (err == MP_OKAY)
    3671                err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
     4589                   err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
    36724590           if (err == MP_OKAY)
    3673                err = wc_ecc_gen_k(rng, key->dp->size, &k, curve->order);
     4591                   err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
     4592
     4593           #ifdef HAVE_CAVIUM_V
    36744594           if (err == MP_OKAY)
    3675                err = wc_mp_to_bigint(&k, &k.raw);
     4595                   err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,
     4596                    &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
     4597           #else
    36764598           if (err == MP_OKAY)
    3677                err = IntelQaEcdsaSign(&key->asyncDev, &e.raw, &key->k.raw,
    3678                   &k.raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
     4599                   err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,
     4600                      &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
    36794601                  &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
    36804602                  &curve->Gy->raw);
    3681 
    3682            mp_clear(&e);
    3683            mp_clear(&k);
     4603           #endif
     4604
     4605           #ifndef HAVE_CAVIUM_V
     4606               mp_clear(e);
     4607               mp_clear(k);
     4608           #endif
    36844609           wc_ecc_curve_free(curve);
     4610               FREE_CURVE_SPECS();
    36854611
    36864612           return err;
    3687        #endif
     4613           }
     4614       #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
    36884615       }
    36894616   #endif /* WOLFSSL_ASYNC_CRYPT */
    36904617
     4618   #ifdef WOLFSSL_SMALL_STACK
     4619       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
     4620       if (pubkey == NULL)
     4621           err = MEMORY_E;
     4622   #endif
     4623
    36914624       /* don't use async for key, since we don't support async return here */
    3692        if (wc_ecc_init_ex(&pubkey, key->heap, INVALID_DEVID) == MP_OKAY) {
     4625       if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap,
     4626                                                   INVALID_DEVID)) == MP_OKAY) {
     4627       #ifdef WOLFSSL_SMALL_STACK
     4628           mp_int* b = NULL;
     4629       #else
     4630           mp_int  b[1];
     4631       #endif
     4632
     4633       #ifdef WOLFSSL_SMALL_STACK
     4634           if (err == MP_OKAY) {
     4635               b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
     4636                                                              DYNAMIC_TYPE_ECC);
     4637               if (b == NULL)
     4638                   err = MEMORY_E;
     4639           }
     4640       #endif
     4641
     4642           if (err == MP_OKAY) {
     4643               err = mp_init(b);
     4644           }
     4645
    36934646       #ifdef WOLFSSL_CUSTOM_CURVES
    36944647           /* if custom curve, apply params to pubkey */
    3695            if (key->idx == ECC_CUSTOM_IDX) {
    3696                wc_ecc_set_custom_curve(&pubkey, key->dp);
     4648           if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
     4649               err = wc_ecc_set_custom_curve(pubkey, key->dp);
    36974650           }
    36984651       #endif
    36994652
    3700            for (;;) {
     4653           if (err == MP_OKAY) {
     4654               /* Generate blinding value - non-zero value. */
     4655               do {
     4656                   if (++loop_check > 64) {
     4657                        err = RNG_FAILURE_E;
     4658                        break;
     4659                   }
     4660
     4661                   err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
     4662               }
     4663               while (err == MP_ZERO_E);
     4664               loop_check = 0;
     4665           }
     4666
     4667           for (; err == MP_OKAY;) {
    37014668               if (++loop_check > 64) {
    37024669                    err = RNG_FAILURE_E;
    37034670                    break;
    37044671               }
    3705                err = wc_ecc_make_key_ex(rng, key->dp->size, &pubkey,
     4672               err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
    37064673                                                              key->dp->id);
    37074674               if (err != MP_OKAY) break;
    37084675
    37094676               /* find r = x1 mod n */
    3710                err = mp_mod(pubkey.pubkey.x, curve->order, r);
     4677               err = mp_mod(pubkey->pubkey.x, curve->order, r);
    37114678               if (err != MP_OKAY) break;
    37124679
    37134680               if (mp_iszero(r) == MP_YES) {
    37144681                #ifndef ALT_ECC_SIZE
    3715                    mp_clear(pubkey.pubkey.x);
    3716                    mp_clear(pubkey.pubkey.y);
    3717                    mp_clear(pubkey.pubkey.z);
     4682                   mp_clear(pubkey->pubkey.x);
     4683                   mp_clear(pubkey->pubkey.y);
     4684                   mp_clear(pubkey->pubkey.z);
    37184685                #endif
    3719                    mp_forcezero(&pubkey.k);
     4686                   mp_forcezero(&pubkey->k);
    37204687               }
    37214688               else {
    3722                    /* find s = (e + xr)/k */
    3723                    err = mp_invmod(&pubkey.k, curve->order, &pubkey.k);
     4689                   /* find s = (e + xr)/k
     4690                             = b.(e/k.b + x.r/k.b) */
     4691
     4692                   /* k = k.b */
     4693                   err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);
    37244694                   if (err != MP_OKAY) break;
    37254695
    3726                    /* s = xr */
     4696                   /* k = 1/k.b */
     4697                   err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);
     4698                   if (err != MP_OKAY) break;
     4699
     4700                   /* s = x.r */
    37274701                   err = mp_mulmod(&key->k, r, curve->order, s);
    37284702                   if (err != MP_OKAY) break;
    37294703
    3730                    /* s = e +  xr */
    3731                    err = mp_add(&e, s, s);
     4704                   /* s = x.r/k.b */
     4705                   err = mp_mulmod(&pubkey->k, s, curve->order, s);
    37324706                   if (err != MP_OKAY) break;
    37334707
    3734                    /* s = e +  xr */
     4708                   /* e = e/k.b */
     4709                   err = mp_mulmod(&pubkey->k, e, curve->order, e);
     4710                   if (err != MP_OKAY) break;
     4711
     4712                   /* s = e/k.b + x.r/k.b
     4713                        = (e + x.r)/k.b */
     4714                   err = mp_add(e, s, s);
     4715                   if (err != MP_OKAY) break;
     4716
     4717                   /* s = b.(e + x.r)/k.b
     4718                        = (e + x.r)/k */
     4719                   err = mp_mulmod(s, b, curve->order, s);
     4720                   if (err != MP_OKAY) break;
     4721
     4722                   /* s = (e + xr)/k */
    37354723                   err = mp_mod(s, curve->order, s);
    37364724                   if (err != MP_OKAY) break;
    3737 
    3738                    /* s = (e + xr)/k */
    3739                    err = mp_mulmod(s, &pubkey.k, curve->order, s);
    37404725
    37414726                   if (mp_iszero(s) == MP_NO)
     
    37434728                }
    37444729           }
    3745            wc_ecc_free(&pubkey);
     4730           mp_clear(b);
     4731           mp_free(b);
     4732       #ifdef WOLFSSL_SMALL_STACK
     4733           XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
     4734       #endif
     4735           wc_ecc_free(pubkey);
     4736       #ifdef WOLFSSL_SMALL_STACK
     4737           XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
     4738       #endif
    37464739       }
    37474740   }
    37484741
    3749    mp_clear(&e);
     4742   mp_clear(e);
    37504743   wc_ecc_curve_free(curve);
     4744#ifdef WOLFSSL_SMALL_STACK
     4745   XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
     4746#endif
     4747   FREE_CURVE_SPECS();
     4748#endif /* WOLFSSL_SP_MATH */
    37514749
    37524750   return err;
     
    37544752#endif /* WOLFSSL_ATECC508A */
    37554753#endif /* HAVE_ECC_SIGN */
     4754
     4755#ifdef WOLFSSL_CUSTOM_CURVES
     4756void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
     4757{
     4758    if (curve->prime != NULL)
     4759        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4760    if (curve->Af != NULL)
     4761        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4762    if (curve->Bf != NULL)
     4763        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4764    if (curve->order != NULL)
     4765        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4766    if (curve->Gx != NULL)
     4767        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4768    if (curve->Gy != NULL)
     4769        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4770
     4771    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4772
     4773    (void)heap;
     4774}
     4775#endif /* WOLFSSL_CUSTOM_CURVES */
    37564776
    37574777/**
     
    37594779  key   The key you wish to free
    37604780*/
    3761 void wc_ecc_free(ecc_key* key)
     4781int wc_ecc_free(ecc_key* key)
    37624782{
    37634783    if (key == NULL) {
    3764         return;
    3765     }
    3766 
    3767 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     4784        return 0;
     4785    }
     4786
     4787#ifdef WOLFSSL_ASYNC_CRYPT
     4788    #ifdef WC_ASYNC_ENABLE_ECC
    37684789    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
    3769     wc_ecc_free_rs(key, &key->r, &key->s);
     4790    #endif
     4791    wc_ecc_free_async(key);
    37704792#endif
    37714793
    37724794#ifdef WOLFSSL_ATECC508A
    37734795   atmel_ecc_free(key->slot);
    3774    key->slot = -1;
     4796    key->slot = ATECC_INVALID_SLOT;
    37754797#else
    37764798
     
    37814803    mp_forcezero(&key->k);
    37824804#endif /* WOLFSSL_ATECC508A */
    3783 }
    3784 
     4805
     4806#ifdef WOLFSSL_CUSTOM_CURVES
     4807    if (key->deallocSet && key->dp != NULL)
     4808        wc_ecc_free_curve(key->dp, key->heap);
     4809#endif
     4810
     4811    return 0;
     4812}
     4813
     4814#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A)
    37854815#ifdef ECC_SHAMIR
    37864816
     
    38014831                             void* heap)
    38024832#else
    3803 static int ecc_mul2add(ecc_point* A, mp_int* kA,
     4833int ecc_mul2add(ecc_point* A, mp_int* kA,
    38044834                    ecc_point* B, mp_int* kB,
    38054835                    ecc_point* C, mp_int* a, mp_int* modulus,
     
    38074837#endif
    38084838{
    3809   ecc_point*     precomp[16];
     4839#ifdef WOLFSSL_SMALL_STACK
     4840  ecc_point**    precomp = NULL;
     4841#ifdef WOLFSSL_SMALL_STACK_CACHE
     4842  ecc_key        key;
     4843#endif
     4844#else
     4845  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
     4846#endif
    38104847  unsigned       bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
    38114848  unsigned char* tA;
    38124849  unsigned char* tB;
    38134850  int            err = MP_OKAY, first, x, y;
    3814   mp_digit mp;
     4851  mp_digit       mp = 0;
    38154852
    38164853  /* argchks */
     
    38304867     return GEN_MEM_ERR;
    38314868  }
     4869#ifdef WOLFSSL_SMALL_STACK
     4870  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
     4871                                                       DYNAMIC_TYPE_ECC_BUFFER);
     4872  if (precomp == NULL) {
     4873     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4874     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4875     return GEN_MEM_ERR;
     4876  }
     4877#endif
     4878#ifdef WOLFSSL_SMALL_STACK_CACHE
     4879  key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4880  key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4881#ifdef ALT_ECC_SIZE
     4882  key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4883  key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4884  key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4885#endif
     4886  if (key.t1 == NULL || key.t2 == NULL
     4887#ifdef ALT_ECC_SIZE
     4888     || key.x == NULL || key.y == NULL || key.z == NULL
     4889#endif
     4890  ) {
     4891#ifdef ALT_ECC_SIZE
     4892      XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     4893      XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     4894      XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     4895#endif
     4896      XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     4897      XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     4898      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4899      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4900      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
     4901      return MEMORY_E;
     4902  }
     4903  C->key = &key;
     4904#endif /* WOLFSSL_SMALL_STACK_CACHE */
    38324905
    38334906  /* init variables */
    38344907  XMEMSET(tA, 0, ECC_BUFSIZE);
    38354908  XMEMSET(tB, 0, ECC_BUFSIZE);
     4909#ifndef WOLFSSL_SMALL_STACK
    38364910  XMEMSET(precomp, 0, sizeof(precomp));
     4911#else
     4912  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
     4913#endif
    38374914
    38384915  /* get sizes */
     
    38564933    /* allocate the table */
    38574934    if (err == MP_OKAY) {
    3858         for (x = 0; x < 16; x++) {
     4935        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
    38594936            precomp[x] = wc_ecc_new_point_h(heap);
    38604937            if (precomp[x] == NULL) {
     
    38624939                break;
    38634940            }
     4941        #ifdef WOLFSSL_SMALL_STACK_CACHE
     4942            precomp[x]->key = &key;
     4943        #endif
    38644944        }
    38654945    }
     
    38714951
    38724952  if (err == MP_OKAY) {
    3873     mp_int mu;
    3874     err = mp_init(&mu);
     4953  #ifdef WOLFSSL_SMALL_STACK
     4954    mp_int* mu = NULL;
     4955  #else
     4956    mp_int  mu[1];
     4957  #endif
     4958  #ifdef WOLFSSL_SMALL_STACK
     4959    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     4960    if (mu == NULL)
     4961        err = MEMORY_E;
     4962  #endif
    38754963    if (err == MP_OKAY) {
    3876       err = mp_montgomery_calc_normalization(&mu, modulus);
     4964        err = mp_init(mu);
     4965    }
     4966    if (err == MP_OKAY) {
     4967      err = mp_montgomery_calc_normalization(mu, modulus);
    38774968
    38784969      if (err == MP_OKAY)
    38794970        /* copy ones ... */
    3880         err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x);
     4971        err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
    38814972
    38824973      if (err == MP_OKAY)
    3883         err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y);
     4974        err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
    38844975      if (err == MP_OKAY)
    3885         err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z);
     4976        err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
    38864977
    38874978      if (err == MP_OKAY)
    3888         err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x);
     4979        err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
    38894980      if (err == MP_OKAY)
    3890         err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y);
     4981        err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
    38914982      if (err == MP_OKAY)
    3892         err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z);
     4983        err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
    38934984
    38944985      /* done with mu */
    3895       mp_clear(&mu);
     4986      mp_clear(mu);
     4987  #ifdef WOLFSSL_SMALL_STACK
     4988      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     4989  #endif
    38964990    }
    38974991  }
     
    39165010    for (x = 1; x < 4; x++) {
    39175011        for (y = 1; y < 4; y++) {
    3918             if (err == MP_OKAY)
     5012        if (err == MP_OKAY) {
    39195013                err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
    39205014                                               precomp[x+(y<<2)], a, modulus, mp);
    39215015        }
    39225016    }
     5017  }
    39235018  }
    39245019
     
    39945089
    39955090  /* clean up */
    3996   for (x = 0; x < 16; x++) {
     5091  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
    39975092     wc_ecc_del_point_h(precomp[x], heap);
    39985093  }
     
    40005095  ForceZero(tA, ECC_BUFSIZE);
    40015096  ForceZero(tB, ECC_BUFSIZE);
     5097#ifdef WOLFSSL_SMALL_STACK_CACHE
     5098#ifdef ALT_ECC_SIZE
     5099  XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
     5100  XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
     5101  XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
     5102#endif
     5103  XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
     5104  XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     5105  C->key = NULL;
     5106#endif
     5107#ifdef WOLFSSL_SMALL_STACK
     5108  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
     5109#endif
     5110  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
    40025111  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
    4003   XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
    40045112
    40055113  return err;
     
    40075115
    40085116#endif /* ECC_SHAMIR */
     5117#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A */
    40095118
    40105119
     
    40375146    mp_int *r = NULL, *s = NULL;
    40385147#ifndef WOLFSSL_ASYNC_CRYPT
    4039     mp_int r_lcl, s_lcl;
    4040     r = &r_lcl;
    4041     s = &s_lcl;
     5148#ifndef WOLFSSL_SMALL_STACK
     5149    mp_int r_lcl[1], s_lcl[1];
     5150#endif
    40425151#endif
    40435152
     
    40455154        return ECC_BAD_ARG_E;
    40465155    }
     5156
     5157#ifdef WOLF_CRYPTO_DEV
     5158    if (key->devId != INVALID_DEVID) {
     5159        err = wc_CryptoDev_EccVerify(sig, siglen, hash, hashlen, res, key);
     5160        if (err != NOT_COMPILED_IN)
     5161            return err;
     5162    }
     5163#endif
     5164
     5165#ifdef WOLFSSL_ASYNC_CRYPT
     5166    err = wc_ecc_alloc_async(key);
     5167    if (err != 0)
     5168        return err;
     5169    r = key->r;
     5170    s = key->s;
     5171#else
     5172    #ifndef WOLFSSL_SMALL_STACK
     5173    r = r_lcl;
     5174    s = s_lcl;
     5175    #else
     5176    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5177    if (r == NULL)
     5178        return MEMORY_E;
     5179    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5180    if (s == NULL) {
     5181        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
     5182        return MEMORY_E;
     5183    }
     5184    #endif
     5185    XMEMSET(r, 0, sizeof(mp_int));
     5186    XMEMSET(s, 0, sizeof(mp_int));
     5187#endif /* WOLFSSL_ASYNC_CRYPT */
    40475188
    40485189    switch(key->state) {
     
    40585199             * the rest of this function will execute, and everything
    40595200             * gets cleaned up at the end. */
    4060             err = wc_ecc_alloc_rs(key, &r, &s);
    4061             if (err != 0)
    4062                 break;
    4063 
    40645201            /* decode DSA header */
    40655202            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
     
    40735210
    40745211            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
     5212
     5213        #ifndef WOLFSSL_ASYNC_CRYPT
     5214            /* done with R/S */
     5215            mp_clear(r);
     5216            mp_clear(s);
     5217        #ifdef WOLFSSL_SMALL_STACK
     5218            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
     5219            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
     5220            r = NULL;
     5221            s = NULL;
     5222        #endif
     5223        #endif
     5224
    40755225            if (err < 0) {
    40765226                break;
     
    40815231            key->state = ECC_STATE_VERIFY_RES;
    40825232            err = 0;
    4083 
    4084         #ifdef WOLFSSL_ASYNC_CRYPT
    4085             /* restore r/s */
    4086             r = key->r;
    4087             s = key->s;
    4088         #endif
    4089 
    4090             /* done with R/S */
    4091             mp_clear(r);
    4092             mp_clear(s);
    40935233            break;
    40945234
     
    41045244
    41055245    /* cleanup */
    4106     wc_ecc_free_rs(key, &r, &s);
     5246#ifdef WOLFSSL_ASYNC_CRYPT
     5247    wc_ecc_free_async(key);
     5248#endif
    41075249    key->state = ECC_STATE_NONE;
     5250
     5251#ifdef WOLFSSL_SMALL_STACK
     5252    if (err != WC_PENDING_E) {
     5253            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
     5254            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
     5255            r = NULL;
     5256            s = NULL;
     5257    }
     5258#endif
    41085259
    41095260    return err;
     
    41265277{
    41275278   int           err;
    4128 #ifndef WOLFSSL_ATECC508A
     5279   word32        keySz;
     5280#ifdef WOLFSSL_ATECC508A
     5281   byte sigRS[ATECC_KEY_SIZE*2];
     5282#elif !defined(WOLFSSL_SP_MATH)
    41295283   int          did_init = 0;
    41305284   ecc_point    *mG = NULL, *mQ = NULL;
    4131    mp_int        v;
    4132    mp_int        w;
    4133    mp_int        u1;
    4134    mp_int        u2;
    4135    mp_int        e;
    4136    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
    4137 #else
    4138    byte sigRS[ATECC_KEY_SIZE*2];
     5285#ifdef WOLFSSL_SMALL_STACK
     5286   mp_int*       v = NULL;
     5287   mp_int*       w = NULL;
     5288   mp_int*       u1 = NULL;
     5289   mp_int*       u2 = NULL;
     5290#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
     5291   mp_int*       e_lcl = NULL;
     5292#endif
     5293#else /* WOLFSSL_SMALL_STACK */
     5294   mp_int        v[1];
     5295   mp_int        w[1];
     5296   mp_int        u1[1];
     5297   mp_int        u2[1];
     5298#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
     5299   mp_int        e_lcl[1];
     5300#endif
     5301#endif /* WOLFSSL_SMALL_STACK */
     5302   mp_int*       e;
     5303   DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
    41395304#endif
    41405305
     
    41495314      return ECC_BAD_ARG_E;
    41505315   }
     5316
     5317   keySz = key->dp->size;
    41515318
    41525319#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
     
    41725339        return err;
    41735340    }
    4174     err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]);
     5341    err = mp_to_unsigned_bin(s, &sigRS[keySz]);
    41755342    if (err != MP_OKAY) {
    41765343        return err;
    41775344    }
    41785345
    4179     err = atcatls_verify(hash, sigRS, key->pubkey, (bool*)res);
    4180     if (err != ATCA_SUCCESS) {
    4181        return BAD_COND_E;
    4182    }
     5346    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
     5347    if (err != 0) {
     5348       return err;
     5349   }
     5350    (void)hashlen;
    41835351
    41845352#else
    4185 
    41865353  /* checking if private key with no public part */
    41875354  if (key->type == ECC_PRIVATEKEY_ONLY) {
     
    41945361  }
    41955362
     5363#ifdef WOLFSSL_SP_MATH
     5364  if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
     5365      return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
     5366                                           key->pubkey.z, r, s, res, key->heap);
     5367  }
     5368  else
     5369      return WC_KEY_SIZE_E;
     5370#else
    41965371#ifdef WOLFSSL_HAVE_SP_ECC
    41975372#ifndef WOLFSSL_SP_NO_256
     
    42055380                                     key->pubkey.z,r, s, res, key->heap);
    42065381    }
    4207 #endif
    4208 #endif
    4209 
    4210    err = mp_init(&e);
     5382#endif /* WOLFSSL_SP_NO_256 */
     5383#endif /* WOLFSSL_HAVE_SP_ECC */
     5384
     5385   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
     5386
     5387#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
     5388   err = wc_ecc_alloc_mpint(key, &key->e);
     5389   if (err != 0) {
     5390      FREE_CURVE_SPECS();
     5391      return err;
     5392   }
     5393   e = key->e;
     5394#else
     5395#ifdef WOLFSSL_SMALL_STACK
     5396   e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5397   if (e_lcl == NULL) {
     5398       FREE_CURVE_SPECS();
     5399       return MEMORY_E;
     5400   }
     5401#endif
     5402   e = e_lcl;
     5403#endif
     5404
     5405   err = mp_init(e);
    42115406   if (err != MP_OKAY)
    42125407      return MEMORY_E;
     
    42325427       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
    42335428           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
    4234        err = mp_read_unsigned_bin(&e, hash, hashlen);
     5429       err = mp_read_unsigned_bin(e, hash, hashlen);
    42355430
    42365431       /* may still need bit truncation too */
    42375432       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
    4238            mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
     5433           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
    42395434   }
    42405435
     
    42425437#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
    42435438   if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
    4244    #ifdef HAVE_CAVIUM
    4245       /* TODO: Not implemented */
    4246    #elif defined(HAVE_INTEL_QA)
    4247       err = wc_mp_to_bigint(&e, &e.raw);
     5439   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
     5440   #ifdef HAVE_CAVIUM_V
     5441      if (NitroxEccIsCurveSupported(key))
     5442   #endif
     5443      {
     5444          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
    42485445      if (err == MP_OKAY)
    4249           err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
     5446              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
    42505447      if (err == MP_OKAY)
    4251           err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
     5448              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
    42525449      if (err == MP_OKAY)
    4253           err = IntelQaEcdsaVerify(&key->asyncDev, &e.raw, &key->pubkey.x->raw,
     5450          #ifdef HAVE_CAVIUM_V
     5451              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
     5452                    &key->pubkey.y->raw, &r->raw, &s->raw,
     5453                    &curve->prime->raw, &curve->order->raw, res);
     5454          #else
     5455              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
    42545456                &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
    42555457                &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
    42565458                &curve->Gx->raw, &curve->Gy->raw, res);
    4257 
    4258       mp_clear(&e);
    4259 
     5459          #endif
     5460
     5461      #ifndef HAVE_CAVIUM_V
     5462          mp_clear(e);
     5463      #endif
    42605464      wc_ecc_curve_free(curve);
     5465          FREE_CURVE_SPECS();
    42615466
    42625467      return err;
    4263    #endif
     5468      }
     5469   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
    42645470   }
    42655471#endif /* WOLFSSL_ASYNC_CRYPT */
     5472
     5473#ifdef WOLFSSL_SMALL_STACK
     5474   if (err == MP_OKAY) {
     5475       v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5476       if (v == NULL)
     5477           err = MEMORY_E;
     5478   }
     5479   if (err == MP_OKAY) {
     5480       w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5481       if (w == NULL)
     5482           err = MEMORY_E;
     5483   }
     5484   if (err == MP_OKAY) {
     5485       u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5486       if (u1 == NULL)
     5487           err = MEMORY_E;
     5488   }
     5489   if (err == MP_OKAY) {
     5490       u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     5491       if (u2 == NULL)
     5492           err = MEMORY_E;
     5493   }
     5494#endif
    42665495
    42675496   /* allocate ints */
    42685497   if (err == MP_OKAY) {
    4269        if ((err = mp_init_multi(&v, &w, &u1, &u2, NULL, NULL)) != MP_OKAY) {
     5498       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
    42705499          err = MEMORY_E;
    42715500       }
     
    42835512   /*  w  = s^-1 mod n */
    42845513   if (err == MP_OKAY)
    4285        err = mp_invmod(s, curve->order, &w);
     5514       err = mp_invmod(s, curve->order, w);
    42865515
    42875516   /* u1 = ew */
    42885517   if (err == MP_OKAY)
    4289        err = mp_mulmod(&e, &w, curve->order, &u1);
     5518       err = mp_mulmod(e, w, curve->order, u1);
    42905519
    42915520   /* u2 = rw */
    42925521   if (err == MP_OKAY)
    4293        err = mp_mulmod(r, &w, curve->order, &u2);
     5522       err = mp_mulmod(r, w, curve->order, u2);
    42945523
    42955524   /* find mG and mQ */
     
    43115540   /* use PKHA to compute u1*mG + u2*mQ */
    43125541   if (err == MP_OKAY)
    4313        err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
    4314    if (err == MP_OKAY)
    4315        err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
     5542       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
     5543   if (err == MP_OKAY)
     5544       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
    43165545   if (err == MP_OKAY)
    43175546       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
    4318 #else /* FREESCALE_LTC_ECC */
     5547#else
    43195548#ifndef ECC_SHAMIR
    43205549    {
    4321         mp_digit      mp;
     5550        mp_digit mp = 0;
    43225551
    43235552        /* compute u1*mG + u2*mQ = mG */
    43245553        if (err == MP_OKAY) {
    4325             err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0,
     5554            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
    43265555                                                                     key->heap);
    43275556        }
    43285557        if (err == MP_OKAY) {
    4329             err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0,
     5558            err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
    43305559                                                                     key->heap);
    43315560        }
     
    43475576       /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
    43485577        if (err == MP_OKAY) {
    4349             err = ecc_mul2add(mG, &u1, mQ, &u2, mG, curve->Af, curve->prime,
     5578            err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
    43505579                                                                    key->heap);
    43515580        }
     
    43545583   /* v = X_x1 mod n */
    43555584   if (err == MP_OKAY)
    4356        err = mp_mod(mG->x, curve->order, &v);
     5585       err = mp_mod(mG->x, curve->order, v);
    43575586
    43585587   /* does v == r */
    43595588   if (err == MP_OKAY) {
    4360        if (mp_cmp(&v, r) == MP_EQ)
     5589       if (mp_cmp(v, r) == MP_EQ)
    43615590           *res = 1;
    43625591   }
     
    43665595   wc_ecc_del_point_h(mQ, key->heap);
    43675596
    4368    mp_clear(&e);
     5597   mp_clear(e);
    43695598   if (did_init) {
    4370        mp_clear(&v);
    4371        mp_clear(&w);
    4372        mp_clear(&u1);
    4373        mp_clear(&u2);
    4374    }
     5599       mp_clear(v);
     5600       mp_clear(w);
     5601       mp_clear(u1);
     5602       mp_clear(u2);
     5603   }
     5604#ifdef WOLFSSL_SMALL_STACK
     5605   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
     5606   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
     5607   XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
     5608   XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
     5609#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
     5610   XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
     5611#endif
     5612#endif
    43755613
    43765614   wc_ecc_curve_free(curve);
    4377 
     5615   FREE_CURVE_SPECS();
     5616
     5617#endif /* WOLFSSL_SP_MATH */
    43785618#endif /* WOLFSSL_ATECC508A */
    43795619
     5620   (void)keySz;
     5621   (void)hashlen;
     5622
    43805623   return err;
    43815624}
     
    43835626
    43845627#ifdef HAVE_ECC_KEY_IMPORT
    4385 #ifndef WOLFSSL_ATECC508A
    43865628/* import point from der */
    43875629int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
     
    43905632    int err = 0;
    43915633    int compressed = 0;
     5634    int keysize;
     5635    byte pointType;
    43925636
    43935637    if (in == NULL || point == NULL || (curve_idx < 0) ||
     
    44145658        return MEMORY_E;
    44155659
    4416     /* check for 4, 2, or 3 */
    4417     if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
     5660    /* check for point type (4, 2, or 3) */
     5661    pointType = in[0];
     5662    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
     5663                                         pointType != ECC_POINT_COMP_ODD) {
    44185664        err = ASN_PARSE_E;
    44195665    }
    44205666
    4421     if (in[0] == 0x02 || in[0] == 0x03) {
     5667    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
    44225668#ifdef HAVE_COMP_KEY
    44235669        compressed = 1;
     
    44275673    }
    44285674
     5675    /* adjust to skip first byte */
     5676    inLen -= 1;
     5677    in += 1;
     5678
     5679    /* calculate key size based on inLen / 2 */
     5680    keysize = inLen>>1;
     5681
    44295682    /* read data */
    44305683    if (err == MP_OKAY)
    4431         err = mp_read_unsigned_bin(point->x, (byte*)in+1, (inLen-1)>>1);
     5684        err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);
    44325685
    44335686#ifdef HAVE_COMP_KEY
    44345687    if (err == MP_OKAY && compressed == 1) {   /* build y */
     5688#ifndef WOLFSSL_SP_MATH
    44355689        int did_init = 0;
    44365690        mp_int t1, t2;
    4437         DECLARE_CURVE_SPECS(3)
     5691        DECLARE_CURVE_SPECS(curve, 3);
     5692
     5693        ALLOC_CURVE_SPECS(3);
    44385694
    44395695        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
     
    44705726        /* adjust y */
    44715727        if (err == MP_OKAY) {
    4472             if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
    4473                 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
     5728            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
     5729                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
    44745730                err = mp_mod(&t2, curve->prime, point->y);
    44755731            }
     
    44855741
    44865742        wc_ecc_curve_free(curve);
     5743        FREE_CURVE_SPECS();
     5744#else
     5745        sp_ecc_uncompress_256(point->x, pointType, point->y);
     5746#endif
    44875747    }
    44885748#endif
    44895749
    44905750    if (err == MP_OKAY && compressed == 0)
    4491         err = mp_read_unsigned_bin(point->y,
    4492                                    (byte*)in+1+((inLen-1)>>1), (inLen-1)>>1);
     5751        err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize);
    44935752    if (err == MP_OKAY)
    44945753        err = mp_set(point->z, 1);
     
    45025761    return err;
    45035762}
    4504 #endif /* !WOLFSSL_ATECC508A */
    45055763#endif /* HAVE_ECC_KEY_IMPORT */
    45065764
     
    45125770    int    ret = MP_OKAY;
    45135771    word32 numlen;
    4514 #ifndef WOLFSSL_ATECC508A
    45155772#ifdef WOLFSSL_SMALL_STACK
    45165773    byte*  buf;
     
    45185775    byte   buf[ECC_BUFSIZE];
    45195776#endif
    4520 #endif /* !WOLFSSL_ATECC508A */
    45215777
    45225778    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
     
    45405796    }
    45415797
    4542 #ifdef WOLFSSL_ATECC508A
    4543    /* TODO: Implement equiv call to ATECC508A */
    4544    ret = BAD_COND_E;
    4545 
    4546 #else
    4547 
    4548     /* store byte 0x04 */
    4549     out[0] = 0x04;
     5798    /* store byte point type */
     5799    out[0] = ECC_POINT_UNCOMP;
    45505800
    45515801#ifdef WOLFSSL_SMALL_STACK
     
    45775827    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
    45785828#endif
    4579 #endif /* WOLFSSL_ATECC508A */
    45805829
    45815830    return ret;
     
    45885837   int    ret = MP_OKAY;
    45895838   word32 numlen;
    4590 #ifndef WOLFSSL_ATECC508A
    45915839#ifdef WOLFSSL_SMALL_STACK
    45925840   byte*  buf;
     
    45955843#endif
    45965844   word32 pubxlen, pubylen;
    4597 #endif /* WOLFSSL_ATECC508A */
    45985845
    45995846   /* return length needed only */
     
    46205867      return BUFFER_E;
    46215868   }
    4622 
    4623 #ifdef WOLFSSL_ATECC508A
    4624    /* TODO: Implement equiv call to ATECC508A */
    4625    ret = BAD_COND_E;
    4626 
    4627 #else
    46285869
    46295870   /* verify public key length is less than key size */
     
    46355876   }
    46365877
    4637    /* store byte 0x04 */
    4638    out[0] = 0x04;
     5878   /* store byte point type */
     5879   out[0] = ECC_POINT_UNCOMP;
    46395880
    46405881#ifdef WOLFSSL_SMALL_STACK
     
    46645905   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
    46655906#endif
    4666 #endif /* WOLFSSL_ATECC508A */
    46675907
    46685908   return ret;
     
    46925932int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
    46935933{
     5934#ifndef WOLFSSL_SP_MATH
    46945935   int err;
    4695    mp_int t1, t2;
    4696 
    4697    if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     5936#ifdef WOLFSSL_SMALL_STACK
     5937   mp_int* t1 = NULL;
     5938   mp_int* t2 = NULL;
     5939#else
     5940   mp_int  t1[1], t2[1];
     5941#endif
     5942
     5943#ifdef WOLFSSL_SMALL_STACK
     5944   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     5945   if (t1 == NULL)
     5946       return MEMORY_E;
     5947   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     5948   if (t2 == NULL) {
     5949       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     5950       return MEMORY_E;
     5951   }
     5952#endif
     5953
     5954   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
     5955   #ifdef WOLFSSL_SMALL_STACK
     5956      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     5957      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     5958   #endif
    46985959      return err;
    46995960   }
     
    47015962   /* compute y^2 */
    47025963   if (err == MP_OKAY)
    4703        err = mp_sqr(ecp->y, &t1);
     5964       err = mp_sqr(ecp->y, t1);
    47045965
    47055966   /* compute x^3 */
    47065967   if (err == MP_OKAY)
    4707        err = mp_sqr(ecp->x, &t2);
    4708    if (err == MP_OKAY)
    4709        err = mp_mod(&t2, prime, &t2);
    4710    if (err == MP_OKAY)
    4711        err = mp_mul(ecp->x, &t2, &t2);
     5968       err = mp_sqr(ecp->x, t2);
     5969   if (err == MP_OKAY)
     5970       err = mp_mod(t2, prime, t2);
     5971   if (err == MP_OKAY)
     5972       err = mp_mul(ecp->x, t2, t2);
    47125973
    47135974   /* compute y^2 - x^3 */
    47145975   if (err == MP_OKAY)
    4715        err = mp_sub(&t1, &t2, &t1);
     5976       err = mp_sub(t1, t2, t1);
    47165977
    47175978   /* Determine if curve "a" should be used in calc */
     
    47195980   if (err == MP_OKAY) {
    47205981      /* Use a and prime to determine if a == 3 */
    4721       err = mp_set(&t2, 0);
     5982      err = mp_set(t2, 0);
    47225983      if (err == MP_OKAY)
    4723           err = mp_submod(prime, a, prime, &t2);
    4724    }
    4725    if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
     5984          err = mp_submod(prime, a, prime, t2);
     5985   }
     5986   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
    47265987      /* compute y^2 - x^3 + a*x */
    47275988      if (err == MP_OKAY)
    4728           err = mp_mulmod(&t2, ecp->x, prime, &t2);
     5989          err = mp_mulmod(t2, ecp->x, prime, t2);
    47295990      if (err == MP_OKAY)
    4730           err = mp_addmod(&t1, &t2, prime, &t1);
     5991          err = mp_addmod(t1, t2, prime, t1);
    47315992   }
    47325993   else
     
    47385999      /* compute y^2 - x^3 + 3x */
    47396000      if (err == MP_OKAY)
    4740           err = mp_add(&t1, ecp->x, &t1);
     6001          err = mp_add(t1, ecp->x, t1);
    47416002      if (err == MP_OKAY)
    4742           err = mp_add(&t1, ecp->x, &t1);
     6003          err = mp_add(t1, ecp->x, t1);
    47436004      if (err == MP_OKAY)
    4744           err = mp_add(&t1, ecp->x, &t1);
     6005          err = mp_add(t1, ecp->x, t1);
    47456006      if (err == MP_OKAY)
    4746           err = mp_mod(&t1, prime, &t1);
     6007          err = mp_mod(t1, prime, t1);
    47476008  }
    47486009
    47496010   /* adjust range (0, prime) */
    4750    while (err == MP_OKAY && mp_isneg(&t1)) {
    4751       err = mp_add(&t1, prime, &t1);
    4752    }
    4753    while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) {
    4754       err = mp_sub(&t1, prime, &t1);
     6011   while (err == MP_OKAY && mp_isneg(t1)) {
     6012      err = mp_add(t1, prime, t1);
     6013   }
     6014   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
     6015      err = mp_sub(t1, prime, t1);
    47556016   }
    47566017
    47576018   /* compare to b */
    47586019   if (err == MP_OKAY) {
    4759        if (mp_cmp(&t1, b) != MP_EQ) {
     6020       if (mp_cmp(t1, b) != MP_EQ) {
    47606021          err = MP_VAL;
    47616022       } else {
     
    47646025   }
    47656026
    4766    mp_clear(&t1);
    4767    mp_clear(&t2);
     6027   mp_clear(t1);
     6028   mp_clear(t2);
     6029#ifdef WOLFSSL_SMALL_STACK
     6030   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
     6031   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
     6032#endif
    47686033
    47696034   return err;
    4770 }
    4771 
    4772 
     6035#else
     6036   (void)a;
     6037   (void)b;
     6038   (void)prime;
     6039
     6040   return sp_ecc_is_point_256(ecp->x, ecp->y);
     6041#endif
     6042}
     6043
     6044#ifndef WOLFSSL_SP_MATH
    47736045/* validate privkey * generator == pubkey, 0 on success */
    47746046static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
     
    47776049    ecc_point* base = NULL;
    47786050    ecc_point* res  = NULL;
    4779     DECLARE_CURVE_SPECS(2)
     6051    DECLARE_CURVE_SPECS(curve, 2);
    47806052
    47816053    if (key == NULL)
    47826054        return BAD_FUNC_ARG;
     6055
     6056    ALLOC_CURVE_SPECS(2);
    47836057
    47846058    res = wc_ecc_new_point_h(key->heap);
     
    48316105    wc_ecc_del_point_h(res, key->heap);
    48326106    wc_ecc_del_point_h(base, key->heap);
     6107    FREE_CURVE_SPECS();
    48336108
    48346109    return err;
    48356110}
     6111#endif
    48366112
    48376113#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
     
    48426118    int    err;
    48436119#ifndef WOLFSSL_ATECC508A
    4844     DECLARE_CURVE_SPECS(2)
     6120    DECLARE_CURVE_SPECS(curve, 2);
    48456121#endif
    48466122
     
    48496125
    48506126#ifdef WOLFSSL_ATECC508A
    4851     /* TODO: Implement equiv call to ATECC508A */
    4852     err = BAD_COND_E;
     6127    /* Hardware based private key, so this operation is not supported */
     6128    err = MP_OKAY; /* just report success */
    48536129
    48546130#else
     6131    ALLOC_CURVE_SPECS(2);
    48556132
    48566133    /* load curve info */
     
    48626139
    48636140    wc_ecc_curve_free(curve);
     6141    FREE_CURVE_SPECS();
    48646142
    48656143#endif /* WOLFSSL_ATECC508A */
     
    48716149
    48726150
     6151#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
    48736152/* validate order * pubkey = point at infinity, 0 on success */
    48746153static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
     
    48946173#endif
    48956174#endif
     6175#ifndef WOLFSSL_SP_MATH
    48966176            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
    48976177        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
    48986178            err = ECC_INF_E;
     6179#else
     6180            (void)a;
     6181            (void)prime;
     6182
     6183            err = WC_KEY_SIZE_E;
     6184#endif
    48996185    }
    49006186
     
    49036189    return err;
    49046190}
    4905 
     6191#endif
    49066192#endif /* !WOLFSSL_ATECC508A */
    49076193
     
    49116197{
    49126198    int    err;
     6199#ifndef WOLFSSL_SP_MATH
    49136200#ifndef WOLFSSL_ATECC508A
    4914     mp_int* b;
     6201    mp_int* b = NULL;
    49156202#ifdef USE_ECC_B_PARAM
    4916     DECLARE_CURVE_SPECS(4)
     6203    DECLARE_CURVE_SPECS(curve, 4);
    49176204#else
     6205#ifndef WOLFSSL_SMALL_STACK
    49186206    mp_int b_lcl;
    4919     DECLARE_CURVE_SPECS(3)
    4920     b = &b_lcl;
    4921     XMEMSET(b, 0, sizeof(mp_int));
    4922 #endif
     6207#endif
     6208    DECLARE_CURVE_SPECS(curve, 3);
     6209#endif /* USE_ECC_B_PARAM */
    49236210#endif /* WOLFSSL_ATECC508A */
    49246211
     
    49286215#ifdef WOLFSSL_ATECC508A
    49296216
    4930     if (key->slot == ATECC_INVALID_SLOT)
    4931         return ECC_BAD_ARG_E;
    4932 
    4933     err = 0; /* consider key check success on ECC508A */
     6217    err = 0; /* consider key check success on ATECC508A */
    49346218
    49356219#else
    4936 
     6220    #ifdef USE_ECC_B_PARAM
     6221        ALLOC_CURVE_SPECS(4);
     6222    #else
     6223        ALLOC_CURVE_SPECS(3);
     6224        #ifndef WOLFSSL_SMALL_STACK
     6225            b = &b_lcl;
     6226        #else
     6227            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
     6228            if (b == NULL) {
     6229                FREE_CURVE_SPECS();
     6230                return MEMORY_E;
     6231            }
     6232        #endif
     6233        XMEMSET(b, 0, sizeof(mp_int));
     6234    #endif
     6235
     6236    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
    49376237    /* pubkey point cannot be at infinity */
    4938     if (wc_ecc_point_is_at_infinity(&key->pubkey))
     6238    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
     6239    #ifdef WOLFSSL_SMALL_STACK
     6240        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
     6241    #endif
     6242        FREE_CURVE_SPECS();
    49396243        return ECC_INF_E;
     6244    }
    49406245
    49416246    /* load curve info */
     
    49526257        err = mp_init(b);
    49536258    if (err == MP_OKAY)
    4954         err = mp_read_radix(b, key->dp->Bf, 16);
     6259        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
    49556260#else
    49566261    b = curve->Bf;
    49576262#endif
    49586263
     6264    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
    49596265    /* Qx must be in the range [0, p-1] */
    49606266    if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
     
    49656271        err = ECC_OUT_OF_RANGE_E;
    49666272
     6273    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */
    49676274    /* make sure point is actually on curve */
    49686275    if (err == MP_OKAY)
    49696276        err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
    49706277
     6278    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */
    49716279    /* pubkey * order must be at infinity */
    49726280    if (err == MP_OKAY)
     
    49746282                curve->order);
    49756283
     6284    /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
    49766285    /* private * base generator must equal pubkey */
    49776286    if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
     
    49826291#ifndef USE_ECC_B_PARAM
    49836292    mp_clear(b);
    4984 #endif
     6293    #ifdef WOLFSSL_SMALL_STACK
     6294        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
     6295#endif
     6296#endif
     6297
     6298    FREE_CURVE_SPECS();
    49856299
    49866300#endif /* WOLFSSL_ATECC508A */
     6301#else
     6302    if (key == NULL)
     6303        return BAD_FUNC_ARG;
     6304
     6305    /* pubkey point cannot be at infinity */
     6306    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
     6307        err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
     6308                                                                     key->heap);
     6309    }
     6310    else
     6311        err = WC_KEY_SIZE_E;
     6312#endif
    49876313
    49886314    return err;
     
    49956321{
    49966322    int err = MP_OKAY;
    4997 #ifndef WOLFSSL_ATECC508A
    49986323    int compressed = 0;
    4999 #endif /* !WOLFSSL_ATECC508A */
     6324    int keysize = 0;
     6325    byte pointType;
    50006326
    50016327    if (in == NULL || key == NULL)
     
    50096335    /* make sure required variables are reset */
    50106336    wc_ecc_reset(key);
    5011 
    5012 #ifdef WOLFSSL_ATECC508A
    5013     /* TODO: Implement equiv call to ATECC508A */
    5014     err = BAD_COND_E;
    5015 
    5016 #else
    50176337
    50186338    /* init key */
     
    50326352        return MEMORY_E;
    50336353
    5034     /* check for 4, 2, or 3 */
    5035     if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
     6354    /* check for point type (4, 2, or 3) */
     6355    pointType = in[0];
     6356    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
     6357                                         pointType != ECC_POINT_COMP_ODD) {
    50366358        err = ASN_PARSE_E;
    50376359    }
    50386360
    5039     if (in[0] == 0x02 || in[0] == 0x03) {
     6361    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
    50406362    #ifdef HAVE_COMP_KEY
    50416363        compressed = 1;
     
    50456367    }
    50466368
     6369    /* adjust to skip first byte */
     6370    inLen -= 1;
     6371    in += 1;
     6372
     6373#ifdef WOLFSSL_ATECC508A
     6374    /* For SECP256R1 only save raw public key for hardware */
     6375    if (curve_id == ECC_SECP256R1 && !compressed &&
     6376                                            inLen <= sizeof(key->pubkey_raw)) {
     6377        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
     6378    }
     6379#endif
     6380
    50476381    if (err == MP_OKAY) {
    5048         int keysize;
    50496382    #ifdef HAVE_COMP_KEY
    50506383        /* adjust inLen if compressed */
    50516384        if (compressed)
    5052             inLen = (inLen-1)*2 + 1;  /* used uncompressed len */
     6385            inLen = inLen*2 + 1;  /* used uncompressed len */
    50536386    #endif
    50546387
    50556388        /* determine key size */
    5056         keysize = ((inLen-1)>>1);
     6389        keysize = (inLen>>1);
    50576390        err = wc_ecc_set_curve(key, keysize, curve_id);
    50586391        key->type = ECC_PUBLICKEY;
     
    50616394    /* read data */
    50626395    if (err == MP_OKAY)
    5063         err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
     6396        err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize);
    50646397
    50656398#ifdef HAVE_COMP_KEY
    50666399    if (err == MP_OKAY && compressed == 1) {   /* build y */
     6400#ifndef WOLFSSL_SP_MATH
    50676401        mp_int t1, t2;
    50686402        int did_init = 0;
    50696403
    5070         DECLARE_CURVE_SPECS(3)
     6404        DECLARE_CURVE_SPECS(curve, 3);
     6405        ALLOC_CURVE_SPECS(3);
    50716406
    50726407        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
     
    51036438        /* adjust y */
    51046439        if (err == MP_OKAY) {
    5105             if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
    5106                 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
     6440            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
     6441                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
    51076442                err = mp_mod(&t2, curve->prime, &t2);
    51086443            }
     
    51206455
    51216456        wc_ecc_curve_free(curve);
     6457        FREE_CURVE_SPECS();
     6458#else
     6459        sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y);
     6460#endif
    51226461    }
    51236462#endif /* HAVE_COMP_KEY */
    51246463
    51256464    if (err == MP_OKAY && compressed == 0)
    5126         err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
    5127                                                                 (inLen-1)>>1);
     6465        err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, keysize);
    51286466    if (err == MP_OKAY)
    51296467        err = mp_set(key->pubkey.z, 1);
     
    51406478        mp_clear(&key->k);
    51416479    }
    5142 #endif /* WOLFSSL_ATECC508A */
    51436480
    51446481    return err;
    5145 }
     6482    }
    51466483
    51476484int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
     
    51526489
    51536490#ifdef HAVE_ECC_KEY_EXPORT
    5154 /* export ecc private key only raw, outLen is in/out size
     6491
     6492/* export ecc key to component form, d is optional if only exporting public
     6493 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
     6494 * return MP_OKAY on success */
     6495int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
     6496                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
     6497{
     6498    int err = 0;
     6499    word32 keySz;
     6500
     6501    if (key == NULL) {
     6502        return BAD_FUNC_ARG;
     6503    }
     6504
     6505    if (wc_ecc_is_valid_idx(key->idx) == 0) {
     6506        return ECC_BAD_ARG_E;
     6507    }
     6508    keySz = key->dp->size;
     6509
     6510    /* private key, d */
     6511    if (d != NULL) {
     6512        if (dLen == NULL ||
     6513            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
     6514            return BAD_FUNC_ARG;
     6515
     6516    #ifdef WOLFSSL_ATECC508A
     6517        /* Hardware cannot export private portion */
     6518        return NOT_COMPILED_IN;
     6519    #else
     6520        err = wc_export_int(&key->k, d, dLen, keySz, encType);
     6521        if (err != MP_OKAY)
     6522            return err;
     6523    #endif
     6524    }
     6525
     6526    /* public x component */
     6527    if (qx != NULL) {
     6528        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
     6529            return BAD_FUNC_ARG;
     6530
     6531        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
     6532    if (err != MP_OKAY)
     6533        return err;
     6534    }
     6535
     6536    /* public y component */
     6537    if (qy != NULL) {
     6538        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
     6539            return BAD_FUNC_ARG;
     6540
     6541        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
     6542    if (err != MP_OKAY)
     6543        return err;
     6544    }
     6545
     6546    return err;
     6547}
     6548
     6549
     6550/* export ecc private key only raw, outLen is in/out size as unsigned bin
    51556551   return MP_OKAY on success */
    51566552int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
    51576553{
    5158     word32 numlen;
    5159 
    5160     if (key == NULL || out == NULL || outLen == NULL) {
     6554    if (out == NULL || outLen == NULL) {
    51616555        return BAD_FUNC_ARG;
    5162     }
    5163 
    5164     if (wc_ecc_is_valid_idx(key->idx) == 0) {
    5165         return ECC_BAD_ARG_E;
    5166     }
    5167     numlen = key->dp->size;
    5168 
    5169     if (*outLen < numlen) {
    5170         *outLen = numlen;
    5171         return BUFFER_E;
    5172     }
    5173     *outLen = numlen;
    5174     XMEMSET(out, 0, *outLen);
    5175 
    5176 #ifdef WOLFSSL_ATECC508A
    5177    /* TODO: Implement equiv call to ATECC508A */
    5178    return BAD_COND_E;
    5179 
    5180 #else
    5181 
    5182     return mp_to_unsigned_bin(&key->k, out + (numlen -
    5183                                            mp_unsigned_bin_size(&key->k)));
    5184 #endif /* WOLFSSL_ATECC508A */
    5185 }
    5186 
    5187 
    5188 /* export ecc key to component form, d is optional if only exporting public
    5189  * return MP_OKAY on success */
    5190 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen,
    5191                              byte* qy, word32* qyLen, byte* d, word32* dLen)
    5192 {
    5193     int  err;
    5194     byte exportPriv = 0;
    5195     word32 numLen;
    5196 
    5197     if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
    5198         qyLen == NULL) {
    5199         return BAD_FUNC_ARG;
    5200     }
    5201 
    5202     if (key->type == ECC_PRIVATEKEY_ONLY) {
    5203         return ECC_PRIVATEONLY_E;
    5204     }
    5205 
    5206     if (wc_ecc_is_valid_idx(key->idx) == 0) {
    5207         return ECC_BAD_ARG_E;
    5208     }
    5209     numLen = key->dp->size;
    5210 
    5211     if (d != NULL) {
    5212         if (dLen == NULL || key->type != ECC_PRIVATEKEY)
    5213             return BAD_FUNC_ARG;
    5214         exportPriv = 1;
    5215     }
    5216 
    5217     /* check public buffer sizes */
    5218     if ((*qxLen < numLen) || (*qyLen < numLen)) {
    5219         *qxLen = numLen;
    5220         *qyLen = numLen;
    5221         return BUFFER_E;
    5222     }
    5223 
    5224     *qxLen = numLen;
    5225     *qyLen = numLen;
    5226 
    5227     XMEMSET(qx, 0, *qxLen);
    5228     XMEMSET(qy, 0, *qyLen);
    5229 
    5230     /* private d component */
    5231     if (exportPriv == 1) {
    5232 
    5233         /* check private buffer size */
    5234         if (*dLen < numLen) {
    5235             *dLen = numLen;
    5236             return BUFFER_E;
    5237         }
    5238 
    5239         *dLen = numLen;
    5240         XMEMSET(d, 0, *dLen);
    5241 
    5242     #ifdef WOLFSSL_ATECC508A
    5243        /* TODO: Implement equiv call to ATECC508A */
    5244        return BAD_COND_E;
    5245 
    5246     #else
    5247 
    5248         /* private key, d */
    5249         err = mp_to_unsigned_bin(&key->k, d +
    5250                             (numLen - mp_unsigned_bin_size(&key->k)));
    5251         if (err != MP_OKAY)
    5252             return err;
    5253     #endif /* WOLFSSL_ATECC508A */
    5254     }
    5255 
    5256 #ifdef WOLFSSL_ATECC508A
    5257     /* TODO: Implement equiv call to ATECC508A */
    5258     return BAD_COND_E;
    5259 
    5260 #else
    5261 
    5262     /* public x component */
    5263     err = mp_to_unsigned_bin(key->pubkey.x, qx +
    5264                             (numLen - mp_unsigned_bin_size(key->pubkey.x)));
    5265     if (err != MP_OKAY)
    5266         return err;
    5267 
    5268     /* public y component */
    5269     err = mp_to_unsigned_bin(key->pubkey.y, qy +
    5270                             (numLen - mp_unsigned_bin_size(key->pubkey.y)));
    5271     if (err != MP_OKAY)
    5272         return err;
    5273 
    5274     return 0;
    5275 #endif /* WOLFSSL_ATECC508A */
    5276 }
    5277 
    5278 
    5279 /* export public key to raw elements including public (Qx,Qy)
     6556}
     6557
     6558    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
     6559        WC_TYPE_UNSIGNED_BIN);
     6560}
     6561
     6562/* export public key to raw elements including public (Qx,Qy) as unsigned bin
    52806563 * return MP_OKAY on success, negative on error */
    52816564int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
    52826565                             byte* qy, word32* qyLen)
    52836566{
    5284     return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL);
    5285 }
    5286 
    5287 
    5288 /* export ecc key to raw elements including public (Qx,Qy) and private (d)
     6567    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
     6568        return BAD_FUNC_ARG;
     6569}
     6570
     6571    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
     6572        WC_TYPE_UNSIGNED_BIN);
     6573}
     6574
     6575/* export ecc key to raw elements including public (Qx,Qy) and
     6576 *   private (d) as unsigned bin
    52896577 * return MP_OKAY on success, negative on error */
    52906578int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
    52916579                              byte* qy, word32* qyLen, byte* d, word32* dLen)
    52926580{
    5293     /* sanitize d and dLen, other args are checked later */
    5294     if (d == NULL || dLen == NULL)
    5295         return BAD_FUNC_ARG;
    5296 
    5297     return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen);
     6581    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
     6582        WC_TYPE_UNSIGNED_BIN);
    52986583}
    52996584
     
    53076592{
    53086593    int ret;
     6594    word32 idx = 0;
     6595
     6596    if (key == NULL || priv == NULL)
     6597        return BAD_FUNC_ARG;
    53096598
    53106599    /* public optional, NULL if only importing private */
    53116600    if (pub != NULL) {
    53126601        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
     6602        if (ret < 0)
     6603            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
    53136604        key->type = ECC_PRIVATEKEY;
    53146605    }
    53156606    else {
    5316         if (key == NULL || priv == NULL)
    5317             return BAD_FUNC_ARG;
    5318 
    53196607        /* make sure required variables are reset */
    53206608        wc_ecc_reset(key);
     
    53286616        return ret;
    53296617
    5330 
    53316618#ifdef WOLFSSL_ATECC508A
    5332     /* TODO: Implement equiv call to ATECC508A */
    5333     return BAD_COND_E;
     6619    /* Hardware does not support loading private keys */
     6620    return NOT_COMPILED_IN;
    53346621
    53356622#else
    53366623
    53376624    ret = mp_read_unsigned_bin(&key->k, priv, privSz);
     6625#ifdef HAVE_WOLF_BIGINT
     6626    if (ret == 0 &&
     6627                  wc_bigint_from_unsigned_bin(&key->k.raw, priv, privSz) != 0) {
     6628        mp_clear(&key->k);
     6629        ret = ASN_GETINT_E;
     6630    }
     6631#endif /* HAVE_WOLF_BIGINT */
     6632
    53386633
    53396634#endif /* WOLFSSL_ATECC508A */
     
    53696664{
    53706665    int err;
    5371     mp_int rtmp;
    5372     mp_int stmp;
     6666#ifdef WOLFSSL_SMALL_STACK
     6667    mp_int* rtmp = NULL;
     6668    mp_int* stmp = NULL;
     6669#else
     6670    mp_int  rtmp[1];
     6671    mp_int  stmp[1];
     6672#endif
    53736673
    53746674    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
    53756675        return ECC_BAD_ARG_E;
    53766676
    5377     err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL);
    5378     if (err != MP_OKAY)
     6677#ifdef WOLFSSL_SMALL_STACK
     6678    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6679    if (rtmp == NULL)
     6680        return MEMORY_E;
     6681    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6682    if (stmp == NULL) {
     6683        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6684        return MEMORY_E;
     6685    }
     6686#endif
     6687
     6688    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
     6689    if (err != MP_OKAY) {
     6690    #ifdef WOLFSSL_SMALL_STACK
     6691        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
     6692        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6693    #endif
    53796694        return err;
    5380 
    5381     err = mp_read_radix(&rtmp, r, 16);
     6695    }
     6696
     6697    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
    53826698    if (err == MP_OKAY)
    5383         err = mp_read_radix(&stmp, s, 16);
     6699        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
    53846700
    53856701    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
    53866702    if (err == MP_OKAY)
    5387         err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp);
     6703        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
    53886704
    53896705    if (err == MP_OKAY) {
    5390         if (mp_iszero(&rtmp) == MP_YES || mp_iszero(&stmp) == MP_YES)
     6706        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
    53916707            err = MP_ZERO_E;
    53926708    }
    53936709
    5394     mp_clear(&rtmp);
    5395     mp_clear(&stmp);
     6710    mp_clear(rtmp);
     6711    mp_clear(stmp);
     6712#ifdef WOLFSSL_SMALL_STACK
     6713    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
     6714    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6715#endif
    53966716
    53976717    return err;
    53986718}
    53996719
     6720/**
     6721   Convert ECC R,S raw unsigned bin to signature
     6722   r       R component of signature
     6723   rSz     R size
     6724   s       S component of signature
     6725   sSz     S size
     6726   out     DER-encoded ECDSA signature
     6727   outlen  [in/out] output buffer size, output signature size
     6728   return  MP_OKAY on success
     6729*/
     6730int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
     6731    byte* out, word32* outlen)
     6732{
     6733    int err;
     6734#ifdef WOLFSSL_SMALL_STACK
     6735    mp_int* rtmp = NULL;
     6736    mp_int* stmp = NULL;
     6737#else
     6738    mp_int  rtmp[1];
     6739    mp_int  stmp[1];
     6740#endif
     6741
     6742    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
     6743        return ECC_BAD_ARG_E;
     6744
     6745#ifdef WOLFSSL_SMALL_STACK
     6746    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6747    if (rtmp == NULL)
     6748        return MEMORY_E;
     6749    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6750    if (stmp == NULL) {
     6751        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6752        return MEMORY_E;
     6753    }
     6754#endif
     6755
     6756    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
     6757    if (err != MP_OKAY) {
     6758    #ifdef WOLFSSL_SMALL_STACK
     6759        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
     6760        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6761    #endif
     6762    return err;
     6763}
     6764
     6765    err = mp_read_unsigned_bin(rtmp, r, rSz);
     6766    if (err == MP_OKAY)
     6767        err = mp_read_unsigned_bin(stmp, s, sSz);
     6768
     6769    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
     6770    if (err == MP_OKAY)
     6771        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
     6772
     6773    if (err == MP_OKAY) {
     6774        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
     6775            err = MP_ZERO_E;
     6776    }
     6777
     6778    mp_clear(rtmp);
     6779    mp_clear(stmp);
     6780#ifdef WOLFSSL_SMALL_STACK
     6781    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
     6782    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6783#endif
     6784
     6785    return err;
     6786}
    54006787
    54016788/**
     
    54146801    int err;
    54156802    word32 x = 0;
    5416     mp_int rtmp;
    5417     mp_int stmp;
     6803#ifdef WOLFSSL_SMALL_STACK
     6804    mp_int* rtmp = NULL;
     6805    mp_int* stmp = NULL;
     6806#else
     6807    mp_int  rtmp[1];
     6808    mp_int  stmp[1];
     6809#endif
    54186810
    54196811    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
    54206812        return ECC_BAD_ARG_E;
    54216813
    5422     err = DecodeECC_DSA_Sig(sig, sigLen, &rtmp, &stmp);
     6814#ifdef WOLFSSL_SMALL_STACK
     6815    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6816    if (rtmp == NULL)
     6817        return MEMORY_E;
     6818    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     6819    if (stmp == NULL) {
     6820        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6821        return MEMORY_E;
     6822    }
     6823#endif
     6824
     6825    err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);
    54236826
    54246827    /* extract r */
    54256828    if (err == MP_OKAY) {
    5426         x = mp_unsigned_bin_size(&rtmp);
     6829        x = mp_unsigned_bin_size(rtmp);
    54276830        if (*rLen < x)
    54286831            err = BUFFER_E;
     
    54306833        if (err == MP_OKAY) {
    54316834            *rLen = x;
    5432             err = mp_to_unsigned_bin(&rtmp, r);
     6835            err = mp_to_unsigned_bin(rtmp, r);
    54336836        }
    54346837    }
     
    54366839    /* extract s */
    54376840    if (err == MP_OKAY) {
    5438         x = mp_unsigned_bin_size(&stmp);
     6841        x = mp_unsigned_bin_size(stmp);
    54396842        if (*sLen < x)
    54406843            err = BUFFER_E;
     
    54426845        if (err == MP_OKAY) {
    54436846            *sLen = x;
    5444             err = mp_to_unsigned_bin(&stmp, s);
     6847            err = mp_to_unsigned_bin(stmp, s);
    54456848        }
    54466849    }
    54476850
    5448     mp_clear(&rtmp);
    5449     mp_clear(&stmp);
     6851    mp_clear(rtmp);
     6852    mp_clear(stmp);
     6853#ifdef WOLFSSL_SMALL_STACK
     6854    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
     6855    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
     6856#endif
    54506857
    54516858    return err;
     
    54556862#ifdef HAVE_ECC_KEY_IMPORT
    54566863static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
    5457           const char* qy, const char* d, int curve_id)
     6864          const char* qy, const char* d, int curve_id, int encType)
    54586865{
    54596866    int err = MP_OKAY;
     
    54726879        return err;
    54736880    }
    5474 
    5475 #ifdef WOLFSSL_ATECC508A
    5476     /* TODO: Implement equiv call to ATECC508A */
    5477     err = BAD_COND_E;
    5478 
    5479 #else
    54806881
    54816882    /* init key */
     
    54966897
    54976898    /* read Qx */
    5498     if (err == MP_OKAY)
    5499         err = mp_read_radix(key->pubkey.x, qx, 16);
     6899    if (err == MP_OKAY) {
     6900        if (encType == WC_TYPE_HEX_STR)
     6901            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
     6902        else
     6903            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
     6904                key->dp->size);
     6905    }
    55006906
    55016907    /* read Qy */
    5502     if (err == MP_OKAY)
    5503         err = mp_read_radix(key->pubkey.y, qy, 16);
     6908    if (err == MP_OKAY) {
     6909        if (encType == WC_TYPE_HEX_STR)
     6910            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
     6911        else
     6912            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
     6913                key->dp->size);
     6914
     6915    }
    55046916
    55056917    if (err == MP_OKAY)
    55066918        err = mp_set(key->pubkey.z, 1);
     6919
     6920#ifdef WOLFSSL_ATECC508A
     6921    /* For SECP256R1 only save raw public key for hardware */
     6922    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
     6923        word32 keySz = key->dp->size;
     6924        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
     6925            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
     6926        if (err == MP_OKAY)
     6927            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
     6928                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
     6929    }
     6930#endif
    55076931
    55086932    /* import private key */
    55096933    if (err == MP_OKAY) {
    55106934        if (d != NULL) {
     6935        #ifdef WOLFSSL_ATECC508A
     6936            /* Hardware doesn't support loading private key */
     6937            err = NOT_COMPILED_IN;
     6938        #else
    55116939            key->type = ECC_PRIVATEKEY;
    5512             err = mp_read_radix(&key->k, d, 16);
     6940
     6941            if (encType == WC_TYPE_HEX_STR)
     6942                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
     6943            else
     6944                err = mp_read_unsigned_bin(&key->k, (const byte*)d,
     6945                    key->dp->size);
     6946        #endif /* WOLFSSL_ATECC508A */
    55136947        } else {
    55146948            key->type = ECC_PUBLICKEY;
     
    55276961        mp_clear(&key->k);
    55286962    }
    5529 #endif /* WOLFSSL_ATECC508A */
    55306963
    55316964    return err;
     
    55456978                   const char* d, int curve_id)
    55466979{
    5547     return wc_ecc_import_raw_private(key, qx, qy, d, curve_id);
    5548 
     6980    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
     6981        WC_TYPE_HEX_STR);
     6982
     6983}
     6984
     6985/* Import x, y and optional private (d) as unsigned binary */
     6986int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
     6987                   byte* d, int curve_id)
     6988{
     6989    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
     6990        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
    55496991}
    55506992
     
    55817023        err = ASN_PARSE_E;
    55827024    } else {
    5583         return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id);
     7025        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
     7026            WC_TYPE_HEX_STR);
    55847027    }
    55857028
     
    55967039}
    55977040
     7041int wc_ecc_sig_size_calc(int sz)
     7042{
     7043    return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
     7044}
    55987045
    55997046/* worst case estimate, check actual return from wc_ecc_sign_hash for actual
     
    56057052        return sz;
    56067053
    5607     return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
     7054    return wc_ecc_sig_size_calc(sz);
    56087055}
    56097056
     
    56337080#endif
    56347081
     7082
     7083#ifndef WOLFSSL_SP_MATH
    56357084
    56367085/** Our FP cache */
     
    61827631};
    61837632
     7633
    61847634/* find a hole and free as required, return -1 if no hole found */
    61857635static int find_hole(void)
     
    62717721   return MP_OKAY;
    62727722}
    6273 
     7723#endif
     7724
     7725#ifndef WOLFSSL_SP_MATH
    62747726/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
    62757727 *
     
    64417893      if (y == 66) --x;
    64427894
    6443       if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
     7895      if ((err = mp_read_radix(&order, ecc_sets[x].order,
     7896                                                MP_RADIX_HEX)) != MP_OKAY) {
    64447897         goto done;
    64457898      }
     
    64927945
    64937946      while ((unsigned)x < y) {
    6494          z = kb[x]; kb[x] = kb[y]; kb[y] = z;
     7947         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
    64957948         ++x; --y;
    64967949      }
     
    65598012   return err;
    65608013}
     8014#endif
    65618015
    65628016#ifdef ECC_SHAMIR
     8017#ifndef WOLFSSL_SP_MATH
    65638018/* perform a fixed point ECC mulmod */
    65648019static int accel_fp_mul2add(int idx1, int idx2,
     
    65928047      if (y == 66) --x;
    65938048
    6594       if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
     8049      if ((err = mp_read_radix(&order, ecc_sets[x].order,
     8050                                                MP_RADIX_HEX)) != MP_OKAY) {
    65958051         goto done;
    65968052      }
     
    66238079      if (y == 66) --x;
    66248080
    6625       if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
     8081      if ((err = mp_read_radix(&order, ecc_sets[x].order,
     8082                                                MP_RADIX_HEX)) != MP_OKAY) {
    66268083         goto done;
    66278084      }
     
    66788135   mp_clear(&tka);
    66798136   while ((unsigned)x < y) {
    6680       z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
     8137      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
    66818138      ++x; --y;
    66828139   }
     
    66998156
    67008157      while ((unsigned)x < y) {
    6701          z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
     8158         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
    67028159         ++x; --y;
    67038160      }
     
    69198376    return err;
    69208377}
     8378#endif
    69218379#endif /* ECC_SHAMIR */
    69228380
     
    69348392    mp_int* modulus, int map, void* heap)
    69358393{
     8394#ifndef WOLFSSL_SP_MATH
    69368395   int   idx, err = MP_OKAY;
    69378396   mp_digit mp;
    69388397   mp_int   mu;
    69398398   int      mpSetup = 0;
     8399
     8400   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
     8401       return ECC_BAD_ARG_E;
     8402   }
    69408403
    69418404   if (mp_init(&mu) != MP_OKAY)
     
    70068469
    70078470    return err;
    7008 }
    7009 
     8471#else
     8472    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
     8473        return ECC_BAD_ARG_E;
     8474    }
     8475
     8476    return sp_ecc_mulmod_256(k, G, R, map, heap);
     8477#endif
     8478}
     8479
     8480#ifndef WOLFSSL_SP_MATH
    70108481/* helper function for freeing the cache ...
    70118482   must be called with the cache mutex locked */
     
    70278498   }
    70288499}
     8500#endif
    70298501
    70308502/** Free the Fixed Point cache */
    70318503void wc_ecc_fp_free(void)
    70328504{
     8505#ifndef WOLFSSL_SP_MATH
    70338506#ifndef HAVE_THREAD_LS
    70348507   if (initMutex == 0) {
     
    70488521   }
    70498522#endif /* HAVE_THREAD_LS */
     8523#endif
    70508524}
    70518525
     
    74078881               {
    74088882                   Aes aes;
     8883                   ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
     8884                   if (ret == 0) {
    74098885                   ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
    74108886                                                                AES_ENCRYPTION);
    7411                    if (ret != 0)
    7412                        break;
     8887                       if (ret == 0) {
    74138888                   ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
    74148889                #if defined(WOLFSSL_ASYNC_CRYPT)
    7415                    ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
     8890                           ret = wc_AsyncWait(ret, &aes.asyncDev,
     8891                                              WC_ASYNC_FLAG_NONE);
    74168892                #endif
     8893               }
     8894                       wc_AesFree(&aes);
     8895                   }
     8896                   if (ret != 0)
     8897                      break;
    74178898               }
    74188899               break;
     
    76379118#ifndef WOLFSSL_ATECC508A
    76389119
     9120#ifndef WOLFSSL_SP_MATH
    76399121int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
    76409122
     
    77609242int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
    77619243{
     9244#ifdef SQRTMOD_USE_MOD_EXP
     9245  int res;
     9246
     9247  mp_int e;
     9248
     9249  res = mp_init(&e);
     9250  if (res == MP_OKAY)
     9251      res = mp_add_d(prime, 1, &e);
     9252  if (res == MP_OKAY)
     9253      res = mp_div_2d(&e, 2, &e, NULL);
     9254  if (res == MP_OKAY)
     9255      res = mp_exptmod(n, &e, prime, ret);
     9256
     9257  mp_clear(&e);
     9258
     9259  return res;
     9260#else
    77629261  int res, legendre, done = 0;
    77639262  mp_int t1, C, Q, S, Z, M, T, R, two;
     
    79389437
    79399438  return res;
    7940 }
     9439#endif
     9440}
     9441#endif
    79419442#endif /* !WOLFSSL_ATECC508A */
    79429443
     
    79619462   }
    79629463
    7963 #ifdef WOLFSSL_ATECC508A
    7964    /* TODO: Implement equiv call to ATECC508A */
    7965    ret = BAD_COND_E;
    7966 
    7967 #else
    7968 
    79699464   /* store first byte */
    7970    out[0] = mp_isodd(key->pubkey.y) == MP_YES ? 0x03 : 0x02;
     9465   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
    79719466
    79729467   /* pad and store x */
     
    79759470                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
    79769471   *outLen = 1 + numlen;
    7977 
    7978 #endif /* WOLFSSL_ATECC508A */
    79799472
    79809473   return ret;
     
    80459538#ifdef HAVE_X963_KDF
    80469539
    8047 static INLINE void IncrementX963KdfCounter(byte* inOutCtr)
     9540static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
    80489541{
    80499542    int i;
     
    81109603        ret = wc_HashUpdate(hash, type, secret, secretSz);
    81119604        if (ret != 0) {
    8112 #ifdef WOLFSSL_SMALL_STACK
    8113             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
    8114 #endif
    8115             return ret;
     9605            break;
    81169606        }
    81179607
    81189608        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
    81199609        if (ret != 0) {
    8120 #ifdef WOLFSSL_SMALL_STACK
    8121             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
    8122 #endif
    8123             return ret;
     9610            break;
    81249611        }
    81259612
     
    81279614            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
    81289615            if (ret != 0) {
    8129 #ifdef WOLFSSL_SMALL_STACK
    8130                 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
    8131 #endif
    8132                 return ret;
     9616                break;
    81339617            }
    81349618        }
     
    81369620        ret = wc_HashFinal(hash, type, tmp);
    81379621        if (ret != 0) {
    8138 #ifdef WOLFSSL_SMALL_STACK
    8139             XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
    8140 #endif
    8141             return ret;
     9622            break;
    81429623        }
    81439624
     
    81499630    }
    81509631
     9632    wc_HashFree(hash, type);
     9633
    81519634#ifdef WOLFSSL_SMALL_STACK
    81529635     XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
    81539636#endif
    81549637
    8155     return 0;
     9638    return ret;
    81569639}
    81579640#endif /* HAVE_X963_KDF */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/error.c

    r352 r372  
    3434#endif
    3535
     36#ifndef NO_ERROR_STRINGS
    3637const char* wc_GetErrorString(int error)
    3738{
    38 #ifdef NO_ERROR_STRINGS
    39 
    40     (void)error;
    41     return "no support for error strings built in";
    42 
    43 #else
    44 
    4539    switch (error) {
    4640
     
    207201        return "X.509 Critical extension ignored or invalid";
    208202
     203    case ASN_ALT_NAME_E:
     204        return "ASN alternate name error";
     205
    209206    case ECC_BAD_ARG_E :
    210207        return "ECC input argument wrong type, invalid input";
     
    267264        return "ASN OCSP sig error, confirm failure";
    268265
     266    case ASN_NO_PEM_HEADER:
     267        return "ASN no PEM Header Error";
     268
    269269    case BAD_STATE_E:
    270270        return "Bad state operation";
     
    282282        return "PKCS#7 error: no matching recipient found";
    283283
     284    case WC_PKCS7_WANT_READ_E:
     285        return "PKCS#7 operations wants more input, call again";
     286
    284287    case FIPS_NOT_ALLOWED_E:
    285288        return "FIPS mode not allowed error";
     
    435438        return "Invalid use of private only ECC key";
    436439
     440    case WC_HW_E:
     441        return "Error with hardware crypto use";
     442
     443    case WC_HW_WAIT_E:
     444        return "Hardware waiting on resource";
     445
     446    case PSS_SALTLEN_E:
     447        return "PSS - Length of salt is too big for hash algorithm";
     448
     449    case PRIME_GEN_E:
     450        return "Unable to find a prime for RSA key";
     451
     452    case BER_INDEF_E:
     453        return "Unable to decode an indefinite length encoded message";
     454
     455    case RSA_OUT_OF_RANGE_E:
     456        return "Ciphertext to decrypt is out of range";
     457
     458    case RSAPSS_PAT_FIPS_E:
     459        return "wolfcrypt FIPS RSA-PSS Pairwise Agreement Test Failure";
     460
     461    case ECDSA_PAT_FIPS_E:
     462        return "wolfcrypt FIPS ECDSA Pairwise Agreement Test Failure";
     463
     464    case DH_KAT_FIPS_E:
     465        return "wolfcrypt FIPS DH Known Answer Test Failure";
     466
     467    case AESCCM_KAT_FIPS_E:
     468        return "AESCCM Known Answer Test check FIPS error";
     469
     470    case SHA3_KAT_FIPS_E:
     471        return "SHA-3 Known Answer Test check FIPS error";
     472
     473    case ECDHE_KAT_FIPS_E:
     474        return "wolfcrypt FIPS ECDHE Known Answer Test Failure";
     475
     476    case AES_GCM_OVERFLOW_E:
     477        return "AES-GCM invocation counter overflow";
     478
     479    case AES_CCM_OVERFLOW_E:
     480        return "AES-CCM invocation counter overflow";
     481
     482    case RSA_KEY_PAIR_E:
     483        return "RSA Key Pair-Wise Consistency check fail";
     484
     485    case DH_CHECK_PRIV_E:
     486        return "DH Check Private Key failure";
     487
     488    case WC_AFALG_SOCK_E:
     489        return "AF_ALG socket error";
     490
     491    case WC_DEVCRYPTO_E:
     492        return "Error with /dev/crypto";
     493
     494    case ZLIB_INIT_ERROR:
     495        return "zlib init error";
     496
     497    case ZLIB_COMPRESS_ERROR:
     498        return "zlib compress error";
     499
     500    case ZLIB_DECOMPRESS_ERROR:
     501        return "zlib decompress error";
     502
     503    case PKCS7_NO_SIGNER_E:
     504        return "No signer in PKCS#7 signed data";
     505
    437506    default:
    438507        return "unknown error number";
    439508
    440509    }
    441 
    442 #endif /* NO_ERROR_STRINGS */
    443 
    444510}
    445511
     
    448514    XSTRNCPY(buffer, wc_GetErrorString(error), WOLFSSL_MAX_ERROR_SZ);
    449515}
     516#endif /* !NO_ERROR_STRINGS */
     517
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hash.c

    r352 r372  
    4747    SHA512h = 416
    4848};
    49 #endif
     49#endif /* !NO_ASN */
     50
     51#ifdef HAVE_SELFTEST
     52enum {
     53    /* CAVP selftest includes these in hmac.h instead of sha3.h,
     54       copied here for that build */
     55    WC_SHA3_224_BLOCK_SIZE = 144,
     56    WC_SHA3_256_BLOCK_SIZE = 136,
     57    WC_SHA3_384_BLOCK_SIZE = 104,
     58    WC_SHA3_512_BLOCK_SIZE = 72,
     59};
     60#endif
     61
     62
     63/* function converts int hash type to enum */
     64enum wc_HashType wc_HashTypeConvert(int hashType)
     65{
     66    /* Default to hash type none as error */
     67    enum wc_HashType eHashType = WC_HASH_TYPE_NONE;
     68#if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
     69    /* original FIPSv1  and CAVP selftest require a mapping for unique hash
     70       type to wc_HashType */
     71    switch (hashType) {
     72    #ifndef NO_MD5
     73        case WC_MD5:
     74            eHashType = WC_HASH_TYPE_MD5;
     75            break;
     76    #endif /* !NO_MD5 */
     77    #ifndef NO_SHA
     78        case WC_SHA:
     79            eHashType = WC_HASH_TYPE_SHA;
     80            break;
     81    #endif /* !NO_SHA */
     82
     83    #ifdef WOLFSSL_SHA224
     84        case WC_SHA224:
     85            eHashType = WC_HASH_TYPE_SHA224;
     86            break;
     87    #endif /* WOLFSSL_SHA224 */
     88
     89    #ifndef NO_SHA256
     90        case WC_SHA256:
     91            eHashType = WC_HASH_TYPE_SHA256;
     92            break;
     93    #endif /* !NO_SHA256 */
     94
     95    #ifdef WOLFSSL_SHA384
     96        case WC_SHA384:
     97            eHashType = WC_HASH_TYPE_SHA384;
     98            break;
     99    #endif /* WOLFSSL_SHA384 */
     100    #ifdef WOLFSSL_SHA512
     101        case WC_SHA512:
     102            eHashType = WC_HASH_TYPE_SHA512;
     103            break;
     104    #endif /* WOLFSSL_SHA512 */
     105        default:
     106            eHashType = WC_HASH_TYPE_NONE;
     107            break;
     108    }
     109#else
     110    /* current master uses same unique types as wc_HashType */
     111    if (hashType > 0 && hashType <= WC_HASH_TYPE_MAX) {
     112        eHashType = (enum wc_HashType)hashType;
     113    }
     114#endif
     115    return eHashType;
     116}
     117
    50118
    51119int wc_HashGetOID(enum wc_HashType hash_type)
     
    71139            break;
    72140        case WC_HASH_TYPE_SHA224:
    73         #if defined(WOLFSSL_SHA224)
     141        #ifdef WOLFSSL_SHA224
    74142            oid = SHA224h;
    75143        #endif
     
    81149            break;
    82150        case WC_HASH_TYPE_SHA384:
    83         #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384)
     151        #ifdef WOLFSSL_SHA384
    84152            oid = SHA384h;
    85153        #endif
     
    93161        /* Not Supported */
    94162        case WC_HASH_TYPE_MD4:
     163        case WC_HASH_TYPE_SHA3_224:
     164        case WC_HASH_TYPE_SHA3_256:
     165        case WC_HASH_TYPE_SHA3_384:
     166        case WC_HASH_TYPE_SHA3_512:
     167        case WC_HASH_TYPE_BLAKE2B:
    95168        case WC_HASH_TYPE_NONE:
    96169        default:
     
    100173    return oid;
    101174}
    102 #endif
     175
     176enum wc_HashType wc_OidGetHash(int oid)
     177{
     178    enum wc_HashType hash_type = WC_HASH_TYPE_NONE;
     179    switch (oid)
     180    {
     181    #ifdef WOLFSSL_MD2
     182        case MD2h:
     183            hash_type = WC_HASH_TYPE_MD2;
     184            break;
     185    #endif
     186        case MD5h:
     187        #ifndef NO_MD5
     188            hash_type = WC_HASH_TYPE_MD5;
     189#endif
     190            break;
     191        case SHAh:
     192        #ifndef NO_SHA
     193            hash_type = WC_HASH_TYPE_SHA;
     194        #endif
     195            break;
     196        case SHA224h:
     197        #ifdef WOLFSSL_SHA224
     198            hash_type = WC_HASH_TYPE_SHA224;
     199        #endif
     200            break;
     201        case SHA256h:
     202        #ifndef NO_SHA256
     203            hash_type = WC_HASH_TYPE_SHA256;
     204        #endif
     205            break;
     206        case SHA384h:
     207        #ifdef WOLFSSL_SHA384
     208            hash_type = WC_HASH_TYPE_SHA384;
     209        #endif
     210            break;
     211        case SHA512h:
     212        #ifdef WOLFSSL_SHA512
     213            hash_type = WC_HASH_TYPE_SHA512;
     214        #endif
     215            break;
     216        default:
     217            break;
     218    }
     219    return hash_type;
     220}
     221#endif /* !NO_ASN || !NO_DH || HAVE_ECC */
     222
     223
    103224
    104225/* Get Hash digest size */
     
    108229    switch(hash_type)
    109230    {
     231        case WC_HASH_TYPE_MD2:
     232        #ifdef WOLFSSL_MD2
     233            dig_size = MD2_DIGEST_SIZE;
     234        #endif
     235            break;
     236        case WC_HASH_TYPE_MD4:
     237        #ifndef NO_MD4
     238            dig_size = MD4_DIGEST_SIZE;
     239        #endif
     240            break;
    110241        case WC_HASH_TYPE_MD5:
    111242#ifndef NO_MD5
     
    129260            break;
    130261        case WC_HASH_TYPE_SHA384:
    131 #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384)
     262        #ifdef WOLFSSL_SHA384
    132263            dig_size = WC_SHA384_DIGEST_SIZE;
    133264#endif
     
    138269#endif
    139270            break;
    140         case WC_HASH_TYPE_MD5_SHA:
     271        case WC_HASH_TYPE_MD5_SHA: /* Old TLS Specific */
    141272#if !defined(NO_MD5) && !defined(NO_SHA)
    142             dig_size = WC_MD5_DIGEST_SIZE + WC_SHA_DIGEST_SIZE;
     273            dig_size = (int)WC_MD5_DIGEST_SIZE + (int)WC_SHA_DIGEST_SIZE;
     274        #endif
     275            break;
     276
     277        case WC_HASH_TYPE_SHA3_224:
     278        #ifdef WOLFSSL_SHA3
     279            dig_size = WC_SHA3_224_DIGEST_SIZE;
     280        #endif
     281            break;
     282        case WC_HASH_TYPE_SHA3_256:
     283        #ifdef WOLFSSL_SHA3
     284            dig_size = WC_SHA3_256_DIGEST_SIZE;
     285        #endif
     286            break;
     287        case WC_HASH_TYPE_SHA3_384:
     288        #ifdef WOLFSSL_SHA3
     289            dig_size = WC_SHA3_384_DIGEST_SIZE;
     290        #endif
     291            break;
     292        case WC_HASH_TYPE_SHA3_512:
     293        #ifdef WOLFSSL_SHA3
     294            dig_size = WC_SHA3_512_DIGEST_SIZE;
    143295#endif
    144296            break;
    145297
    146298        /* Not Supported */
    147         case WC_HASH_TYPE_MD2:
    148         case WC_HASH_TYPE_MD4:
     299        case WC_HASH_TYPE_BLAKE2B:
    149300        case WC_HASH_TYPE_NONE:
    150301        default:
     
    153304    }
    154305    return dig_size;
     306}
     307
     308
     309/* Get Hash block size */
     310int wc_HashGetBlockSize(enum wc_HashType hash_type)
     311{
     312    int block_size = HASH_TYPE_E; /* Default to hash type error */
     313    switch (hash_type)
     314    {
     315        case WC_HASH_TYPE_MD2:
     316        #ifdef WOLFSSL_MD2
     317            block_size = MD2_BLOCK_SIZE;
     318        #endif
     319            break;
     320        case WC_HASH_TYPE_MD4:
     321        #ifndef NO_MD4
     322            block_size = MD4_BLOCK_SIZE;
     323        #endif
     324            break;
     325        case WC_HASH_TYPE_MD5:
     326        #ifndef NO_MD5
     327            block_size = WC_MD5_BLOCK_SIZE;
     328        #endif
     329            break;
     330        case WC_HASH_TYPE_SHA:
     331        #ifndef NO_SHA
     332            block_size = WC_SHA_BLOCK_SIZE;
     333        #endif
     334            break;
     335        case WC_HASH_TYPE_SHA224:
     336        #ifdef WOLFSSL_SHA224
     337            block_size = WC_SHA224_BLOCK_SIZE;
     338        #endif
     339            break;
     340        case WC_HASH_TYPE_SHA256:
     341        #ifndef NO_SHA256
     342            block_size = WC_SHA256_BLOCK_SIZE;
     343        #endif
     344            break;
     345        case WC_HASH_TYPE_SHA384:
     346        #ifdef WOLFSSL_SHA384
     347            block_size = WC_SHA384_BLOCK_SIZE;
     348        #endif
     349            break;
     350        case WC_HASH_TYPE_SHA512:
     351        #ifdef WOLFSSL_SHA512
     352            block_size = WC_SHA512_BLOCK_SIZE;
     353        #endif
     354            break;
     355        case WC_HASH_TYPE_MD5_SHA: /* Old TLS Specific */
     356        #if !defined(NO_MD5) && !defined(NO_SHA)
     357            block_size = (int)WC_MD5_BLOCK_SIZE + (int)WC_SHA_BLOCK_SIZE;
     358        #endif
     359            break;
     360
     361        case WC_HASH_TYPE_SHA3_224:
     362        #ifdef WOLFSSL_SHA3
     363            block_size = WC_SHA3_224_BLOCK_SIZE;
     364        #endif
     365            break;
     366        case WC_HASH_TYPE_SHA3_256:
     367        #ifdef WOLFSSL_SHA3
     368            block_size = WC_SHA3_256_BLOCK_SIZE;
     369        #endif
     370            break;
     371        case WC_HASH_TYPE_SHA3_384:
     372        #ifdef WOLFSSL_SHA3
     373            block_size = WC_SHA3_384_BLOCK_SIZE;
     374        #endif
     375            break;
     376        case WC_HASH_TYPE_SHA3_512:
     377        #ifdef WOLFSSL_SHA3
     378            block_size = WC_SHA3_512_BLOCK_SIZE;
     379        #endif
     380            break;
     381
     382        /* Not Supported */
     383        case WC_HASH_TYPE_BLAKE2B:
     384        case WC_HASH_TYPE_NONE:
     385        default:
     386            block_size = BAD_FUNC_ARG;
     387            break;
     388    }
     389    return block_size;
    155390}
    156391
     
    197432            break;
    198433        case WC_HASH_TYPE_SHA384:
    199 #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384)
     434#ifdef WOLFSSL_SHA384
    200435            ret = wc_Sha384Hash(data, data_len, hash);
    201436#endif
     
    218453        case WC_HASH_TYPE_MD2:
    219454        case WC_HASH_TYPE_MD4:
     455        case WC_HASH_TYPE_SHA3_224:
     456        case WC_HASH_TYPE_SHA3_256:
     457        case WC_HASH_TYPE_SHA3_384:
     458        case WC_HASH_TYPE_SHA3_512:
     459        case WC_HASH_TYPE_BLAKE2B:
    220460        case WC_HASH_TYPE_NONE:
    221461        default:
     
    236476        case WC_HASH_TYPE_MD5:
    237477#ifndef NO_MD5
    238             wc_InitMd5(&hash->md5);
    239             ret = 0;
     478            ret = wc_InitMd5(&hash->md5);
    240479#endif
    241480            break;
     
    270509        case WC_HASH_TYPE_MD2:
    271510        case WC_HASH_TYPE_MD4:
     511        case WC_HASH_TYPE_SHA3_224:
     512        case WC_HASH_TYPE_SHA3_256:
     513        case WC_HASH_TYPE_SHA3_384:
     514        case WC_HASH_TYPE_SHA3_512:
     515        case WC_HASH_TYPE_BLAKE2B:
    272516        case WC_HASH_TYPE_NONE:
    273517        default:
     
    289533        case WC_HASH_TYPE_MD5:
    290534#ifndef NO_MD5
    291             wc_Md5Update(&hash->md5, data, dataSz);
    292             ret = 0;
     535            ret = wc_Md5Update(&hash->md5, data, dataSz);
    293536#endif
    294537            break;
     
    296539#ifndef NO_SHA
    297540            ret = wc_ShaUpdate(&hash->sha, data, dataSz);
    298             if (ret != 0)
    299                 return ret;
    300541#endif
    301542            break;
     
    325566        case WC_HASH_TYPE_MD2:
    326567        case WC_HASH_TYPE_MD4:
     568        case WC_HASH_TYPE_SHA3_224:
     569        case WC_HASH_TYPE_SHA3_256:
     570        case WC_HASH_TYPE_SHA3_384:
     571        case WC_HASH_TYPE_SHA3_512:
     572        case WC_HASH_TYPE_BLAKE2B:
    327573        case WC_HASH_TYPE_NONE:
    328574        default:
     
    343589        case WC_HASH_TYPE_MD5:
    344590#ifndef NO_MD5
    345             wc_Md5Final(&hash->md5, out);
    346             ret = 0;
     591            ret = wc_Md5Final(&hash->md5, out);
    347592#endif
    348593            break;
     
    377622        case WC_HASH_TYPE_MD2:
    378623        case WC_HASH_TYPE_MD4:
     624        case WC_HASH_TYPE_SHA3_224:
     625        case WC_HASH_TYPE_SHA3_256:
     626        case WC_HASH_TYPE_SHA3_384:
     627        case WC_HASH_TYPE_SHA3_512:
     628        case WC_HASH_TYPE_BLAKE2B:
    379629        case WC_HASH_TYPE_NONE:
    380630        default:
     
    385635}
    386636
     637int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type)
     638{
     639    int ret = HASH_TYPE_E; /* Default to hash type error */
     640
     641    if (hash == NULL)
     642        return BAD_FUNC_ARG;
     643
     644    switch (type) {
     645        case WC_HASH_TYPE_MD5:
     646#ifndef NO_MD5
     647            wc_Md5Free(&hash->md5);
     648            ret = 0;
     649#endif
     650            break;
     651        case WC_HASH_TYPE_SHA:
     652#ifndef NO_SHA
     653            wc_ShaFree(&hash->sha);
     654            ret = 0;
     655#endif
     656            break;
     657        case WC_HASH_TYPE_SHA224:
     658#ifdef WOLFSSL_SHA224
     659            wc_Sha224Free(&hash->sha224);
     660            ret = 0;
     661#endif
     662            break;
     663        case WC_HASH_TYPE_SHA256:
     664#ifndef NO_SHA256
     665            wc_Sha256Free(&hash->sha256);
     666            ret = 0;
     667#endif
     668            break;
     669        case WC_HASH_TYPE_SHA384:
     670#ifdef WOLFSSL_SHA384
     671            wc_Sha384Free(&hash->sha384);
     672            ret = 0;
     673#endif
     674            break;
     675        case WC_HASH_TYPE_SHA512:
     676#ifdef WOLFSSL_SHA512
     677            wc_Sha512Free(&hash->sha512);
     678            ret = 0;
     679#endif
     680            break;
     681
     682        /* not supported */
     683        case WC_HASH_TYPE_MD5_SHA:
     684        case WC_HASH_TYPE_MD2:
     685        case WC_HASH_TYPE_MD4:
     686        case WC_HASH_TYPE_SHA3_224:
     687        case WC_HASH_TYPE_SHA3_256:
     688        case WC_HASH_TYPE_SHA3_384:
     689        case WC_HASH_TYPE_SHA3_512:
     690        case WC_HASH_TYPE_BLAKE2B:
     691        case WC_HASH_TYPE_NONE:
     692        default:
     693            ret = BAD_FUNC_ARG;
     694    };
     695
     696    return ret;
     697}
     698
    387699
    388700#if !defined(WOLFSSL_TI_HASH)
     
    404716    #endif
    405717
    406         ret = wc_InitMd5(md5);
    407         if (ret == 0) {
    408             ret = wc_Md5Update(md5, data, len);
    409             if (ret == 0) {
    410                 ret = wc_Md5Final(md5, hash);
     718        if ((ret = wc_InitMd5(md5)) != 0) {
     719            WOLFSSL_MSG("InitMd5 failed");
     720        }
     721        else {
     722            if ((ret = wc_Md5Update(md5, data, len)) != 0) {
     723                WOLFSSL_MSG("Md5Update failed");
    411724            }
     725            else if ((ret = wc_Md5Final(md5, hash)) != 0) {
     726                WOLFSSL_MSG("Md5Final failed");
     727            }
     728            wc_Md5Free(md5);
    412729        }
    413730
     
    437754
    438755        if ((ret = wc_InitSha(sha)) != 0) {
    439             WOLFSSL_MSG("wc_InitSha failed");
     756            WOLFSSL_MSG("InitSha failed");
    440757        }
    441758        else {
    442             wc_ShaUpdate(sha, data, len);
    443             wc_ShaFinal(sha, hash);
     759            if ((ret = wc_ShaUpdate(sha, data, len)) != 0) {
     760                WOLFSSL_MSG("ShaUpdate failed");
     761            }
     762            else if ((ret = wc_ShaFinal(sha, hash)) != 0) {
     763                WOLFSSL_MSG("ShaFinal failed");
     764            }
     765            wc_ShaFree(sha);
    444766        }
    445767
     
    472794        WOLFSSL_MSG("InitSha224 failed");
    473795    }
    474     else if ((ret = wc_Sha224Update(sha224, data, len)) != 0) {
     796        else {
     797            if ((ret = wc_Sha224Update(sha224, data, len)) != 0) {
    475798        WOLFSSL_MSG("Sha224Update failed");
    476799    }
     
    478801        WOLFSSL_MSG("Sha224Final failed");
    479802    }
     803            wc_Sha224Free(sha224);
     804        }
    480805
    481806#ifdef WOLFSSL_SMALL_STACK
     
    507832            WOLFSSL_MSG("InitSha256 failed");
    508833        }
    509         else if ((ret = wc_Sha256Update(sha256, data, len)) != 0) {
     834        else {
     835            if ((ret = wc_Sha256Update(sha256, data, len)) != 0) {
    510836            WOLFSSL_MSG("Sha256Update failed");
    511837        }
     
    513839            WOLFSSL_MSG("Sha256Final failed");
    514840        }
     841            wc_Sha256Free(sha256);
     842        }
     843
    515844
    516845    #ifdef WOLFSSL_SMALL_STACK
     
    545874            WOLFSSL_MSG("InitSha512 failed");
    546875        }
    547         else if ((ret = wc_Sha512Update(sha512, data, len)) != 0) {
     876        else {
     877            if ((ret = wc_Sha512Update(sha512, data, len)) != 0) {
    548878            WOLFSSL_MSG("Sha512Update failed");
    549879        }
     
    551881            WOLFSSL_MSG("Sha512Final failed");
    552882        }
     883            wc_Sha512Free(sha512);
     884        }
    553885
    554886    #ifdef WOLFSSL_SMALL_STACK
     
    558890        return ret;
    559891    }
     892#endif /* WOLFSSL_SHA512 */
    560893
    561894    #if defined(WOLFSSL_SHA384)
     
    579912                WOLFSSL_MSG("InitSha384 failed");
    580913            }
    581             else if ((ret = wc_Sha384Update(sha384, data, len)) != 0) {
     914        else {
     915            if ((ret = wc_Sha384Update(sha384, data, len)) != 0) {
    582916                WOLFSSL_MSG("Sha384Update failed");
    583917            }
     
    585919                WOLFSSL_MSG("Sha384Final failed");
    586920            }
     921            wc_Sha384Free(sha384);
     922        }
    587923
    588924        #ifdef WOLFSSL_SMALL_STACK
     
    593929        }
    594930    #endif /* WOLFSSL_SHA384 */
    595 #endif /* WOLFSSL_SHA512 */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hc128.c

    r352 r372  
    273273
    274274
    275 static INLINE int DoKey(HC128* ctx, const byte* key, const byte* iv)
     275static WC_INLINE int DoKey(HC128* ctx, const byte* key, const byte* iv)
    276276{
    277277  word32 i;
     
    336336
    337337/* The following defines the encryption of data stream */
    338 static INLINE int DoProcess(HC128* ctx, byte* output, const byte* input,
     338static WC_INLINE int DoProcess(HC128* ctx, byte* output, const byte* input,
    339339                            word32 msglen)
    340340{
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hmac.c

    r352 r372  
    1 /* hmac.h
     1/* hmac.c
    22 *
    33 * Copyright (C) 2006-2017 wolfSSL Inc.
     
    3030#ifndef NO_HMAC
    3131
     32#if defined(HAVE_FIPS) && \
     33    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     34
     35    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     36    #define FIPS_NO_WRAPPERS
     37
     38    #ifdef USE_WINDOWS_API
     39        #pragma code_seg(".fipsA$b")
     40        #pragma const_seg(".fipsB$b")
     41    #endif
     42#endif
     43
    3244#include <wolfssl/wolfcrypt/hmac.h>
    3345
     
    4153
    4254/* fips wrapper calls, user can call direct */
    43 #ifdef HAVE_FIPS
     55/* If building for old FIPS. */
     56#if defined(HAVE_FIPS) && \
     57    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     58
    4459    /* does init */
    4560    int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
     
    4762        if (hmac == NULL || (key == NULL && keySz != 0) ||
    4863           !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||
    49                 type == WC_SHA384 || type == WC_SHA512 || type == BLAKE2B_ID)) {
     64                type == WC_SHA384 || type == WC_SHA512 ||
     65                type == BLAKE2B_ID)) {
    5066            return BAD_FUNC_ARG;
    5167        }
     
    101117    #endif /* HAVE_HKDF */
    102118
    103 #else /* else build without fips */
    104 
    105 
    106 #include <wolfssl/wolfcrypt/error-crypt.h>
     119#else /* else build without fips, or for new fips */
    107120
    108121
     
    111124    int ret;
    112125
    113     if (!(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
    114             type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
     126    if (!(type == WC_MD5 || type == WC_SHA ||
     127            type == WC_SHA224 || type == WC_SHA256 ||
     128            type == WC_SHA384 || type == WC_SHA512 ||
     129            type == WC_SHA3_224 || type == WC_SHA3_256 ||
     130            type == WC_SHA3_384 || type == WC_SHA3_512 ||
    115131            type == BLAKE2B_ID)) {
    116132        return BAD_FUNC_ARG;
     
    142158    #endif /* !NO_SHA256 */
    143159
    144     #ifdef WOLFSSL_SHA512
    145160    #ifdef WOLFSSL_SHA384
    146161        case WC_SHA384:
     
    148163            break;
    149164    #endif /* WOLFSSL_SHA384 */
     165    #ifdef WOLFSSL_SHA512
    150166        case WC_SHA512:
    151167            ret = WC_SHA512_DIGEST_SIZE;
     
    159175    #endif /* HAVE_BLAKE2 */
    160176
     177    #ifdef WOLFSSL_SHA3
     178        case WC_SHA3_224:
     179            ret = WC_SHA3_224_DIGEST_SIZE;
     180            break;
     181
     182        case WC_SHA3_256:
     183            ret = WC_SHA3_256_DIGEST_SIZE;
     184            break;
     185
     186        case WC_SHA3_384:
     187            ret = WC_SHA3_384_DIGEST_SIZE;
     188            break;
     189
     190        case WC_SHA3_512:
     191            ret = WC_SHA3_512_DIGEST_SIZE;
     192            break;
     193
     194    #endif
     195
    161196        default:
    162197            ret = BAD_FUNC_ARG;
     
    167202}
    168203
    169 static int _InitHmac(Hmac* hmac, int type, void* heap)
     204int _InitHmac(Hmac* hmac, int type, void* heap)
    170205{
    171206    int ret = 0;
     
    196231    #endif /* !NO_SHA256 */
    197232
    198     #ifdef WOLFSSL_SHA512
    199233    #ifdef WOLFSSL_SHA384
    200234        case WC_SHA384:
     
    202236            break;
    203237    #endif /* WOLFSSL_SHA384 */
     238    #ifdef WOLFSSL_SHA512
    204239        case WC_SHA512:
    205240            ret = wc_InitSha512(&hmac->hash.sha512);
     
    212247            break;
    213248    #endif /* HAVE_BLAKE2 */
     249
     250    #ifdef WOLFSSL_SHA3
     251        case WC_SHA3_224:
     252            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
     253            break;
     254        case WC_SHA3_256:
     255            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
     256            break;
     257        case WC_SHA3_384:
     258            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
     259            break;
     260        case WC_SHA3_512:
     261            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
     262            break;
     263    #endif
    214264
    215265        default:
     
    238288
    239289    if (hmac == NULL || (key == NULL && length != 0) ||
    240         !(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
    241             type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
     290       !(type == WC_MD5 || type == WC_SHA ||
     291            type == WC_SHA224 || type == WC_SHA256 ||
     292            type == WC_SHA384 || type == WC_SHA512 ||
     293            type == WC_SHA3_224 || type == WC_SHA3_256 ||
     294            type == WC_SHA3_384 || type == WC_SHA3_512 ||
    242295            type == BLAKE2B_ID)) {
    243296        return BAD_FUNC_ARG;
    244297    }
    245298
     299    /* if set key has already been run then make sure and free existing */
     300    if (hmac->macType != 0) {
     301        wc_HmacFree(hmac);
     302        }
     303
    246304    hmac->innerHashKeyed = 0;
    247305    hmac->macType = (byte)type;
    248 
    249 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
    250     if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
    251     #if defined(HAVE_CAVIUM)
    252         if (length > HMAC_BLOCK_SIZE) {
    253             return WC_KEY_SIZE_E;
    254         }
    255 
    256         if (key != NULL) {
    257             XMEMCPY(hmac->ipad, key, length);
    258         }
    259         hmac->keyLen = (word16)length;
    260 
    261         return 0; /* nothing to do here */
    262     #endif /* HAVE_CAVIUM */
    263     }
    264 #endif /* WOLFSSL_ASYNC_CRYPT */
    265306
    266307    ret = _InitHmac(hmac, type, heap);
     
    362403    #endif /* !NO_SHA256 */
    363404
    364     #ifdef WOLFSSL_SHA512
    365405    #ifdef WOLFSSL_SHA384
    366406        case WC_SHA384:
     
    383423            break;
    384424    #endif /* WOLFSSL_SHA384 */
     425    #ifdef WOLFSSL_SHA512
    385426        case WC_SHA512:
    386427            hmac_block_size = WC_SHA512_BLOCK_SIZE;
     
    424465    #endif /* HAVE_BLAKE2 */
    425466
     467    #ifdef WOLFSSL_SHA3
     468        case WC_SHA3_224:
     469            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
     470            if (length <= WC_SHA3_224_BLOCK_SIZE) {
     471                if (key != NULL) {
     472                    XMEMCPY(ip, key, length);
     473                }
     474            }
     475            else {
     476                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
     477                if (ret != 0)
     478                    break;
     479                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
     480                if (ret != 0)
     481                    break;
     482
     483                length = WC_SHA3_224_DIGEST_SIZE;
     484            }
     485            break;
     486        case WC_SHA3_256:
     487            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
     488            if (length <= WC_SHA3_256_BLOCK_SIZE) {
     489                if (key != NULL) {
     490                    XMEMCPY(ip, key, length);
     491                }
     492            }
     493            else {
     494                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
     495                if (ret != 0)
     496                    break;
     497                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
     498                if (ret != 0)
     499                    break;
     500
     501                length = WC_SHA3_256_DIGEST_SIZE;
     502            }
     503            break;
     504        case WC_SHA3_384:
     505            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
     506            if (length <= WC_SHA3_384_BLOCK_SIZE) {
     507                if (key != NULL) {
     508                    XMEMCPY(ip, key, length);
     509                }
     510            }
     511            else {
     512                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
     513                if (ret != 0)
     514                    break;
     515                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
     516                if (ret != 0)
     517                    break;
     518
     519                length = WC_SHA3_384_DIGEST_SIZE;
     520            }
     521            break;
     522        case WC_SHA3_512:
     523            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
     524            if (length <= WC_SHA3_512_BLOCK_SIZE) {
     525                if (key != NULL) {
     526                    XMEMCPY(ip, key, length);
     527                }
     528            }
     529            else {
     530                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
     531                if (ret != 0)
     532                    break;
     533                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
     534                if (ret != 0)
     535                    break;
     536
     537                length = WC_SHA3_512_DIGEST_SIZE;
     538            }
     539            break;
     540    #endif /* WOLFSSL_SHA3 */
     541
    426542        default:
    427543            return BAD_FUNC_ARG;
     
    430546#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
    431547    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
    432     #if defined(HAVE_INTEL_QA)
     548    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
     549        #ifdef HAVE_INTEL_QA
     550        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
     551        #endif
     552        {
    433553        if (length > hmac_block_size)
    434554            length = hmac_block_size;
     
    437557
    438558        return ret;
     559        }
    439560        /* no need to pad below */
    440561    #endif
     
    489610    #endif /* !NO_SHA256 */
    490611
    491     #ifdef WOLFSSL_SHA512
    492612    #ifdef WOLFSSL_SHA384
    493613        case WC_SHA384:
     
    496616            break;
    497617    #endif /* WOLFSSL_SHA384 */
     618    #ifdef WOLFSSL_SHA512
    498619        case WC_SHA512:
    499620            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,
     
    508629            break;
    509630    #endif /* HAVE_BLAKE2 */
     631
     632    #ifdef WOLFSSL_SHA3
     633        case WC_SHA3_224:
     634            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
     635                                                       WC_SHA3_224_BLOCK_SIZE);
     636            break;
     637        case WC_SHA3_256:
     638            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
     639                                                       WC_SHA3_256_BLOCK_SIZE);
     640            break;
     641        case WC_SHA3_384:
     642            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
     643                                                       WC_SHA3_384_BLOCK_SIZE);
     644            break;
     645        case WC_SHA3_512:
     646            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
     647                                                       WC_SHA3_512_BLOCK_SIZE);
     648            break;
     649    #endif /* WOLFSSL_SHA3 */
    510650
    511651        default:
     
    533673        return NitroxHmacUpdate(hmac, msg, length);
    534674    #elif defined(HAVE_INTEL_QA)
     675        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
    535676        return IntelQaHmac(&hmac->asyncDev, hmac->macType,
    536677            (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
     678        }
    537679    #endif
    538680    }
     
    570712    #endif /* !NO_SHA256 */
    571713
    572     #ifdef WOLFSSL_SHA512
    573714    #ifdef WOLFSSL_SHA384
    574715        case WC_SHA384:
     
    576717            break;
    577718    #endif /* WOLFSSL_SHA384 */
     719    #ifdef WOLFSSL_SHA512
    578720        case WC_SHA512:
    579721            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
     
    586728            break;
    587729    #endif /* HAVE_BLAKE2 */
     730
     731    #ifdef WOLFSSL_SHA3
     732        case WC_SHA3_224:
     733            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
     734            break;
     735        case WC_SHA3_256:
     736            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
     737            break;
     738        case WC_SHA3_384:
     739            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
     740            break;
     741        case WC_SHA3_512:
     742            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
     743            break;
     744    #endif /* WOLFSSL_SHA3 */
    588745
    589746        default:
     
    610767
    611768    #if defined(HAVE_CAVIUM)
    612         return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen);
     769        return NitroxHmacFinal(hmac, hash, hashLen);
    613770    #elif defined(HAVE_INTEL_QA)
     771        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
    614772        return IntelQaHmac(&hmac->asyncDev, hmac->macType,
    615773            (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
     774        }
    616775    #endif
    617776    }
     
    697856    #endif /* !NO_SHA256 */
    698857
    699     #ifdef WOLFSSL_SHA512
    700858    #ifdef WOLFSSL_SHA384
    701859        case WC_SHA384:
     
    714872            break;
    715873    #endif /* WOLFSSL_SHA384 */
     874    #ifdef WOLFSSL_SHA512
    716875        case WC_SHA512:
    717876            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
     
    748907    #endif /* HAVE_BLAKE2 */
    749908
     909    #ifdef WOLFSSL_SHA3
     910        case WC_SHA3_224:
     911            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
     912            if (ret != 0)
     913                break;
     914            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
     915                                                       WC_SHA3_224_BLOCK_SIZE);
     916            if (ret != 0)
     917                break;
     918            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
     919                                                          WC_SHA3_224_DIGEST_SIZE);
     920            if (ret != 0)
     921                break;
     922            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
     923            break;
     924        case WC_SHA3_256:
     925            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
     926            if (ret != 0)
     927                break;
     928            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
     929                                                       WC_SHA3_256_BLOCK_SIZE);
     930            if (ret != 0)
     931                break;
     932            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
     933                                                          WC_SHA3_256_DIGEST_SIZE);
     934            if (ret != 0)
     935                break;
     936            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
     937            break;
     938        case WC_SHA3_384:
     939            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
     940            if (ret != 0)
     941                break;
     942            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
     943                                                       WC_SHA3_384_BLOCK_SIZE);
     944            if (ret != 0)
     945                break;
     946            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
     947                                                          WC_SHA3_384_DIGEST_SIZE);
     948            if (ret != 0)
     949                break;
     950            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
     951            break;
     952        case WC_SHA3_512:
     953            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
     954            if (ret != 0)
     955                break;
     956            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
     957                                                       WC_SHA3_512_BLOCK_SIZE);
     958            if (ret != 0)
     959                break;
     960            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
     961                                                          WC_SHA3_512_DIGEST_SIZE);
     962            if (ret != 0)
     963                break;
     964            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
     965            break;
     966    #endif /* WOLFSSL_SHA3 */
     967
    750968        default:
    751969            ret = BAD_FUNC_ARG;
     
    774992#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
    775993    hmac->keyLen = 0;
    776     #ifdef HAVE_CAVIUM
    777         hmac->dataLen = 0;
    778         hmac->data    = NULL;        /* buffered input data */
    779     #endif /* HAVE_CAVIUM */
    780994
    781995    ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
     
    7941008        return;
    7951009
     1010    switch (hmac->macType) {
     1011    #ifndef NO_MD5
     1012        case WC_MD5:
     1013            wc_Md5Free(&hmac->hash.md5);
     1014            break;
     1015    #endif /* !NO_MD5 */
     1016
     1017    #ifndef NO_SHA
     1018        case WC_SHA:
     1019            wc_ShaFree(&hmac->hash.sha);
     1020            break;
     1021    #endif /* !NO_SHA */
     1022
     1023    #ifdef WOLFSSL_SHA224
     1024        case WC_SHA224:
     1025            wc_Sha224Free(&hmac->hash.sha224);
     1026            break;
     1027    #endif /* WOLFSSL_SHA224 */
     1028
     1029    #ifndef NO_SHA256
     1030        case WC_SHA256:
     1031            wc_Sha256Free(&hmac->hash.sha256);
     1032            break;
     1033    #endif /* !NO_SHA256 */
     1034
     1035    #ifdef WOLFSSL_SHA384
     1036        case WC_SHA384:
     1037            wc_Sha384Free(&hmac->hash.sha384);
     1038            break;
     1039    #endif /* WOLFSSL_SHA384 */
     1040    #ifdef WOLFSSL_SHA512
     1041        case WC_SHA512:
     1042            wc_Sha512Free(&hmac->hash.sha512);
     1043            break;
     1044    #endif /* WOLFSSL_SHA512 */
     1045
     1046    #ifdef HAVE_BLAKE2
     1047        case BLAKE2B_ID:
     1048            break;
     1049    #endif /* HAVE_BLAKE2 */
     1050
     1051    #ifdef WOLFSSL_SHA3
     1052        case WC_SHA3_224:
     1053            wc_Sha3_224_Free(&hmac->hash.sha3);
     1054            break;
     1055        case WC_SHA3_256:
     1056            wc_Sha3_256_Free(&hmac->hash.sha3);
     1057            break;
     1058        case WC_SHA3_384:
     1059            wc_Sha3_384_Free(&hmac->hash.sha3);
     1060            break;
     1061        case WC_SHA3_512:
     1062            wc_Sha3_512_Free(&hmac->hash.sha3);
     1063            break;
     1064    #endif /* WOLFSSL_SHA3 */
     1065
     1066        default:
     1067            break;
     1068    }
     1069
    7961070#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
    7971071    wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
    798 
    799 #ifdef HAVE_CAVIUM
    800     XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC);
    801     hmac->data = NULL;
    802 #endif /* HAVE_CAVIUM */
    8031072#endif /* WOLFSSL_ASYNC_CRYPT */
     1073
     1074    switch (hmac->macType) {
     1075    #ifndef NO_MD5
     1076        case WC_MD5:
     1077            wc_Md5Free(&hmac->hash.md5);
     1078            break;
     1079    #endif /* !NO_MD5 */
     1080
     1081    #ifndef NO_SHA
     1082        case WC_SHA:
     1083            wc_ShaFree(&hmac->hash.sha);
     1084            break;
     1085    #endif /* !NO_SHA */
     1086
     1087    #ifdef WOLFSSL_SHA224
     1088        case WC_SHA224:
     1089            wc_Sha224Free(&hmac->hash.sha224);
     1090            break;
     1091    #endif /* WOLFSSL_SHA224 */
     1092
     1093    #ifndef NO_SHA256
     1094        case WC_SHA256:
     1095            wc_Sha256Free(&hmac->hash.sha256);
     1096            break;
     1097    #endif /* !NO_SHA256 */
     1098
     1099    #ifdef WOLFSSL_SHA512
     1100    #ifdef WOLFSSL_SHA384
     1101        case WC_SHA384:
     1102            wc_Sha384Free(&hmac->hash.sha384);
     1103            break;
     1104    #endif /* WOLFSSL_SHA384 */
     1105        case WC_SHA512:
     1106            wc_Sha512Free(&hmac->hash.sha512);
     1107            break;
     1108    #endif /* WOLFSSL_SHA512 */
     1109    }
    8041110}
    8051111
    8061112int wolfSSL_GetHmacMaxSize(void)
    8071113{
    808     return MAX_DIGEST_SIZE;
     1114    return WC_MAX_DIGEST_SIZE;
    8091115}
    8101116
     
    8241130                        const byte* inKey, word32 inKeySz, byte* out)
    8251131    {
    826         byte   tmp[MAX_DIGEST_SIZE]; /* localSalt helper */
     1132        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
    8271133        Hmac   myHmac;
    8281134        int    ret;
     
    8691175                       const byte* info, word32 infoSz, byte* out, word32 outSz)
    8701176    {
    871         byte   tmp[MAX_DIGEST_SIZE];
     1177        byte   tmp[WC_MAX_DIGEST_SIZE];
    8721178        Hmac   myHmac;
    8731179        int    ret = 0;
     
    9301236                       byte* out,         word32 outSz)
    9311237    {
    932         byte   prk[MAX_DIGEST_SIZE];
     1238        byte   prk[WC_MAX_DIGEST_SIZE];
    9331239        int    hashSz = wc_HmacSizeByType(type);
    9341240        int    ret;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/integer.c

    r352 r372  
    4646#ifndef USE_FAST_MATH
    4747
     48#ifndef WOLFSSL_SP_MATH
     49
    4850#include <wolfssl/wolfcrypt/integer.h>
    4951
     
    320322}
    321323
     324int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)
     325{
     326    int i, len;
     327
     328    len = mp_unsigned_bin_size(a);
     329
     330    /* pad front w/ zeros to match length */
     331    for (i = 0; i < c - len; i++)
     332        b[i] = 0x00;
     333    return mp_to_unsigned_bin(a, b + i);
     334}
    322335
    323336/* creates "a" then copies b into it */
     
    39773990
    39783991
    3979 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC)
     3992#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) || !defined(NO_RSA) || \
     3993    !defined(NO_DSA) | !defined(NO_DH)
    39803994
    39813995/* c = a * a (mod b) */
     
    40034017#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || \
    40044018    defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN) || \
    4005     defined(OPENSSL_EXTRA) || defined(WC_RSA_BLINDING)
     4019    defined(OPENSSL_EXTRA) || defined(WC_RSA_BLINDING) || \
     4020    (!defined(NO_RSA) && !defined(NO_RSA_BOUNDS_CHECK))
    40064021
    40074022/* single digit addition */
     
    41704185
    41714186
    4172 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC)
     4187#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC) || \
     4188    defined(DEBUG_WOLFSSL) || !defined(NO_RSA) || !defined(NO_DSA) || \
     4189    !defined(NO_DH)
    41734190
    41744191static const int lnz[16] = {
     
    43164333}
    43174334
    4318 #endif /* defined(WOLFSSL_KEY_GEN)||defined(HAVE_COMP_KEY)||defined(HAVE_ECC) */
    4319 
    4320 #ifdef WOLFSSL_KEY_GEN
     4335#endif /* WOLFSSL_KEY_GEN || HAVE_COMP_KEY || HAVE_ECC || DEBUG_WOLFSSL */
     4336
     4337#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA)
    43214338
    43224339const mp_digit ltm_prime_tab[PRIME_SIZE] = {
     
    44744491}
    44754492
     4493/*
     4494 * Sets result to 1 if probably prime, 0 otherwise
     4495 */
     4496int mp_prime_is_prime (mp_int * a, int t, int *result)
     4497{
     4498  mp_int  b;
     4499  int     ix, err, res;
     4500
     4501  /* default to no */
     4502  *result = MP_NO;
     4503
     4504  /* valid value of t? */
     4505  if (t <= 0 || t > PRIME_SIZE) {
     4506        return MP_VAL;
     4507    }
     4508
     4509  /* is the input equal to one of the primes in the table? */
     4510  for (ix = 0; ix < PRIME_SIZE; ix++) {
     4511      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
     4512         *result = 1;
     4513         return MP_OKAY;
     4514      }
     4515    }
     4516
     4517  /* first perform trial division */
     4518  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
     4519            return err;
     4520        }
     4521
     4522  /* return if it was trivially divisible */
     4523  if (res == MP_YES) {
     4524    return MP_OKAY;
     4525  }
     4526
     4527  /* now perform the miller-rabin rounds */
     4528  if ((err = mp_init (&b)) != MP_OKAY) {
     4529            return err;
     4530        }
     4531
     4532  for (ix = 0; ix < t; ix++) {
     4533    /* set the prime */
     4534    if ((err = mp_set (&b, ltm_prime_tab[ix])) != MP_OKAY) {
     4535        goto LBL_B;
     4536        }
     4537
     4538    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
     4539      goto LBL_B;
     4540    }
     4541
     4542    if (res == MP_NO) {
     4543      goto LBL_B;
     4544    }
     4545  }
     4546
     4547  /* passed the test */
     4548  *result = MP_YES;
     4549LBL_B:mp_clear (&b);
     4550  return err;
     4551}
     4552
     4553
     4554/*
     4555 * Sets result to 1 if probably prime, 0 otherwise
     4556 */
     4557int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
     4558{
     4559  mp_int  b, c;
     4560  int     ix, err, res;
     4561  byte*   base = NULL;
     4562  word32  baseSz = 0;
     4563
     4564  /* default to no */
     4565  *result = MP_NO;
     4566
     4567  /* valid value of t? */
     4568  if (t <= 0 || t > PRIME_SIZE) {
     4569    return MP_VAL;
     4570  }
     4571
     4572  /* is the input equal to one of the primes in the table? */
     4573  for (ix = 0; ix < PRIME_SIZE; ix++) {
     4574      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
     4575         *result = MP_YES;
     4576         return MP_OKAY;
     4577      }
     4578  }
     4579
     4580  /* first perform trial division */
     4581  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
     4582    return err;
     4583  }
     4584
     4585  /* return if it was trivially divisible */
     4586  if (res == MP_YES) {
     4587    return MP_OKAY;
     4588  }
     4589
     4590  /* now perform the miller-rabin rounds */
     4591  if ((err = mp_init (&b)) != MP_OKAY) {
     4592    return err;
     4593  }
     4594  if ((err = mp_init (&c)) != MP_OKAY) {
     4595      mp_clear(&b);
     4596    return err;
     4597  }
     4598
     4599  baseSz = mp_count_bits(a);
     4600  baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);
     4601
     4602  base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4603  if (base == NULL) {
     4604      err = MP_MEM;
     4605      goto LBL_B;
     4606  }
     4607
     4608  if ((err = mp_sub_d(a, 2, &c)) != MP_OKAY) {
     4609      goto LBL_B;
     4610  }
     4611
     4612 /* now do a miller rabin with up to t random numbers, this should
     4613  * give a (1/4)^t chance of a false prime. */
     4614  for (ix = 0; ix < t; ix++) {
     4615    /* Set a test candidate. */
     4616    if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
     4617        goto LBL_B;
     4618    }
     4619
     4620    if ((err = mp_read_unsigned_bin(&b, base, baseSz)) != MP_OKAY) {
     4621        goto LBL_B;
     4622    }
     4623
     4624    if (mp_cmp_d(&b, 2) != MP_GT || mp_cmp(&b, &c) != MP_LT)
     4625        continue;
     4626
     4627    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
     4628      goto LBL_B;
     4629    }
     4630
     4631    if (res == MP_NO) {
     4632      goto LBL_B;
     4633    }
     4634  }
     4635
     4636  /* passed the test */
     4637  *result = MP_YES;
     4638LBL_B:mp_clear (&b);
     4639      mp_clear (&c);
     4640      XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     4641  return err;
     4642}
     4643
     4644#endif /* WOLFSSL_KEY_GEN NO_DH NO_DSA NO_RSA */
     4645
     4646#ifdef WOLFSSL_KEY_GEN
     4647
    44764648static const int USE_BBS = 1;
    44774649
     
    45274699
    45284700        /* test */
    4529         if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
     4701        /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance
     4702         * of a 1024-bit candidate being a false positive, when it is our
     4703         * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)
     4704         * Using 8 because we've always used 8. */
     4705        if ((err = mp_prime_is_prime_ex(N, 8, &res, rng)) != MP_OKAY) {
    45304706            XFREE(buf, heap, DYNAMIC_TYPE_RSA);
    45314707            return err;
     
    45374713
    45384714    return MP_OKAY;
    4539 }
    4540 
    4541 /*
    4542  * Sets result to 1 if probably prime, 0 otherwise
    4543  */
    4544 int mp_prime_is_prime (mp_int * a, int t, int *result)
    4545 {
    4546   mp_int  b;
    4547   int     ix, err, res;
    4548 
    4549   /* default to no */
    4550   *result = MP_NO;
    4551 
    4552   /* valid value of t? */
    4553   if (t <= 0 || t > PRIME_SIZE) {
    4554     return MP_VAL;
    4555   }
    4556 
    4557   /* is the input equal to one of the primes in the table? */
    4558   for (ix = 0; ix < PRIME_SIZE; ix++) {
    4559       if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
    4560          *result = 1;
    4561          return MP_OKAY;
    4562       }
    4563   }
    4564 
    4565   /* first perform trial division */
    4566   if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
    4567     return err;
    4568   }
    4569 
    4570   /* return if it was trivially divisible */
    4571   if (res == MP_YES) {
    4572     return MP_OKAY;
    4573   }
    4574 
    4575   /* now perform the miller-rabin rounds */
    4576   if ((err = mp_init (&b)) != MP_OKAY) {
    4577     return err;
    4578   }
    4579 
    4580   for (ix = 0; ix < t; ix++) {
    4581     /* set the prime */
    4582     if ((err = mp_set (&b, ltm_prime_tab[ix])) != MP_OKAY) {
    4583         goto LBL_B;
    4584     }
    4585 
    4586     if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
    4587       goto LBL_B;
    4588     }
    4589 
    4590     if (res == MP_NO) {
    4591       goto LBL_B;
    4592     }
    4593   }
    4594 
    4595   /* passed the test */
    4596   *result = MP_YES;
    4597 LBL_B:mp_clear (&b);
    4598   return err;
    45994715}
    46004716
     
    47294845
    47304846
    4731 #if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
     4847#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \
     4848    defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \
     4849    defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)
    47324850
    47334851/* chars used in radix conversions */
     
    47364854#endif
    47374855
    4738 #ifdef HAVE_ECC
     4856#if !defined(NO_DSA) || defined(HAVE_ECC)
    47394857/* read a string [ASCII] in a given radix */
    47404858int mp_read_radix (mp_int * a, const char *str, int radix)
     
    47474865
    47484866  /* make sure the radix is ok */
    4749   if (radix < 2 || radix > 64) {
     4867  if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
    47504868    return MP_VAL;
    47514869  }
     
    48064924  return MP_OKAY;
    48074925}
    4808 #endif /* HAVE_ECC */
    4809 
    4810 #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
    4811     defined(WOLFSSL_DEBUG_MATH)
     4926#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */
     4927
     4928#ifdef WC_MP_TO_RADIX
    48124929
    48134930/* returns size of ASCII representation */
     
    48214938
    48224939    /* special case for binary */
    4823     if (radix == 2) {
     4940    if (radix == MP_RADIX_BIN) {
    48244941        *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
    48254942        return MP_OKAY;
     
    48274944
    48284945    /* make sure the radix is in range */
    4829     if (radix < 2 || radix > 64) {
     4946    if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
    48304947        return MP_VAL;
    48314948    }
     
    48764993
    48774994    /* check range of the radix */
    4878     if (radix < 2 || radix > 64) {
     4995    if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
    48794996        return MP_VAL;
    48804997    }
     
    49345051    desc, a, a->used, a->sign, size, (int)sizeof(mp_digit));
    49355052
    4936   mp_toradix(a, buffer, 16);
     5053  mp_tohex(a, buffer);
    49375054  printf("  %s\n  ", buffer);
    49385055
     
    49495066#endif /* WOLFSSL_DEBUG_MATH */
    49505067
    4951 #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
     5068#endif /* WC_MP_TO_RADIX */
     5069
     5070#endif /* WOLFSSL_SP_MATH */
    49525071
    49535072#endif /* USE_FAST_MATH */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/logging.c

    r352 r372  
    3131#include <wolfssl/wolfcrypt/logging.h>
    3232#include <wolfssl/wolfcrypt/error-crypt.h>
    33 
    34 
    35 #ifdef __cplusplus
    36     extern "C" {
    37 #endif
    38     WOLFSSL_API int  wolfSSL_Debugging_ON(void);
    39     WOLFSSL_API void wolfSSL_Debugging_OFF(void);
    40 #ifdef __cplusplus
    41     }
     33#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
     34/* avoid adding WANT_READ and WANT_WRITE to error queue */
     35#include <wolfssl/error-ssl.h>
    4236#endif
    4337
     
    5852};
    5953volatile struct wc_error_queue* wc_errors;
     54static struct wc_error_queue* wc_current_node;
    6055static struct wc_error_queue* wc_last_node;
    6156/* pointer to last node in queue to make insertion O(1) */
    6257#endif
    6358
    64 
    65 
    66 #if defined(DEBUG_WOLFSSL)
     59#ifdef WOLFSSL_FUNC_TIME
     60/* WARNING: This code is only to be used for debugging performance.
     61 *          The code is not thread-safe.
     62 *          Do not use WOLFSSL_FUNC_TIME in production code.
     63 */
     64static double wc_func_start[WC_FUNC_COUNT];
     65static double wc_func_time[WC_FUNC_COUNT] = { 0, };
     66static const char* wc_func_name[WC_FUNC_COUNT] = {
     67    "SendHelloRequest",
     68    "DoHelloRequest",
     69    "SendClientHello",
     70    "DoClientHello",
     71    "SendServerHello",
     72    "DoServerHello",
     73    "SendEncryptedExtensions",
     74    "DoEncryptedExtensions",
     75    "SendCertificateRequest",
     76    "DoCertificateRequest",
     77    "SendCertificate",
     78    "DoCertificate",
     79    "SendCertificateVerify",
     80    "DoCertificateVerify",
     81    "SendFinished",
     82    "DoFinished",
     83    "SendKeyUpdate",
     84    "DoKeyUpdate",
     85    "SendEarlyData",
     86    "DoEarlyData",
     87    "SendNewSessionTicket",
     88    "DoNewSessionTicket",
     89    "SendServerHelloDone",
     90    "DoServerHelloDone",
     91    "SendTicket",
     92    "DoTicket",
     93    "SendClientKeyExchange",
     94    "DoClientKeyExchange",
     95    "SendCertificateStatus",
     96    "DoCertificateStatus",
     97    "SendServerKeyExchange",
     98    "DoServerKeyExchange",
     99    "SendEarlyData",
     100    "DoEarlyData",
     101};
     102
     103#include <sys/time.h>
     104
     105/* WARNING: This function is not portable. */
     106static WC_INLINE double current_time(int reset)
     107{
     108    struct timeval tv;
     109    gettimeofday(&tv, 0);
     110    (void)reset;
     111
     112    return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
     113}
     114#endif /* WOLFSSL_FUNC_TIME */
     115
     116#ifdef DEBUG_WOLFSSL
    67117
    68118/* Set these to default values initially. */
     
    70120static int loggingEnabled = 0;
    71121
     122#if defined(WOLFSSL_APACHE_MYNEWT)
     123#include "log/log.h"
     124static struct log mynewt_log;
     125#endif /* WOLFSSL_APACHE_MYNEWT */
     126
    72127#endif /* DEBUG_WOLFSSL */
    73128
    74129
     130/* allow this to be set to NULL, so logs can be redirected to default output */
    75131int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
    76132{
    77133#ifdef DEBUG_WOLFSSL
    78     int res = 0;
    79 
    80     if (f)
    81134        log_function = f;
    82     else
    83         res = BAD_FUNC_ARG;
    84 
    85     return res;
     135    return 0;
    86136#else
    87137    (void)f;
     
    95145#ifdef DEBUG_WOLFSSL
    96146    loggingEnabled = 1;
     147#if defined(WOLFSSL_APACHE_MYNEWT)
     148    log_register("wolfcrypt", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL);
     149#endif /* WOLFSSL_APACHE_MYNEWT */
    97150    return 0;
    98151#else
     
    109162}
    110163
     164#ifdef WOLFSSL_FUNC_TIME
     165/* WARNING: This code is only to be used for debugging performance.
     166 *          The code is not thread-safe.
     167 *          Do not use WOLFSSL_FUNC_TIME in production code.
     168 */
     169void WOLFSSL_START(int funcNum)
     170{
     171    double now = current_time(0) * 1000.0;
     172#ifdef WOLFSSL_FUNC_TIME_LOG
     173    fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]);
     174#endif
     175    wc_func_start[funcNum] = now;
     176}
     177
     178void WOLFSSL_END(int funcNum)
     179{
     180    double now = current_time(0) * 1000.0;
     181    wc_func_time[funcNum] += now - wc_func_start[funcNum];
     182#ifdef WOLFSSL_FUNC_TIME_LOG
     183    fprintf(stderr, "%17.3f: END   - %s\n", now, wc_func_name[funcNum]);
     184#endif
     185}
     186
     187void WOLFSSL_TIME(int count)
     188{
     189    int i;
     190    double avg, total = 0;
     191
     192    for (i = 0; i < WC_FUNC_COUNT; i++) {
     193        if (wc_func_time[i] > 0) {
     194            avg = wc_func_time[i] / count;
     195            fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]);
     196            total += avg;
     197        }
     198    }
     199    fprintf(stderr, "%8.3f ms\n", total);
     200}
     201#endif
    111202
    112203#ifdef DEBUG_WOLFSSL
     
    122213    int sprintf(char* buf, const char *fmt, ...);
    123214#elif defined(MICRIUM)
     215    #if (BSP_SER_COMM_EN  == DEF_ENABLED)
    124216    #include <bsp_ser.h>
     217    #endif
     218#elif defined(WOLFSSL_USER_LOG)
     219    /* user includes their own headers */
     220#elif defined(WOLFSSL_ESPIDF)
     221    #include "esp_types.h"
     222    #include "esp_log.h"
    125223#else
    126224    #include <stdio.h>   /* for default printf stuff */
     
    136234        log_function(logLevel, logMessage);
    137235    else {
    138         if (loggingEnabled) {
    139 #if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
     236#if defined(WOLFSSL_USER_LOG)
     237        WOLFSSL_USER_LOG(logMessage);
     238#elif defined(WOLFSSL_LOG_PRINTF)
     239        printf("%s\n", logMessage);
     240
     241#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
    140242            dc_log_printf("%s\n", logMessage);
    141243#elif defined(MICRIUM)
     
    145247            printf("%s\n", logMessage);
    146248            fflush(stdout) ;
    147 #elif defined(WOLFSSL_LOG_PRINTF)
    148             printf("%s\n", logMessage);
    149249#elif defined(WOLFSSL_UTASKER)
    150250            fnDebugMsg((char*)logMessage);
     
    152252#elif defined(MQX_USE_IO_OLD)
    153253            fprintf(_mqxio_stderr, "%s\n", logMessage);
     254
     255#elif defined(WOLFSSL_APACHE_MYNEWT)
     256        LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage);
     257#elif defined(WOLFSSL_ESPIDF)
     258        extern char* TAG;
     259        ESP_LOGI(TAG, "%s", logMessage);
    154260#else
    155261            fprintf(stderr, "%s\n", logMessage);
     
    157263        }
    158264    }
    159 }
    160 
    161 
     265
     266#ifndef WOLFSSL_DEBUG_ERRORS_ONLY
    162267void WOLFSSL_MSG(const char* msg)
    163268{
     
    208313{
    209314    if (loggingEnabled) {
    210         char buffer[80];
    211         sprintf(buffer, "wolfSSL Entering %s", msg);
     315        char buffer[WOLFSSL_MAX_ERROR_SZ];
     316        XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
    212317        wolfssl_log(ENTER_LOG , buffer);
    213318    }
     
    218323{
    219324    if (loggingEnabled) {
    220         char buffer[80];
    221         sprintf(buffer, "wolfSSL Leaving %s, return %d", msg, ret);
     325        char buffer[WOLFSSL_MAX_ERROR_SZ];
     326        XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
     327                msg, ret);
    222328        wolfssl_log(LEAVE_LOG , buffer);
    223329    }
    224330}
     331#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */
    225332#endif  /* DEBUG_WOLFSSL */
    226333
     
    230337 * name where WOLFSSL_ERROR is called at.
    231338 */
    232 #if (defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY)
    233     #if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
     339#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \
     340    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
     341
     342#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
    234343void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
    235344            const char* file, void* usrCtx)
     
    238347    #endif
    239348{
    240     #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_NGINX)
    241     if (loggingEnabled && error != WC_PENDING_E)
     349#ifdef WOLFSSL_ASYNC_CRYPT
     350    if (error != WC_PENDING_E)
    242351    #endif
    243352    {
    244         char buffer[80];
     353        char buffer[WOLFSSL_MAX_ERROR_SZ];
     354
    245355        #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
    246356            (void)usrCtx; /* a user ctx for future flexibility */
     
    249359            if (wc_LockMutex(&debug_mutex) != 0) {
    250360                WOLFSSL_MSG("Lock debug mutex failed");
    251                 sprintf(buffer, "wolfSSL error occurred, error = %d", error);
     361            XSNPRINTF(buffer, sizeof(buffer),
     362                    "wolfSSL error occurred, error = %d", error);
    252363            }
    253364            else {
    254                 if (error < 0) error = error - (2*error); /*get absolute value*/
    255                 sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s",
     365            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
     366            /* If running in compatibility mode do not add want read and
     367               want right to error queue */
     368            if (error != WANT_READ && error != WANT_WRITE) {
     369            #endif
     370            if (error < 0)
     371                error = error - (2 * error); /* get absolute value */
     372            XSNPRINTF(buffer, sizeof(buffer),
     373                    "wolfSSL error occurred, error = %d line:%d file:%s",
    256374                    error, line, file);
    257375                if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {
     
    260378                     * to unlock mutex and log what buffer was created. */
    261379                }
     380            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
     381            }
     382            else {
     383                XSNPRINTF(buffer, sizeof(buffer),
     384                    "wolfSSL error occurred, error = %d", error);
     385
     386            }
     387            #endif
    262388
    263389                wc_UnLockMutex(&debug_mutex);
    264390            }
    265391        #else
    266             sprintf(buffer, "wolfSSL error occurred, error = %d", error);
     392        XSNPRINTF(buffer, sizeof(buffer),
     393                "wolfSSL error occurred, error = %d", error);
    267394        #endif
     395
    268396        #ifdef DEBUG_WOLFSSL
     397        if (loggingEnabled)
    269398        wolfssl_log(ERROR_LOG , buffer);
    270399        #endif
    271400    }
     401}
     402
     403void WOLFSSL_ERROR_MSG(const char* msg)
     404{
     405#ifdef DEBUG_WOLFSSL
     406    if (loggingEnabled)
     407        wolfssl_log(ERROR_LOG , msg);
     408#else
     409    (void)msg;
     410#endif
    272411}
    273412
     
    283422    }
    284423    wc_errors          = NULL;
     424    wc_current_node    = NULL;
    285425    wc_last_node       = NULL;
    286426
     
    304444
    305445
    306 #if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
    307     defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
    308446/* peek at an error node
    309447 *
     
    367505
    368506
     507/* Pulls the current node from error queue and increments current state.
     508 * Note: this does not delete nodes because input arguments are pointing to
     509 *       node buffers.
     510 *
     511 * file   pointer to file that error was in. Can be NULL to return no file.
     512 * reason error string giving reason for error. Can be NULL to return no reason.
     513 * line   return line number of where error happened.
     514 *
     515 * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure
     516 */
     517int wc_PullErrorNode(const char **file, const char **reason, int *line)
     518{
     519    struct wc_error_queue* err;
     520    int value;
     521
     522    if (wc_LockMutex(&debug_mutex) != 0) {
     523        WOLFSSL_MSG("Lock debug mutex failed");
     524        return BAD_MUTEX_E;
     525    }
     526
     527    err = wc_current_node;
     528    if (err == NULL) {
     529        WOLFSSL_MSG("No Errors in queue");
     530        wc_UnLockMutex(&debug_mutex);
     531        return BAD_STATE_E;
     532    }
     533
     534    if (file != NULL) {
     535        *file = err->file;
     536    }
     537
     538    if (reason != NULL) {
     539        *reason = err->error;
     540    }
     541
     542    if (line != NULL) {
     543        *line = err->line;
     544    }
     545
     546    value = err->value;
     547    wc_current_node = err->next;
     548    wc_UnLockMutex(&debug_mutex);
     549
     550    return value;
     551}
     552
     553
    369554/* create new error node and add it to the queue
    370555 * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal
     
    416601                /* check for unexpected case before over writing wc_errors */
    417602                WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n");
     603                /* In the event both wc_last_node and wc_errors are NULL, err
     604                 * goes unassigned to external wc_errors, wc_last_node. Free
     605                 * err in this instance since wc_ClearErrorNodes will not
     606                 */
     607                XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG);
    418608            }
    419609            else {
    420610                wc_errors    = err;
    421611                wc_last_node = err;
     612                wc_current_node = err;
    422613            }
    423614        }
     
    426617            err->prev = wc_last_node;
    427618            wc_last_node = err;
     619
     620            /* check the case where have read to the end of the queue and the
     621             * current node to read needs updated */
     622            if (wc_current_node == NULL) {
     623                wc_current_node = err;
     624            }
    428625        }
    429626    }
     
    465662}
    466663
    467 #endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
    468664
    469665/* Clears out the list of error nodes.
     
    471667void wc_ClearErrorNodes(void)
    472668{
     669#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
     670    defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
     671
    473672    if (wc_LockMutex(&debug_mutex) != 0) {
    474673        WOLFSSL_MSG("Lock debug mutex failed");
     
    491690    wc_errors    = NULL;
    492691    wc_last_node = NULL;
     692    wc_current_node = NULL;
    493693    wc_UnLockMutex(&debug_mutex);
     694#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
    494695}
    495696
     
    505706}
    506707
     708
     709/* frees all nodes in the queue
     710 *
     711 * id  this is the thread id
     712 */
     713int wc_ERR_remove_state(void)
     714{
     715    struct wc_error_queue* current;
     716    struct wc_error_queue* next;
     717
     718    if (wc_LockMutex(&debug_mutex) != 0) {
     719        WOLFSSL_MSG("Lock debug mutex failed");
     720        return BAD_MUTEX_E;
     721    }
     722
     723    /* free all nodes from error queue */
     724    current = (struct wc_error_queue*)wc_errors;
     725    while (current != NULL) {
     726        next = current->next;
     727        XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
     728        current = next;
     729    }
     730
     731    wc_errors          = NULL;
     732    wc_last_node       = NULL;
     733
     734    wc_UnLockMutex(&debug_mutex);
     735
     736    return 0;
     737}
     738
     739
    507740#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
    508741/* empties out the error queue into the file */
    509 void wc_ERR_print_errors_fp(FILE* fp)
     742void wc_ERR_print_errors_fp(XFILE fp)
    510743{
    511744    WOLFSSL_ENTER("wc_ERR_print_errors_fp");
    512745
    513     if (wc_LockMutex(&debug_mutex) != 0) {
     746        if (wc_LockMutex(&debug_mutex) != 0)
     747        {
    514748        WOLFSSL_MSG("Lock debug mutex failed");
    515749    }
    516     else {
     750        else
     751        {
    517752        /* free all nodes from error queue and print them to file */
    518753        {
     
    521756
    522757            current = (struct wc_error_queue*)wc_errors;
    523             while (current != NULL) {
     758                while (current != NULL)
     759                {
    524760                next = current->next;
    525761                fprintf(fp, "%s\n", current->error);
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/md4.c

    r352 r372  
    131131
    132132
    133 static INLINE void AddLength(Md4* md4, word32 len)
     133static WC_INLINE void AddLength(Md4* md4, word32 len)
    134134{
    135135    word32 tmp = md4->loLen;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/md5.c

    r352 r372  
    4747
    4848
    49 static INLINE void AddLength(wc_Md5* md5, word32 len);
    50 
    5149/* Hardware Acceleration */
    5250#if defined(STM32_HASH)
    5351
    54     /*
    55      * STM32F2/F4/F7 hardware MD5 support through the HASH_* API's from the
    56      * Standard Peripheral Library or CubeMX (See note in README).
    57      */
    58 
     52    /* Supports CubeMX HAL or Standard Peripheral Library */
    5953        #define HAVE_MD5_CUST_API
    60 
    61     /* STM32 register size, bytes */
    62     #ifdef WOLFSSL_STM32_CUBEMX
    63         #define MD5_REG_SIZE  WC_MD5_BLOCK_SIZE
    64     #else
    65         #define MD5_REG_SIZE  4
    66         /* STM32 struct notes:
    67          * md5->buffer  = first 4 bytes used to hold partial block if needed
    68          * md5->buffLen = num bytes currently stored in md5->buffer
    69          * md5->loLen   = num bytes that have been written to STM32 FIFO
    70          */
    71     #endif
    72     #define MD5_HW_TIMEOUT 0xFF
    7354
    7455    int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)
    7556    {
    76         if (md5 == NULL)
     57        if (md5 == NULL) {
    7758            return BAD_FUNC_ARG;
    78 
     59        }
     60
     61        (void)devId;
    7962        (void)heap;
    80         (void)devId;
    81 
    82         md5->heap = heap;
    83         XMEMSET(md5->buffer, 0, sizeof(md5->buffer));
    84         md5->buffLen = 0;
    85         md5->loLen = 0;
    86         md5->hiLen = 0;
    87 
    88         /* initialize HASH peripheral */
    89     #ifdef WOLFSSL_STM32_CUBEMX
    90         HAL_HASH_DeInit(&md5->hashHandle);
    91         md5->hashHandle.Init.DataType = HASH_DATATYPE_8B;
    92         if (HAL_HASH_Init(&md5->hashHandle) != HAL_OK) {
    93             return ASYNC_INIT_E;
    94         }
    95         /* reset the hash control register */
    96         /* required because Cube MX is not clearing algo bits */
    97         HASH->CR &= ~HASH_CR_ALGO;
    98     #else
    99                 HASH_DeInit();
    100 
    101         /* reset the control register */
    102         HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
    103 
    104                 /* configure algo used, algo mode, datatype */
    105                 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH
    106                                    | HASH_DataType_8b);
    107 
    108                 /* reset HASH processor */
    109                 HASH->CR |= HASH_CR_INIT;
    110     #endif
     63
     64        wc_Stm32_Hash_Init(&md5->stmCtx);
    11165
    11266        return 0;
     
    11569    int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)
    11670    {
    117         int ret = 0;
    118         byte* local;
     71        int ret;
    11972
    12073        if (md5 == NULL || (data == NULL && len > 0)) {
     
    12275        }
    12376
    124         /* do block size increments */
    125         local = (byte*)md5->buffer;
    126 
    127         /* check that internal buffLen is valid */
    128         if (md5->buffLen >= MD5_REG_SIZE)
    129             return BUFFER_E;
    130 
    131         while (len) {
    132             word32 add = min(len, MD5_REG_SIZE - md5->buffLen);
    133             XMEMCPY(&local[md5->buffLen], data, add);
    134 
    135             md5->buffLen += add;
    136             data         += add;
    137             len          -= add;
    138 
    139             if (md5->buffLen == MD5_REG_SIZE) {
    140             #ifdef WOLFSSL_STM32_CUBEMX
    141                 if (HAL_HASH_MD5_Accumulate(
    142                         &md5->hashHandle, local, MD5_REG_SIZE) != HAL_OK) {
    143                     ret = ASYNC_OP_E;
    144                 }
    145             #else
    146                 HASH_DataIn(*(uint32_t*)local);
    147             #endif
    148 
    149                 AddLength(md5, MD5_REG_SIZE);
    150                 md5->buffLen = 0;
    151             }
     77        ret = wolfSSL_CryptHwMutexLock();
     78        if (ret == 0) {
     79            ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5,
     80                data, len);
     81            wolfSSL_CryptHwMutexUnLock();
    15282        }
    15383        return ret;
     
    15686    int wc_Md5Final(wc_Md5* md5, byte* hash)
    15787    {
    158         int ret = 0;
    159 
    160         if (md5 == NULL || hash == NULL)
     88        int ret;
     89
     90        if (md5 == NULL || hash == NULL) {
    16191            return BAD_FUNC_ARG;
    162 
    163     #ifdef WOLFSSL_STM32_CUBEMX
    164         if (HAL_HASH_MD5_Start(&md5->hashHandle,
    165                 (byte*)md5->buffer, md5->buffLen,
    166                 (byte*)md5->digest, MD5_HW_TIMEOUT) != HAL_OK) {
    167             ret = ASYNC_OP_E;
    168         }
    169     #else
    170         __IO uint16_t nbvalidbitsdata = 0;
    171 
    172         /* finish reading any trailing bytes into FIFO */
    173         if (md5->buffLen > 0) {
    174                         HASH_DataIn(*(uint32_t*)md5->buffer);
    175             AddLength(md5, md5->buffLen);
    176         }
    177 
    178         /* calculate number of valid bits in last word of input data */
    179         nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE);
    180 
    181         /* configure number of valid bits in last word of the data */
    182         HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
    183 
    184         /* start HASH processor */
    185         HASH_StartDigest();
    186 
    187         /* wait until Busy flag == RESET */
    188         while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
    189 
    190         /* read message digest */
    191         md5->digest[0] = HASH->HR[0];
    192         md5->digest[1] = HASH->HR[1];
    193         md5->digest[2] = HASH->HR[2];
    194         md5->digest[3] = HASH->HR[3];
    195 
    196         ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE);
    197     #endif /* WOLFSSL_STM32_CUBEMX */
    198 
    199         XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE);
     92        }
     93
     94        ret = wolfSSL_CryptHwMutexLock();
     95        if (ret == 0) {
     96            ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5,
     97                hash, WC_MD5_DIGEST_SIZE);
     98            wolfSSL_CryptHwMutexUnLock();
     99        }
    200100
    201101        (void)wc_InitMd5(md5);  /* reset state */
     
    226126    #define HAVE_MD5_CUST_API
    227127
     128#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     129    /* functions implemented in wolfcrypt/src/port/caam/caam_sha.c */
     130    #define HAVE_MD5_CUST_API
    228131#else
    229132    #define NEED_SOFT_MD5
     
    330233#endif /* NEED_SOFT_MD5 */
    331234
    332 #if !defined(HAVE_MD5_CUST_API) || defined(STM32_HASH)
    333 static INLINE void AddLength(wc_Md5* md5, word32 len)
     235#ifndef HAVE_MD5_CUST_API
     236
     237static WC_INLINE void AddLength(wc_Md5* md5, word32 len)
    334238{
    335239    word32 tmp = md5->loLen;
     
    338242    }
    339243}
    340 #endif
    341 
    342 #ifndef HAVE_MD5_CUST_API
     244
    343245static int _InitMd5(wc_Md5* md5)
    344246{
     
    498400    wolfAsync_DevCtxFree(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5);
    499401#endif /* WOLFSSL_ASYNC_CRYPT */
     402
     403#ifdef WOLFSSL_PIC32MZ_HASH
     404    wc_Md5Pic32Free(md5);
     405#endif
    500406}
    501407
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/memory.c

    r352 r372  
    3535#endif
    3636
     37
     38/*
     39Possible memory options:
     40 * NO_WOLFSSL_MEMORY:               Disables wolf memory callback support. When not defined settings.h defines USE_WOLFSSL_MEMORY.
     41 * WOLFSSL_STATIC_MEMORY:           Turns on the use of static memory buffers and functions.
     42                                        This allows for using static memory instead of dynamic.
     43 * WOLFSSL_STATIC_ALIGN:            Define defaults to 16 to indicate static memory alignment.
     44 * HAVE_IO_POOL:                    Enables use of static thread safe memory pool for input/output buffers.
     45 * XMALLOC_OVERRIDE:                Allows override of the XMALLOC, XFREE and XREALLOC macros.
     46 * XMALLOC_USER:                    Allows custom XMALLOC, XFREE and XREALLOC functions to be defined.
     47 * WOLFSSL_NO_MALLOC:               Disables the fall-back case to use STDIO malloc/free when no callbacks are set.
     48 * WOLFSSL_TRACK_MEMORY:            Enables memory tracking for total stats and list of allocated memory.
     49 * WOLFSSL_DEBUG_MEMORY:            Enables extra function and line number args for memory callbacks.
     50 * WOLFSSL_DEBUG_MEMORY_PRINT:      Enables printing of each malloc/free.
     51 * WOLFSSL_MALLOC_CHECK:            Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN
     52 * WOLFSSL_FORCE_MALLOC_FAIL_TEST:  Used for internal testing to induce random malloc failures.
     53 * WOLFSSL_HEAP_TEST:               Used for internal testing of heap hint
     54 */
     55
     56
    3757#ifdef USE_WOLFSSL_MEMORY
    3858
     
    4161#include <wolfssl/wolfcrypt/logging.h>
    4262
    43 #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL)
     63#if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT)
     64#include <stdio.h>
     65#endif
     66
     67#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
     68    static int gMemFailCountSeed;
     69    static int gMemFailCount;
     70    void wolfSSL_SetMemFailCount(int memFailCount)
     71    {
     72        if (gMemFailCountSeed == 0) {
     73            gMemFailCountSeed = memFailCount;
     74            gMemFailCount = memFailCount;
     75        }
     76    }
     77#endif
     78#if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) || \
     79                                                     defined(WOLFSSL_MEMORY_LOG)
    4480    #include <stdio.h>
    4581#endif
     
    4783
    4884/* Set these to default values initially. */
    49 static wolfSSL_Malloc_cb  malloc_function = 0;
    50 static wolfSSL_Free_cb    free_function = 0;
    51 static wolfSSL_Realloc_cb realloc_function = 0;
     85static wolfSSL_Malloc_cb  malloc_function = NULL;
     86static wolfSSL_Free_cb    free_function = NULL;
     87static wolfSSL_Realloc_cb realloc_function = NULL;
    5288
    5389int wolfSSL_SetAllocators(wolfSSL_Malloc_cb  mf,
     
    5591                          wolfSSL_Realloc_cb rf)
    5692{
    57     int res = 0;
    58 
    59     if (mf)
    6093        malloc_function = mf;
    61     else
    62         res = BAD_FUNC_ARG;
    63 
    64     if (ff)
    6594        free_function = ff;
    66     else
    67         res = BAD_FUNC_ARG;
    68 
    69     if (rf)
    7095        realloc_function = rf;
    71     else
    72         res = BAD_FUNC_ARG;
    73 
    74     return res;
     96    return 0;
    7597}
    7698
     
    102124    }
    103125    else {
     126    #ifndef WOLFSSL_NO_MALLOC
    104127        res = malloc(size);
    105     }
     128    #else
     129        WOLFSSL_MSG("No malloc available");
     130    #endif
     131    }
     132
     133#ifdef WOLFSSL_DEBUG_MEMORY
     134#if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
     135    printf("Alloc: %p -> %u at %s:%d\n", res, (word32)size, func, line);
     136#else
     137    (void)func;
     138    (void)line;
     139#endif
     140#endif
    106141
    107142    #ifdef WOLFSSL_MALLOC_CHECK
    108143        if (res == NULL)
    109             puts("wolfSSL_malloc failed");
     144        WOLFSSL_MSG("wolfSSL_malloc failed");
     145#endif
     146
     147#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
     148    if (res && --gMemFailCount == 0) {
     149        printf("\n---FORCED MEM FAIL TEST---\n");
     150        if (free_function) {
     151        #ifdef WOLFSSL_DEBUG_MEMORY
     152            free_function(res, func, line);
     153        #else
     154            free_function(res);
     155        #endif
     156        }
     157        else {
     158            free(res); /* clear */
     159        }
     160        gMemFailCount = gMemFailCountSeed; /* reset */
     161        return NULL;
     162    }
    110163    #endif
    111164
     
    119172#endif
    120173{
     174#ifdef WOLFSSL_DEBUG_MEMORY
     175#if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
     176    printf("Free: %p at %s:%d\n", ptr, func, line);
     177#else
     178    (void)func;
     179    (void)line;
     180#endif
     181#endif
     182
    121183    if (free_function) {
    122184    #ifdef WOLFSSL_DEBUG_MEMORY
     
    127189    }
    128190    else {
     191    #ifndef WOLFSSL_NO_MALLOC
    129192        free(ptr);
     193    #else
     194        WOLFSSL_MSG("No free available");
     195    #endif
    130196    }
    131197}
     
    147213    }
    148214    else {
     215    #ifndef WOLFSSL_NO_MALLOC
    149216        res = realloc(ptr, size);
     217    #else
     218        WOLFSSL_MSG("No realloc available");
     219    #endif
    150220    }
    151221
     
    534604        #else
    535605        #ifndef WOLFSSL_NO_MALLOC
     606            #ifdef FREERTOS
     607                res = pvPortMalloc(size);
     608            #else
    536609            res = malloc(size);
     610            #endif
    537611        #else
    538612            WOLFSSL_MSG("No heap hint found to use and no malloc");
     
    668742        #endif
    669743        #ifndef WOLFSSL_NO_MALLOC
     744            #ifdef FREERTOS
     745                vPortFree(ptr);
     746            #else
    670747            free(ptr);
     748            #endif
    671749        #else
    672750            WOLFSSL_MSG("Error trying to call free when turned off");
     
    9231001#endif /* HAVE_IO_POOL */
    9241002
     1003#ifdef WOLFSSL_MEMORY_LOG
     1004void *xmalloc(size_t n, void* heap, int type, const char* func,
     1005              const char* file, unsigned int line)
     1006{
     1007    void*   p;
     1008    word32* p32;
     1009
     1010    if (malloc_function)
     1011        p32 = malloc_function(n + sizeof(word32) * 4);
     1012    else
     1013        p32 = malloc(n + sizeof(word32) * 4);
     1014
     1015    p32[0] = n;
     1016    p = (void*)(p32 + 4);
     1017
     1018    fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%d\n", p, (word32)n, type,
     1019                                                              func, file, line);
     1020
     1021    (void)heap;
     1022
     1023    return p;
     1024}
     1025void *xrealloc(void *p, size_t n, void* heap, int type, const char* func,
     1026               const char* file, unsigned int line)
     1027{
     1028    void*   newp = NULL;
     1029    word32* p32;
     1030    word32* oldp32 = NULL;
     1031    word32  oldLen;
     1032
     1033    if (p != NULL) {
     1034        oldp32 = (word32*)p;
     1035        oldp32 -= 4;
     1036        oldLen = oldp32[0];
     1037    }
     1038
     1039    if (realloc_function)
     1040        p32 = realloc_function(oldp32, n + sizeof(word32) * 4);
     1041    else
     1042        p32 = realloc(oldp32, n + sizeof(word32) * 4);
     1043
     1044    if (p32 != NULL) {
     1045        p32[0] = n;
     1046        newp = (void*)(p32 + 4);
     1047
     1048        fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%d\n", newp, (word32)n,
     1049                                                        type, func, file, line);
     1050        if (p != NULL) {
     1051            fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%d\n", p, oldLen,
     1052                                                        type, func, file, line);
     1053        }
     1054    }
     1055
     1056    (void)heap;
     1057
     1058    return newp;
     1059}
     1060void xfree(void *p, void* heap, int type, const char* func, const char* file,
     1061           unsigned int line)
     1062{
     1063    word32* p32 = (word32*)p;
     1064
     1065    if (p != NULL) {
     1066        p32 -= 4;
     1067
     1068        fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%d\n", p, p32[0], type,
     1069                                                              func, file, line);
     1070
     1071        if (free_function)
     1072            free_function(p32);
     1073        else
     1074            free(p32);
     1075    }
     1076
     1077    (void)heap;
     1078}
     1079#endif /* WOLFSSL_MEMORY_LOG */
     1080
     1081#ifdef WOLFSSL_STACK_LOG
     1082/* Note: this code only works with GCC using -finstrument-functions. */
     1083void __attribute__((no_instrument_function))
     1084     __cyg_profile_func_enter(void *func,  void *caller)
     1085{
     1086    register void* sp asm("sp");
     1087    fprintf(stderr, "ENTER: %016lx %p\n", (size_t)func, sp);
     1088    (void)caller;
     1089}
     1090
     1091void __attribute__((no_instrument_function))
     1092     __cyg_profile_func_exit(void *func, void *caller)
     1093{
     1094    register void* sp asm("sp");
     1095    fprintf(stderr, "EXIT: %016lx %p\n", (size_t)func, sp);
     1096    (void)caller;
     1097}
     1098#endif
     1099
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/misc.c

    r352 r372  
    4747/* Check for if compiling misc.c when not needed. */
    4848#if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)
     49    #ifndef WOLFSSL_IGNORE_FILE_WARN
    4950    #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)
     51    #endif
    5052
    5153#else
     
    6567    #pragma intrinsic(_lrotl, _lrotr)
    6668
    67     STATIC INLINE word32 rotlFixed(word32 x, word32 y)
     69    STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
    6870    {
    6971        return y ? _lrotl(x, y) : x;
    7072    }
    7173
    72     STATIC INLINE word32 rotrFixed(word32 x, word32 y)
     74    STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
    7375    {
    7476        return y ? _lrotr(x, y) : x;
     
    7779#else /* generic */
    7880
    79     STATIC INLINE word32 rotlFixed(word32 x, word32 y)
     81    STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)
    8082    {
    8183        return (x << y) | (x >> (sizeof(y) * 8 - y));
     
    8385
    8486
    85     STATIC INLINE word32 rotrFixed(word32 x, word32 y)
     87    STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)
    8688    {
    8789        return (x >> y) | (x << (sizeof(y) * 8 - y));
     
    9193
    9294
    93 STATIC INLINE word32 ByteReverseWord32(word32 value)
     95STATIC WC_INLINE word32 ByteReverseWord32(word32 value)
    9496{
    9597#ifdef PPC_INTRINSICS
     
    100102#elif defined(KEIL_INTRINSICS)
    101103    return (word32)__rev(value);
     104#elif defined(WOLF_ALLOW_BUILTIN) && \
     105        defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
     106    return (word32)__builtin_bswap32(value);
    102107#elif defined(FAST_ROTATE)
    103108    /* 5 instructions with rotate instruction, 9 without */
     
    112117
    113118
    114 STATIC INLINE void ByteReverseWords(word32* out, const word32* in,
     119STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
    115120                                    word32 byteCount)
    116121{
     
    123128
    124129
    125 #ifdef WORD64_AVAILABLE
    126 
    127 
    128 STATIC INLINE word64 rotlFixed64(word64 x, word64 y)
     130#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
     131
     132
     133STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
    129134{
    130135    return (x << y) | (x >> (sizeof(y) * 8 - y));
     
    132137
    133138
    134 STATIC INLINE word64 rotrFixed64(word64 x, word64 y)
     139STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)
    135140{
    136141    return (x >> y) | (x << (sizeof(y) * 8 - y));
     
    138143
    139144
    140 STATIC INLINE word64 ByteReverseWord64(word64 value)
    141 {
    142 #if defined(WOLFCRYPT_SLOW_WORD64)
    143         return (word64)(ByteReverseWord32((word32)value)) << 32 |
    144                     ByteReverseWord32((word32)(value>>32));
     145STATIC WC_INLINE word64 ByteReverseWord64(word64 value)
     146{
     147#if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)
     148    return (word64)__builtin_bswap64(value);
     149#elif defined(WOLFCRYPT_SLOW_WORD64)
     150        return (word64)((word64)ByteReverseWord32((word32) value)) << 32 |
     151                    (word64)ByteReverseWord32((word32)(value   >> 32));
    145152#else
    146153        value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |
     
    153160
    154161
    155 STATIC INLINE void ByteReverseWords64(word64* out, const word64* in,
     162STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,
    156163                                      word32 byteCount)
    157164{
     
    163170}
    164171
    165 #endif /* WORD64_AVAILABLE */
    166 
    167 
    168 STATIC INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
     172#endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */
     173
     174#ifndef WOLFSSL_NO_XOR_OPS
     175STATIC WC_INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)
    169176{
    170177    word32 i;
     
    174181
    175182
    176 STATIC INLINE void xorbuf(void* buf, const void* mask, word32 count)
     183STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
    177184{
    178185    if (((wolfssl_word)buf | (wolfssl_word)mask | count) % WOLFSSL_WORD_SIZE == 0)
     
    187194    }
    188195}
    189 
    190 
     196#endif
     197
     198#ifndef WOLFSSL_NO_FORCE_ZERO
    191199/* Make sure compiler doesn't skip */
    192 STATIC INLINE void ForceZero(const void* mem, word32 len)
     200STATIC WC_INLINE void ForceZero(const void* mem, word32 len)
    193201{
    194202    volatile byte* z = (volatile byte*)mem;
    195 #ifdef WOLFSSL_X86_64_BUILD
     203
     204#if defined(WOLFSSL_X86_64_BUILD) && defined(WORD64_AVAILABLE)
    196205    volatile word64* w;
    197 
     206    #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS
     207        word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &
     208                                                             (sizeof(word64)-1);
     209
     210        if (len < l) l = len;
     211        len -= l;
     212        while (l--) *z++ = 0;
     213    #endif
    198214    for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))
    199215        *w++ = 0;
    200216    z = (volatile byte*)w;
    201217#endif
     218
    202219    while (len--) *z++ = 0;
    203220}
    204 
    205 
     221#endif
     222
     223
     224#ifndef WOLFSSL_NO_CONST_CMP
    206225/* check all length bytes for equality, return 0 on success */
    207 STATIC INLINE int ConstantCompare(const byte* a, const byte* b, int length)
     226STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, int length)
    208227{
    209228    int i;
     
    216235    return compareSum;
    217236}
     237#endif
    218238
    219239
     
    223243        #define min min
    224244    #endif
    225     STATIC INLINE word32 min(word32 a, word32 b)
     245    STATIC WC_INLINE word32 min(word32 a, word32 b)
    226246    {
    227247        return a > b ? b : a;
     
    234254        #define max max
    235255    #endif
    236     STATIC INLINE word32 max(word32 a, word32 b)
     256    STATIC WC_INLINE word32 max(word32 a, word32 b)
    237257    {
    238258        return a > b ? a : b;
     
    240260#endif /* !WOLFSSL_HAVE_MAX */
    241261
     262#ifndef WOLFSSL_NO_INT_ENCODE
    242263/* converts a 32 bit integer to 24 bit */
    243 STATIC INLINE void c32to24(word32 in, word24 out)
     264STATIC WC_INLINE void c32to24(word32 in, word24 out)
    244265{
    245266    out[0] = (in >> 16) & 0xff;
     
    249270
    250271/* convert 16 bit integer to opaque */
    251 STATIC INLINE void c16toa(word16 u16, byte* c)
    252 {
    253     c[0] = (u16 >> 8) & 0xff;
    254     c[1] =  u16 & 0xff;
     272STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)
     273{
     274    c[0] = (wc_u16 >> 8) & 0xff;
     275    c[1] =  wc_u16 & 0xff;
    255276}
    256277
    257278/* convert 32 bit integer to opaque */
    258 STATIC INLINE void c32toa(word32 u32, byte* c)
    259 {
    260     c[0] = (u32 >> 24) & 0xff;
    261     c[1] = (u32 >> 16) & 0xff;
    262     c[2] = (u32 >>  8) & 0xff;
    263     c[3] =  u32 & 0xff;
    264 }
    265 
     279STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)
     280{
     281    c[0] = (wc_u32 >> 24) & 0xff;
     282    c[1] = (wc_u32 >> 16) & 0xff;
     283    c[2] = (wc_u32 >>  8) & 0xff;
     284    c[3] =  wc_u32 & 0xff;
     285}
     286#endif
     287
     288#ifndef WOLFSSL_NO_INT_DECODE
    266289/* convert a 24 bit integer into a 32 bit one */
    267 STATIC INLINE void c24to32(const word24 u24, word32* u32)
    268 {
    269     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
     290STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)
     291{
     292    *wc_u32 = (wc_u24[0] << 16) | (wc_u24[1] << 8) | wc_u24[2];
    270293}
    271294
    272295
    273296/* convert opaque to 24 bit integer */
    274 STATIC INLINE void ato24(const byte* c, word32* u24)
    275 {
    276     *u24 = (c[0] << 16) | (c[1] << 8) | c[2];
     297STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)
     298{
     299    *wc_u24 = (c[0] << 16) | (c[1] << 8) | c[2];
    277300}
    278301
    279302/* convert opaque to 16 bit integer */
    280 STATIC INLINE void ato16(const byte* c, word16* u16)
    281 {
    282     *u16 = (word16) ((c[0] << 8) | (c[1]));
     303STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)
     304{
     305    *wc_u16 = (word16) ((c[0] << 8) | (c[1]));
    283306}
    284307
    285308/* convert opaque to 32 bit integer */
    286 STATIC INLINE void ato32(const byte* c, word32* u32)
    287 {
    288     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
    289 }
    290 
    291 
    292 STATIC INLINE word32 btoi(byte b)
     309STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)
     310{
     311    *wc_u32 = ((word32)c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
     312}
     313
     314
     315STATIC WC_INLINE word32 btoi(byte b)
    293316{
    294317    return (word32)(b - 0x30);
    295318}
    296 
     319#endif
     320
     321
     322#ifndef WOLFSSL_NO_CT_OPS
     323/* Constant time - mask set when a > b. */
     324STATIC WC_INLINE byte ctMaskGT(int a, int b)
     325{
     326    return (((word32)a - b - 1) >> 31) - 1;
     327}
     328
     329/* Constant time - mask set when a >= b. */
     330STATIC WC_INLINE byte ctMaskGTE(int a, int b)
     331{
     332    return (((word32)a - b    ) >> 31) - 1;
     333}
     334
     335/* Constant time - mask set when a < b. */
     336STATIC WC_INLINE byte ctMaskLT(int a, int b)
     337{
     338    return (((word32)b - a - 1) >> 31) - 1;
     339}
     340
     341/* Constant time - mask set when a <= b. */
     342STATIC WC_INLINE byte ctMaskLTE(int a, int b)
     343{
     344    return (((word32)b - a    ) >> 31) - 1;
     345}
     346
     347/* Constant time - mask set when a == b. */
     348STATIC WC_INLINE byte ctMaskEq(int a, int b)
     349{
     350    return 0 - (a == b);
     351}
     352
     353/* Constant time - mask set when a != b. */
     354STATIC WC_INLINE byte ctMaskNotEq(int a, int b)
     355{
     356    return 0 - (a != b);
     357}
     358
     359/* Constant time - select a when mask is set and b otherwise. */
     360STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)
     361{
     362    return (b & ((byte)~(word32)m)) | (a & m);
     363}
     364
     365/* Constant time - select integer a when mask is set and integer b otherwise. */
     366STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)
     367{
     368    return (b & (~(signed int)(signed char)m)) |
     369           (a & ( (signed int)(signed char)m));
     370}
     371
     372/* Constant time - bit set when a <= b. */
     373STATIC WC_INLINE byte ctSetLTE(int a, int b)
     374{
     375    return ((word32)a - b - 1) >> 31;
     376}
     377#endif
    297378
    298379
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/pwdbased.c

    r352 r372  
    3131#include <wolfssl/wolfcrypt/pwdbased.h>
    3232#include <wolfssl/wolfcrypt/hmac.h>
     33#include <wolfssl/wolfcrypt/hash.h>
    3334#include <wolfssl/wolfcrypt/integer.h>
    3435#include <wolfssl/wolfcrypt/error-crypt.h>
    35 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
    36     #include <wolfssl/wolfcrypt/sha512.h>
    37 #endif
    3836
    3937#ifdef NO_INLINE
     
    4543
    4644
    47 #ifndef NO_SHA
    48 /* PBKDF1 needs at least SHA available */
     45/* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */
     46int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
     47    const byte* passwd, int passwdLen, const byte* salt, int saltLen,
     48    int iterations, int hashType, void* heap)
     49{
     50    int  err;
     51    int  keyLeft, ivLeft, i;
     52    int  digestLeft, store;
     53    int  keyOutput = 0;
     54    int  diestLen;
     55    byte digest[WC_MAX_DIGEST_SIZE];
     56#ifdef WOLFSSL_SMALL_STACK
     57    wc_HashAlg* hash = NULL;
     58#else
     59    wc_HashAlg  hash[1];
     60#endif
     61    enum wc_HashType hashT;
     62
     63    (void)heap;
     64
     65    if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){
     66        return BAD_FUNC_ARG;
     67    }
     68
     69    if (iterations <= 0)
     70        iterations = 1;
     71
     72    hashT = wc_HashTypeConvert(hashType);
     73    err = wc_HashGetDigestSize(hashT);
     74    if (err < 0)
     75        return err;
     76    diestLen = err;
     77
     78    /* initialize hash */
     79#ifdef WOLFSSL_SMALL_STACK
     80    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,
     81                                DYNAMIC_TYPE_HASHCTX);
     82    if (hash == NULL)
     83        return MEMORY_E;
     84#endif
     85
     86    err = wc_HashInit(hash, hashT);
     87    if (err != 0) {
     88    #ifdef WOLFSSL_SMALL_STACK
     89        XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
     90    #endif
     91        return err;
     92            }
     93
     94    keyLeft = keyLen;
     95    ivLeft  = ivLen;
     96    while (keyOutput < (keyLen + ivLen)) {
     97        digestLeft = diestLen;
     98        /* D_(i - 1) */
     99        if (keyOutput) { /* first time D_0 is empty */
     100            err = wc_HashUpdate(hash, hashT, digest, diestLen);
     101            if (err != 0) break;
     102            }
     103
     104        /* data */
     105        err = wc_HashUpdate(hash, hashT, passwd, passwdLen);
     106        if (err != 0) break;
     107
     108        /* salt */
     109        if (salt) {
     110            err = wc_HashUpdate(hash, hashT, salt, saltLen);
     111            if (err != 0) break;
     112    }
     113
     114        err = wc_HashFinal(hash, hashT, digest);
     115        if (err != 0) break;
     116
     117        /* count */
     118    for (i = 1; i < iterations; i++) {
     119            err = wc_HashUpdate(hash, hashT, digest, diestLen);
     120            if (err != 0) break;
     121
     122            err = wc_HashFinal(hash, hashT, digest);
     123            if (err != 0) break;
     124            }
     125
     126        if (keyLeft) {
     127            store = min(keyLeft, diestLen);
     128            XMEMCPY(&key[keyLen - keyLeft], digest, store);
     129
     130            keyOutput  += store;
     131            keyLeft    -= store;
     132            digestLeft -= store;
     133            }
     134
     135        if (ivLeft && digestLeft) {
     136            store = min(ivLeft, digestLeft);
     137            if (iv != NULL)
     138                XMEMCPY(&iv[ivLen - ivLeft],
     139                        &digest[diestLen - digestLeft], store);
     140            keyOutput += store;
     141            ivLeft    -= store;
     142        }
     143    }
     144
     145    wc_HashFree(hash, hashT);
     146
     147#ifdef WOLFSSL_SMALL_STACK
     148    XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
     149#endif
     150
     151    if (err != 0)
     152        return err;
     153
     154    if (keyOutput != (keyLen + ivLen))
     155        return BUFFER_E;
     156
     157    return err;
     158    }
     159
     160/* PKCS#5 v1.5 */
    49161int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
    50162           int sLen, int iterations, int kLen, int hashType)
    51163{
    52     wc_Sha  sha;
    53 #ifndef NO_MD5
    54     wc_Md5  md5;
    55 #endif
    56     int  hLen = (int)WC_SHA_DIGEST_SIZE;
    57     int  i, ret = 0;
    58     byte buffer[WC_SHA_DIGEST_SIZE];  /* max size */
    59 
    60     if (hashType != WC_MD5 && hashType != WC_SHA)
    61         return BAD_FUNC_ARG;
    62 
    63 #ifndef NO_MD5
    64     if (hashType == WC_MD5)
    65         hLen = (int)WC_MD5_DIGEST_SIZE;
    66 #endif
    67 
    68     if ((kLen > hLen) || (kLen < 0))
    69         return BAD_FUNC_ARG;
    70 
    71     if (iterations < 1)
    72         return BAD_FUNC_ARG;
    73 
    74     switch (hashType) {
    75 #ifndef NO_MD5
    76         case WC_MD5:
    77             ret = wc_InitMd5(&md5);
    78             if (ret != 0) {
    79                 return ret;
    80             }
    81             ret = wc_Md5Update(&md5, passwd, pLen);
    82             if (ret != 0) {
    83                 return ret;
    84             }
    85             ret = wc_Md5Update(&md5, salt,   sLen);
    86             if (ret != 0) {
    87                 return ret;
    88             }
    89             ret = wc_Md5Final(&md5,  buffer);
    90             if (ret != 0) {
    91                 return ret;
    92             }
    93             break;
    94 #endif /* NO_MD5 */
    95         case WC_SHA:
    96         default:
    97             ret = wc_InitSha(&sha);
    98             if (ret != 0)
    99                 return ret;
    100             wc_ShaUpdate(&sha, passwd, pLen);
    101             wc_ShaUpdate(&sha, salt,   sLen);
    102             wc_ShaFinal(&sha,  buffer);
    103             break;
    104     }
    105 
    106     for (i = 1; i < iterations; i++) {
    107         if (hashType == WC_SHA) {
    108             wc_ShaUpdate(&sha, buffer, hLen);
    109             wc_ShaFinal(&sha,  buffer);
    110         }
    111 #ifndef NO_MD5
    112         else {
    113             ret = wc_Md5Update(&md5, buffer, hLen);
    114             if (ret != 0) {
    115                 return ret;
    116             }
    117             ret = wc_Md5Final(&md5,  buffer);
    118             if (ret != 0) {
    119                 return ret;
    120             }
    121         }
    122 #endif
    123     }
    124     XMEMCPY(output, buffer, kLen);
    125 
    126     return 0;
    127 }
    128 #endif /* NO_SHA */
    129 
    130 
    131 int GetDigestSize(int hashType)
    132 {
    133     int hLen;
    134 
    135     switch (hashType) {
    136 #ifndef NO_MD5
    137         case WC_MD5:
    138             hLen = WC_MD5_DIGEST_SIZE;
    139             break;
    140 #endif
    141 #ifndef NO_SHA
    142         case WC_SHA:
    143             hLen = WC_SHA_DIGEST_SIZE;
    144             break;
    145 #endif
    146 #ifndef NO_SHA256
    147         case WC_SHA256:
    148             hLen = WC_SHA256_DIGEST_SIZE;
    149             break;
    150 #endif
    151 #ifdef WOLFSSL_SHA512
    152         case WC_SHA512:
    153             hLen = WC_SHA512_DIGEST_SIZE;
    154             break;
    155 #endif
    156         default:
    157             return BAD_FUNC_ARG;
    158     }
    159 
    160     return hLen;
     164    return wc_PBKDF1_ex(output, kLen, NULL, 0,
     165        passwd, pLen, salt, sLen, iterations, hashType, NULL);
    161166}
    162167
     
    168173    int    hLen;
    169174    int    j, ret;
    170     Hmac   hmac;
    171175#ifdef WOLFSSL_SMALL_STACK
    172176    byte*  buffer;
    173 #else
    174     byte   buffer[MAX_DIGEST_SIZE];
    175 #endif
    176 
    177     hLen = GetDigestSize(hashType);
     177    Hmac*  hmac;
     178#else
     179    byte   buffer[WC_MAX_DIGEST_SIZE];
     180    Hmac   hmac[1];
     181#endif
     182    enum wc_HashType hashT;
     183
     184    if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {
     185        return BAD_FUNC_ARG;
     186    }
     187
     188    if (iterations <= 0)
     189        iterations = 1;
     190
     191    hashT = wc_HashTypeConvert(hashType);
     192    hLen = wc_HashGetDigestSize(hashT);
    178193    if (hLen < 0)
    179194        return BAD_FUNC_ARG;
    180195
    181196#ifdef WOLFSSL_SMALL_STACK
    182     buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     197    buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    183198    if (buffer == NULL)
    184199        return MEMORY_E;
    185 #endif
    186 
    187     ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
     200    hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_HMAC);
     201    if (buffer == NULL)
     202        return MEMORY_E;
     203#endif
     204
     205    ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
    188206    if (ret == 0) {
    189         ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen);
     207        /* use int hashType here, since HMAC FIPS uses the old unique value */
     208        ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);
    190209
    191210        while (ret == 0 && kLen) {
    192211            int currentLen;
    193212
    194             ret = wc_HmacUpdate(&hmac, salt, sLen);
     213            ret = wc_HmacUpdate(hmac, salt, sLen);
    195214            if (ret != 0)
    196215                break;
     
    200219                byte b = (byte)(i >> ((3-j) * 8));
    201220
    202                 ret = wc_HmacUpdate(&hmac, &b, 1);
     221                ret = wc_HmacUpdate(hmac, &b, 1);
    203222                if (ret != 0)
    204223                    break;
     
    209228                break;
    210229
    211             ret = wc_HmacFinal(&hmac, buffer);
     230            ret = wc_HmacFinal(hmac, buffer);
    212231            if (ret != 0)
    213232                break;
     
    217236
    218237            for (j = 1; j < iterations; j++) {
    219                 ret = wc_HmacUpdate(&hmac, buffer, hLen);
     238                ret = wc_HmacUpdate(hmac, buffer, hLen);
    220239                if (ret != 0)
    221240                    break;
    222                 ret = wc_HmacFinal(&hmac, buffer);
     241                ret = wc_HmacFinal(hmac, buffer);
    223242                if (ret != 0)
    224243                    break;
     
    234253            i++;
    235254        }
    236         wc_HmacFree(&hmac);
     255        wc_HmacFree(hmac);
    237256    }
    238257
    239258#ifdef WOLFSSL_SMALL_STACK
    240259    XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     260    XFREE(hmac, NULL, DYNAMIC_TYPE_HMAC);
    241261#endif
    242262
     
    244264}
    245265
    246 #ifdef WOLFSSL_SHA512
    247     #define PBKDF_DIGEST_SIZE WC_SHA512_BLOCK_SIZE
    248 #elif !defined(NO_SHA256)
    249     #define PBKDF_DIGEST_SIZE WC_SHA256_BLOCK_SIZE
    250 #else
    251     #define PBKDF_DIGEST_SIZE WC_SHA_DIGEST_SIZE
    252 #endif
    253 
    254 /* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */
    255 int GetPKCS12HashSizes(int hashType, word32* v, word32* u)
    256 {
    257     if (!v || !u)
    258         return BAD_FUNC_ARG;
    259 
    260     switch (hashType) {
    261 #ifndef NO_MD5
    262         case WC_MD5:
    263             *v = WC_MD5_BLOCK_SIZE;
    264             *u = WC_MD5_DIGEST_SIZE;
    265             break;
    266 #endif
    267 #ifndef NO_SHA
    268         case WC_SHA:
    269             *v = WC_SHA_BLOCK_SIZE;
    270             *u = WC_SHA_DIGEST_SIZE;
    271             break;
    272 #endif
    273 #ifndef NO_SHA256
    274         case WC_SHA256:
    275             *v = WC_SHA256_BLOCK_SIZE;
    276             *u = WC_SHA256_DIGEST_SIZE;
    277             break;
    278 #endif
    279 #ifdef WOLFSSL_SHA512
    280         case WC_SHA512:
    281             *v = WC_SHA512_BLOCK_SIZE;
    282             *u = WC_SHA512_DIGEST_SIZE;
    283             break;
    284 #endif
    285         default:
    286             return BAD_FUNC_ARG;
    287     }
    288 
    289     return 0;
    290 }
    291 
    292266/* helper for PKCS12_PBKDF(), does hash operation */
    293 int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
     267static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
    294268                 byte* Ai, word32 u, int iterations)
    295269{
    296270    int i;
    297271    int ret = 0;
    298 
    299     if (buffer == NULL || Ai == NULL)
     272#ifdef WOLFSSL_SMALL_STACK
     273    wc_HashAlg* hash = NULL;
     274#else
     275    wc_HashAlg  hash[1];
     276#endif
     277    enum wc_HashType hashT;
     278
     279    if (buffer == NULL || Ai == NULL) {
    300280        return BAD_FUNC_ARG;
    301 
    302     switch (hashType) {
    303 #ifndef NO_MD5
    304         case WC_MD5:
    305             {
    306                 wc_Md5 md5;
    307                 ret = wc_InitMd5(&md5);
    308                 if (ret != 0) {
    309                     break;
    310281                }
    311                 ret = wc_Md5Update(&md5, buffer, totalLen);
    312                 if (ret != 0) {
    313                     break;
     282
     283    hashT = wc_HashTypeConvert(hashType);
     284
     285    /* initialize hash */
     286#ifdef WOLFSSL_SMALL_STACK
     287    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
     288                                DYNAMIC_TYPE_HASHCTX);
     289    if (hash == NULL)
     290        return MEMORY_E;
     291#endif
     292
     293    ret = wc_HashInit(hash, hashT);
     294                    if (ret != 0) {
     295    #ifdef WOLFSSL_SMALL_STACK
     296        XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
     297    #endif
     298        return ret;
     299            }
     300
     301    ret = wc_HashUpdate(hash, hashT, buffer, totalLen);
     302
     303    if (ret == 0)
     304        ret = wc_HashFinal(hash, hashT, Ai);
     305
     306                for (i = 1; i < iterations; i++) {
     307        if (ret == 0)
     308            ret = wc_HashUpdate(hash, hashT, Ai, u);
     309        if (ret == 0)
     310            ret = wc_HashFinal(hash, hashT, Ai);
    314311                }
    315                 ret = wc_Md5Final(&md5, Ai);
    316                 if (ret != 0) {
    317                     break;
    318                 }
    319 
    320                 for (i = 1; i < iterations; i++) {
    321                     ret = wc_Md5Update(&md5, Ai, u);
    322                     if (ret != 0) {
    323                         break;
    324                     }
    325                     ret = wc_Md5Final(&md5, Ai);
    326                     if (ret != 0) {
    327                         break;
    328                     }
    329                 }
    330             }
    331             break;
    332 #endif /* NO_MD5 */
    333 #ifndef NO_SHA
    334         case WC_SHA:
    335             {
    336                 wc_Sha sha;
    337                 ret = wc_InitSha(&sha);
    338                 if (ret != 0)
    339                     break;
    340                 ret = wc_ShaUpdate(&sha, buffer, totalLen);
    341                 if (ret != 0) {
    342                     break;
    343                 }
    344                 ret = wc_ShaFinal(&sha, Ai);
    345                 if (ret != 0) {
    346                     break;
    347                 }
    348 
    349                 for (i = 1; i < iterations; i++) {
    350                     ret = wc_ShaUpdate(&sha, Ai, u);
    351                     if (ret != 0) {
    352                         break;
    353                     }
    354                     ret = wc_ShaFinal(&sha, Ai);
    355                     if (ret != 0) {
    356                         break;
    357                     }
    358                 }
    359             }
    360             break;
    361 #endif /* NO_SHA */
    362 #ifndef NO_SHA256
    363         case WC_SHA256:
    364             {
    365                 wc_Sha256 sha256;
    366                 ret = wc_InitSha256(&sha256);
    367                 if (ret != 0)
    368                     break;
    369 
    370                 ret = wc_Sha256Update(&sha256, buffer, totalLen);
    371                 if (ret != 0)
    372                     break;
    373 
    374                 ret = wc_Sha256Final(&sha256, Ai);
    375                 if (ret != 0)
    376                     break;
    377 
    378                 for (i = 1; i < iterations; i++) {
    379                     ret = wc_Sha256Update(&sha256, Ai, u);
    380                     if (ret != 0)
    381                         break;
    382 
    383                     ret = wc_Sha256Final(&sha256, Ai);
    384                     if (ret != 0)
    385                         break;
    386                 }
    387             }
    388             break;
    389 #endif /* NO_SHA256 */
    390 #ifdef WOLFSSL_SHA512
    391         case WC_SHA512:
    392             {
    393                 wc_Sha512 sha512;
    394                 ret = wc_InitSha512(&sha512);
    395                 if (ret != 0)
    396                     break;
    397 
    398                 ret = wc_Sha512Update(&sha512, buffer, totalLen);
    399                 if (ret != 0)
    400                     break;
    401 
    402                 ret = wc_Sha512Final(&sha512, Ai);
    403                 if (ret != 0)
    404                     break;
    405 
    406                 for (i = 1; i < iterations; i++) {
    407                     ret = wc_Sha512Update(&sha512, Ai, u);
    408                     if (ret != 0)
    409                         break;
    410 
    411                     ret = wc_Sha512Final(&sha512, Ai);
    412                     if (ret != 0)
    413                         break;
    414                 }
    415             }
    416             break;
    417 #endif /* WOLFSSL_SHA512 */
    418 
    419         default:
    420             ret = BAD_FUNC_ARG;
    421             break;
    422     }
     312
     313    wc_HashFree(hash, hashT);
     314
     315#ifdef WOLFSSL_SMALL_STACK
     316    XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
     317#endif
    423318
    424319    return ret;
     
    426321
    427322
    428 int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
    429                  int saltLen, int iterations, int kLen, int hashType, int id)
     323int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
     324    const byte* salt, int saltLen, int iterations, int kLen, int hashType,
     325    int id)
    430326{
    431327    return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,
     
    456352    byte*  B;
    457353#else
    458     byte   Ai[PBKDF_DIGEST_SIZE];
    459     byte   B[PBKDF_DIGEST_SIZE];
    460 #endif
    461 
    462     if (!iterations)
     354    byte   Ai[WC_MAX_DIGEST_SIZE];
     355    byte   B[WC_MAX_BLOCK_SIZE];
     356#endif
     357    enum wc_HashType hashT;
     358
     359    (void)heap;
     360
     361    if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) {
     362        return BAD_FUNC_ARG;
     363    }
     364
     365    if (iterations <= 0)
    463366        iterations = 1;
    464367
    465     ret = GetPKCS12HashSizes(hashType, &v, &u);
     368    hashT = wc_HashTypeConvert(hashType);
     369    ret = wc_HashGetDigestSize(hashT);
    466370    if (ret < 0)
    467         return BAD_FUNC_ARG;
    468 
    469 #ifdef WOLFSSL_SMALL_STACK
    470     Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     371        return ret;
     372    u = ret;
     373
     374    ret = wc_HashGetBlockSize(hashT);
     375    if (ret < 0)
     376        return ret;
     377    v = ret;
     378
     379#ifdef WOLFSSL_SMALL_STACK
     380    Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
    471381    if (Ai == NULL)
    472382        return MEMORY_E;
    473383
    474     B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     384    B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
    475385    if (B == NULL) {
    476         XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     386        XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
    477387        return MEMORY_E;
    478388    }
    479389#endif
    480390
    481     XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE);
    482     XMEMSET(B,  0, PBKDF_DIGEST_SIZE);
     391    XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE);
     392    XMEMSET(B,  0, WC_MAX_BLOCK_SIZE);
    483393
    484394    dLen = v;
     
    496406        if (buffer == NULL) {
    497407#ifdef WOLFSSL_SMALL_STACK
    498             XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    499             XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
     408            XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
     409            XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);
    500410#endif
    501411            return MEMORY_E;
     
    584494
    585495#ifdef WOLFSSL_SMALL_STACK
    586     XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    587     XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
     496    XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
     497    XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);
    588498#endif
    589499
     
    740650#else
    741651        byte* t = x + (2*r - 1) * 64;
    742         j = (t[0] | (t[1] << 8) | (t[2] << 16) | (t[3] << 24)) & (n-1);
     652        j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1);
    743653#endif
    744654#ifdef WORD64_AVAILABLE
     
    828738#endif
    829739
    830 #undef PBKDF_DIGEST_SIZE
     740#undef WC_MAX_DIGEST_SIZE
    831741
    832742#endif /* NO_PWDBASED */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/rabbit.c

    r352 r372  
    146146
    147147/* Key setup */
    148 static INLINE int DoKey(Rabbit* ctx, const byte* key, const byte* iv)
     148static WC_INLINE int DoKey(Rabbit* ctx, const byte* key, const byte* iv)
    149149{
    150150    /* Temporary variables */
     
    248248
    249249/* Encrypt/decrypt a message of any size */
    250 static INLINE int DoProcess(Rabbit* ctx, byte* output, const byte* input,
     250static WC_INLINE int DoProcess(Rabbit* ctx, byte* output, const byte* input,
    251251                            word32 msglen)
    252252{
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/random.c

    r352 r372  
    2626
    2727#include <wolfssl/wolfcrypt/settings.h>
     28#include <wolfssl/wolfcrypt/error-crypt.h>
    2829
    2930/* on HPUX 11 you may need to install /dev/random see
     
    3233*/
    3334
     35#if defined(HAVE_FIPS) && \
     36        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     37
     38    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     39    #define FIPS_NO_WRAPPERS
     40
     41    #ifdef USE_WINDOWS_API
     42        #pragma code_seg(".fipsA$c")
     43        #pragma const_seg(".fipsB$c")
     44    #endif
     45#endif
     46
     47
    3448#include <wolfssl/wolfcrypt/random.h>
    3549#include <wolfssl/wolfcrypt/cpuid.h>
    3650
    3751
    38 #ifdef HAVE_FIPS
     52/* If building for old FIPS. */
     53#if defined(HAVE_FIPS) && \
     54    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     55
    3956int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)
    4057{
     
    7390    }
    7491
    75     int wc_RNG_HealthTest(int reseed,
    76                                         const byte* entropyA, word32 entropyASz,
    77                                         const byte* entropyB, word32 entropyBSz,
     92    int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
     93                                      const byte* seedB, word32 seedBSz,
    7894                                        byte* output, word32 outputSz)
    7995    {
    80         return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
    81                               entropyB, entropyBSz, output, outputSz);
     96        return RNG_HealthTest_fips(reseed, seedA, seedASz,
     97                              seedB, seedBSz, output, outputSz);
    8298    }
    8399#endif /* HAVE_HASHDRBG */
    84100
    85 #else /* else build without fips */
     101#else /* else build without fips, or for new fips */
    86102
    87103#ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */
    88104
    89 #include <wolfssl/wolfcrypt/error-crypt.h>
    90105#include <wolfssl/wolfcrypt/sha256.h>
    91106
     
    127142#elif defined(WOLFSSL_EMBOS)
    128143#elif defined(MICRIUM)
     144#elif defined(WOLFSSL_NUCLEUS)
     145#elif defined(WOLFSSL_PB)
    129146#else
    130147    /* include headers that may be needed to get good seed */
     
    148165    static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);
    149166    #endif
     167
     168#ifdef USE_WINDOWS_API
     169    #include <immintrin.h>
     170#endif /* USE_WINDOWS_API */
    150171#endif
    151172
     
    156177#define MAX_REQUEST_LEN   (0x10000)
    157178#define RESEED_INTERVAL   WC_RESEED_INTERVAL
    158 #define SECURITY_STRENGTH (256)
    159 #define ENTROPY_SZ        (SECURITY_STRENGTH/8)
    160 #define NONCE_SZ          (ENTROPY_SZ/2)
    161 #define ENTROPY_NONCE_SZ  (ENTROPY_SZ+NONCE_SZ)
     179
     180
     181/* For FIPS builds, the user should not be adjusting the values. */
     182#if defined(HAVE_FIPS) && \
     183    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     184    #if defined(RNG_SECURITY_STRENGTH) \
     185            || defined(ENTROPY_SCALE_FACTOR) \
     186            || defined(SEED_BLOCK_SZ)
     187
     188        #error "Do not change the RNG parameters for FIPS builds."
     189    #endif
     190#endif
     191
     192
     193/* The security strength for the RNG is the target number of bits of
     194 * entropy you are looking for in a seed. */
     195#ifndef RNG_SECURITY_STRENGTH
     196    #if defined(HAVE_FIPS) && \
     197            defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     198        /* SHA-256 requires a minimum of 256-bits of entropy. The goal
     199         * of 1024 will provide 4 times that. */
     200        #define RNG_SECURITY_STRENGTH (1024)
     201    #else
     202        /* If not using FIPS or using old FIPS, set the number down a bit.
     203         * More is better, but more is also slower. */
     204        #define RNG_SECURITY_STRENGTH (256)
     205    #endif
     206#endif
     207
     208#ifndef ENTROPY_SCALE_FACTOR
     209    /* The entropy scale factor should be the whole number inverse of the
     210     * minimum bits of entropy per bit of NDRNG output. */
     211    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
     212        /* The value of 2 applies to Intel's RDSEED which provides about
     213         * 0.5 bits minimum of entropy per bit. */
     214        #define ENTROPY_SCALE_FACTOR 2
     215    #else
     216        /* Setting the default to 1. */
     217        #define ENTROPY_SCALE_FACTOR 1
     218    #endif
     219#endif
     220
     221#ifndef SEED_BLOCK_SZ
     222    /* The seed block size, is the size of the output of the underlying NDRNG.
     223     * This value is used for testing the output of the NDRNG. */
     224    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
     225        /* RDSEED outputs in blocks of 64-bits. */
     226        #define SEED_BLOCK_SZ sizeof(word64)
     227    #else
     228        /* Setting the default to 4. */
     229        #define SEED_BLOCK_SZ 4
     230    #endif
     231#endif
     232
     233#define SEED_SZ        (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8)
     234
     235/* The maximum seed size will be the seed size plus a seed block for the
     236 * test, and an additional half of the seed size. This additional half
     237 * is in case the user does not supply a nonce. A nonce will be obtained
     238 * from the NDRNG. */
     239#define MAX_SEED_SZ    (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)
     240
    162241
    163242/* Internal return codes */
    164243#define DRBG_SUCCESS      0
    165 #define DRBG_ERROR        1
    166 #define DRBG_FAILURE      2
    167 #define DRBG_NEED_RESEED  3
    168 #define DRBG_CONT_FAILURE 4
     244#define DRBG_FAILURE      1
     245#define DRBG_NEED_RESEED  2
     246#define DRBG_CONT_FAILURE 3
    169247
    170248/* RNG health states */
     
    200278#endif
    201279    byte   matchCount;
     280#ifdef WOLFSSL_SMALL_STACK_CACHE
     281    wc_Sha256 sha256;
     282#endif
    202283} DRBG;
    203284
     
    216297    int len;
    217298    word32 bits = (outSz * 8); /* reverse byte order */
    218     wc_Sha256 sha;
     299#ifdef WOLFSSL_SMALL_STACK_CACHE
     300    wc_Sha256* sha = &drbg->sha256;
     301#else
     302    wc_Sha256 sha[1];
     303#endif
     304#ifdef WC_ASYNC_ENABLE_SHA256
    219305    DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
     306#else
     307    byte digest[WC_SHA256_DIGEST_SIZE];
     308#endif
    220309
    221310    (void)drbg;
    222 #ifdef WOLFSSL_ASYNC_CRYPT
     311#ifdef WC_ASYNC_ENABLE_SHA256
    223312    if (digest == NULL)
    224313        return DRBG_FAILURE;
     
    232321
    233322    for (i = 0, ctr = 1; i < len; i++, ctr++) {
     323#ifndef WOLFSSL_SMALL_STACK_CACHE
    234324    #ifdef WOLFSSL_ASYNC_CRYPT
    235         ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
     325        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
    236326    #else
    237         ret = wc_InitSha256(&sha);
     327        ret = wc_InitSha256(sha);
    238328    #endif
    239329        if (ret != 0)
     
    241331
    242332        if (ret == 0)
    243             ret = wc_Sha256Update(&sha, &ctr, sizeof(ctr));
     333#endif
     334            ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));
    244335        if (ret == 0)
    245             ret = wc_Sha256Update(&sha, (byte*)&bits, sizeof(bits));
     336            ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));
    246337
    247338        if (ret == 0) {
    248339            /* churning V is the only string that doesn't have the type added */
    249340            if (type != drbgInitV)
    250                 ret = wc_Sha256Update(&sha, &type, sizeof(type));
     341                ret = wc_Sha256Update(sha, &type, sizeof(type));
    251342        }
    252343        if (ret == 0)
    253             ret = wc_Sha256Update(&sha, inA, inASz);
     344            ret = wc_Sha256Update(sha, inA, inASz);
    254345        if (ret == 0) {
    255346            if (inB != NULL && inBSz > 0)
    256                 ret = wc_Sha256Update(&sha, inB, inBSz);
     347                ret = wc_Sha256Update(sha, inB, inBSz);
    257348        }
    258349        if (ret == 0)
    259             ret = wc_Sha256Final(&sha, digest);
    260 
    261         wc_Sha256Free(&sha);
     350            ret = wc_Sha256Final(sha, digest);
     351
     352#ifndef WOLFSSL_SMALL_STACK_CACHE
     353        wc_Sha256Free(sha);
     354#endif
    262355        if (ret == 0) {
    263356            if (outSz > OUTPUT_BLOCK_LEN) {
     
    274367    ForceZero(digest, WC_SHA256_DIGEST_SIZE);
    275368
     369#ifdef WC_ASYNC_ENABLE_SHA256
    276370    FREE_VAR(digest, drbg->heap);
     371#endif
    277372
    278373    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
     
    280375
    281376/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
    282 static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
    283 {
    284     byte seed[DRBG_SEED_LEN];
    285 
    286     if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
    287                                           entropy, entropySz) != DRBG_SUCCESS) {
     377static int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz)
     378{
     379    byte newV[DRBG_SEED_LEN];
     380
     381    XMEMSET(newV, 0, DRBG_SEED_LEN);
     382
     383    if (Hash_df(drbg, newV, sizeof(newV), drbgReseed,
     384                drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) {
    288385        return DRBG_FAILURE;
    289386    }
    290387
    291     XMEMCPY(drbg->V, seed, sizeof(drbg->V));
    292     ForceZero(seed, sizeof(seed));
     388    XMEMCPY(drbg->V, newV, sizeof(drbg->V));
     389    ForceZero(newV, sizeof(newV));
    293390
    294391    if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
     
    303400}
    304401
    305 static INLINE void array_add_one(byte* data, word32 dataSz)
     402/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
     403int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)
     404{
     405    if (rng == NULL || seed == NULL) {
     406        return BAD_FUNC_ARG;
     407    }
     408
     409    return Hash_DRBG_Reseed(rng->drbg, seed, seedSz);
     410}
     411
     412static WC_INLINE void array_add_one(byte* data, word32 dataSz)
    306413{
    307414    int i;
     
    322429    int len;
    323430    word32 checkBlock;
    324     wc_Sha256 sha;
     431#ifdef WOLFSSL_SMALL_STACK_CACHE
     432    wc_Sha256* sha = &drbg->sha256;
     433#else
     434    wc_Sha256 sha[1];
     435#endif
     436#ifdef WC_ASYNC_ENABLE_SHA256
    325437    DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
     438#else
     439    byte digest[WC_SHA256_DIGEST_SIZE];
     440#endif
    326441
    327442    /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for
     
    334449    XMEMCPY(data, V, sizeof(data));
    335450    for (i = 0; i < len; i++) {
     451#ifndef WOLFSSL_SMALL_STACK_CACHE
    336452    #ifdef WOLFSSL_ASYNC_CRYPT
    337         ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
     453        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
    338454    #else
    339         ret = wc_InitSha256(&sha);
     455        ret = wc_InitSha256(sha);
    340456    #endif
    341457        if (ret == 0)
    342             ret = wc_Sha256Update(&sha, data, sizeof(data));
     458#endif
     459            ret = wc_Sha256Update(sha, data, sizeof(data));
    343460        if (ret == 0)
    344             ret = wc_Sha256Final(&sha, digest);
    345         wc_Sha256Free(&sha);
     461            ret = wc_Sha256Final(sha, digest);
     462#ifndef WOLFSSL_SMALL_STACK_CACHE
     463        wc_Sha256Free(sha);
     464#endif
    346465
    347466        if (ret == 0) {
     
    379498    ForceZero(data, sizeof(data));
    380499
     500#ifdef WC_ASYNC_ENABLE_SHA256
    381501    FREE_VAR(digest, drbg->heap);
     502#endif
    382503
    383504    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
    384505}
    385506
    386 static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
     507static WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
    387508{
    388509    word16 carry = 0;
     
    410531{
    411532    int ret;
    412     wc_Sha256 sha;
     533#ifdef WOLFSSL_SMALL_STACK_CACHE
     534    wc_Sha256* sha = &drbg->sha256;
     535#else
     536    wc_Sha256 sha[1];
     537#endif
    413538    byte type;
    414539    word32 reseedCtr;
     
    417542        return DRBG_NEED_RESEED;
    418543    } else {
     544    #ifdef WC_ASYNC_ENABLE_SHA256
    419545        DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);
     546    #else
     547        byte digest[WC_SHA256_DIGEST_SIZE];
     548    #endif
    420549        type = drbgGenerateH;
    421550        reseedCtr = drbg->reseedCtr;
     
    423552        ret = Hash_gen(drbg, out, outSz, drbg->V);
    424553        if (ret == DRBG_SUCCESS) {
     554#ifndef WOLFSSL_SMALL_STACK_CACHE
    425555        #ifdef WOLFSSL_ASYNC_CRYPT
    426             ret = wc_InitSha256_ex(&sha, drbg->heap, drbg->devId);
     556            ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);
    427557        #else
    428             ret = wc_InitSha256(&sha);
     558            ret = wc_InitSha256(sha);
    429559        #endif
    430560            if (ret == 0)
    431                 ret = wc_Sha256Update(&sha, &type, sizeof(type));
     561#endif
     562                ret = wc_Sha256Update(sha, &type, sizeof(type));
    432563            if (ret == 0)
    433                 ret = wc_Sha256Update(&sha, drbg->V, sizeof(drbg->V));
     564                ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));
    434565            if (ret == 0)
    435                 ret = wc_Sha256Final(&sha, digest);
    436 
    437             wc_Sha256Free(&sha);
     566                ret = wc_Sha256Final(sha, digest);
     567
     568#ifndef WOLFSSL_SMALL_STACK_CACHE
     569            wc_Sha256Free(sha);
     570#endif
    438571
    439572            if (ret == 0) {
     
    450583        }
    451584        ForceZero(digest, WC_SHA256_DIGEST_SIZE);
     585    #ifdef WC_ASYNC_ENABLE_SHA256
    452586        FREE_VAR(digest, drbg->heap);
     587    #endif
    453588    }
    454589
     
    472607#endif
    473608
     609#ifdef WOLFSSL_SMALL_STACK_CACHE
     610    #ifdef WOLFSSL_ASYNC_CRYPT
     611        ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);
     612    #else
     613        ret = wc_InitSha256(&drbg->sha256);
     614    #endif
     615    if (ret != 0)
     616        return ret;
     617#endif
     618
    474619    if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
    475620                                              nonce, nonceSz) == DRBG_SUCCESS &&
     
    493638    byte*  compareDrbg = (byte*)drbg;
    494639
     640#ifdef WOLFSSL_SMALL_STACK_CACHE
     641    wc_Sha256Free(&drbg->sha256);
     642#endif
     643
    495644    ForceZero(drbg, sizeof(DRBG));
    496645
     
    500649    return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
    501650}
     651
     652
     653int wc_RNG_TestSeed(const byte* seed, word32 seedSz)
     654{
     655    int ret = DRBG_SUCCESS;
     656
     657    /* Check the seed for duplicate words. */
     658    word32 seedIdx = 0;
     659    word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ);
     660
     661    while (seedIdx < seedSz - SEED_BLOCK_SZ) {
     662        if (ConstantCompare(seed + seedIdx,
     663                            seed + seedIdx + scratchSz,
     664                            scratchSz) == 0) {
     665
     666            ret = DRBG_CONT_FAILURE;
     667        }
     668        seedIdx += SEED_BLOCK_SZ;
     669        scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx));
     670    }
     671
     672    return ret;
     673}
    502674#endif /* HAVE_HASHDRBG */
    503675/* End NIST DRBG Code */
    504676
    505677
    506 int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
     678static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
     679                    void* heap, int devId)
    507680{
    508681    int ret = RNG_FAILURE_E;
     682#ifdef HAVE_HASHDRBG
     683    word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;
     684#endif
     685
     686    (void)nonce;
     687    (void)nonceSz;
    509688
    510689    if (rng == NULL)
     690        return BAD_FUNC_ARG;
     691    if (nonce == NULL && nonceSz != 0)
    511692        return BAD_FUNC_ARG;
    512693
     
    552733#else
    553734#ifdef HAVE_HASHDRBG
     735    if (nonceSz == 0)
     736        seedSz = MAX_SEED_SZ;
     737
    554738    if (wc_RNG_HealthTestLocal(0) == 0) {
    555         DECLARE_VAR(entropy, byte, ENTROPY_NONCE_SZ, rng->heap);
     739    #ifdef WC_ASYNC_ENABLE_SHA256
     740        DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap);
     741    #else
     742        byte seed[MAX_SEED_SZ];
     743    #endif
    556744
    557745        rng->drbg =
     
    561749            ret = MEMORY_E;
    562750        }
    563         /* This doesn't use a separate nonce. The entropy input will be
    564          * the default size plus the size of the nonce making the seed
    565          * size. */
    566         else if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
    567                  Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
    568                                    NULL, 0, rng->heap, devId) == DRBG_SUCCESS) {
     751        else {
     752            ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
     753            if (ret != 0)
     754                ret = DRBG_FAILURE;
     755            else
     756                ret = wc_RNG_TestSeed(seed, seedSz);
     757
     758            if (ret == DRBG_SUCCESS)
     759                 ret = Hash_DRBG_Instantiate(rng->drbg,
     760                            seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
     761                            nonce, nonceSz, rng->heap, devId);
     762
     763            if (ret == DRBG_SUCCESS)
    569764            ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
    570765        }
    571         else
    572             ret = DRBG_FAILURE;
    573 
    574         ForceZero(entropy, ENTROPY_NONCE_SZ);
    575         FREE_VAR(entropy, rng->heap);
     766
     767        ForceZero(seed, seedSz);
     768    #ifdef WC_ASYNC_ENABLE_SHA256
     769        FREE_VAR(seed, rng->heap);
     770    #endif
    576771    }
    577772    else
     
    599794}
    600795
     796
    601797int wc_InitRng(WC_RNG* rng)
    602798{
    603     return wc_InitRng_ex(rng, NULL, INVALID_DEVID);
     799    return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
     800}
     801
     802
     803int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
     804{
     805    return _InitRng(rng, NULL, 0, heap, devId);
     806}
     807
     808
     809int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
     810{
     811    return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
     812}
     813
     814
     815int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
     816                       void* heap, int devId)
     817{
     818    return _InitRng(rng, nonce, nonceSz, heap, devId);
    604819}
    605820
     
    623838    #ifdef HAVE_CAVIUM
    624839        return NitroxRngGenerateBlock(rng, output, sz);
    625     #elif defined(HAVE_INTEL_QA)
     840    #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG)
    626841        return IntelQaDrbg(&rng->asyncDev, output, sz);
    627842    #else
     
    646861    if (ret == DRBG_NEED_RESEED) {
    647862        if (wc_RNG_HealthTestLocal(1) == 0) {
    648             byte entropy[ENTROPY_SZ];
    649 
    650             if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
    651                 Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
    652                                                               == DRBG_SUCCESS) {
    653 
     863            byte newSeed[SEED_SZ + SEED_BLOCK_SZ];
     864
     865            ret = wc_GenerateSeed(&rng->seed, newSeed,
     866                                  SEED_SZ + SEED_BLOCK_SZ);
     867            if (ret != 0)
     868                ret = DRBG_FAILURE;
     869            else
     870                ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ);
     871
     872            if (ret == DRBG_SUCCESS)
     873                ret = Hash_DRBG_Reseed(rng->drbg, newSeed + SEED_BLOCK_SZ,
     874                                       SEED_SZ);
     875            if (ret == DRBG_SUCCESS)
    654876                ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
    655877                if (ret == DRBG_SUCCESS)
    656878                    ret = Hash_DRBG_Generate(rng->drbg, output, sz);
    657             }
    658             else
    659                 ret = DRBG_FAILURE;
    660 
    661             ForceZero(entropy, ENTROPY_SZ);
     879
     880            ForceZero(newSeed, sizeof(newSeed));
    662881        }
    663882        else
     
    721940
    722941#ifdef HAVE_HASHDRBG
    723 int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
    724                                   const byte* entropyB, word32 entropyBSz,
     942int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
     943                                  const byte* seedB, word32 seedBSz,
    725944                                  byte* output, word32 outputSz)
     945{
     946    return wc_RNG_HealthTest_ex(reseed, NULL, 0,
     947                                seedA, seedASz, seedB, seedBSz,
     948                                output, outputSz,
     949                                NULL, INVALID_DEVID);
     950}
     951
     952
     953int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
     954                                  const byte* seedA, word32 seedASz,
     955                                  const byte* seedB, word32 seedBSz,
     956                                  byte* output, word32 outputSz,
     957                                  void* heap, int devId)
    726958{
    727959    int ret = -1;
     
    731963#endif
    732964
    733     if (entropyA == NULL || output == NULL) {
     965    if (seedA == NULL || output == NULL) {
    734966        return BAD_FUNC_ARG;
    735967    }
    736968
    737     if (reseed != 0 && entropyB == NULL) {
     969    if (reseed != 0 && seedB == NULL) {
    738970        return BAD_FUNC_ARG;
    739971    }
     
    744976
    745977#ifdef WOLFSSL_SMALL_STACK
    746     drbg = (struct DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
     978    drbg = (DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
    747979    if (drbg == NULL) {
    748980        return MEMORY_E;
     
    752984#endif
    753985
    754     if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, NULL, 0, NULL,
    755                                                     INVALID_DEVID) != 0) {
     986    if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz,
     987                              heap, devId) != 0) {
    756988        goto exit_rng_ht;
    757989    }
    758990
    759991    if (reseed) {
    760         if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) {
     992        if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) {
    761993            goto exit_rng_ht;
    762994        }
     
    7891021
    7901022
    791 const byte entropyA[] = {
     1023const byte seedA[] = {
    7921024    0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
    7931025    0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
     
    7961028};
    7971029
    798 const byte reseedEntropyA[] = {
     1030const byte reseedSeedA[] = {
    7991031    0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
    8001032    0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
     
    8161048};
    8171049
    818 const byte entropyB[] = {
     1050const byte seedB[] = {
    8191051    0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
    8201052    0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
    821     0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
    822     0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
     1053    0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
     1054    0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
     1055    0xdb, 0xcb, 0xcc, 0x2e
    8231056};
    8241057
     
    8561089
    8571090    if (reseed) {
    858         ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
    859                                 reseedEntropyA, sizeof(reseedEntropyA),
     1091        ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA),
     1092                                reseedSeedA, sizeof(reseedSeedA),
    8601093                                check, RNG_HEALTH_TEST_CHECK_SIZE);
    8611094        if (ret == 0) {
     
    8661099    }
    8671100    else {
    868         ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
     1101        ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB),
    8691102                                NULL, 0,
    8701103                                check, RNG_HEALTH_TEST_CHECK_SIZE);
     
    8731106                                RNG_HEALTH_TEST_CHECK_SIZE) != 0)
    8741107                ret = -1;
     1108        }
     1109
     1110        /* The previous test cases use a large seed instead of a seed and nonce.
     1111         * seedB is actually from a test case with a seed and nonce, and
     1112         * just concatenates them. The pivot point between seed and nonce is
     1113         * byte 32, feed them into the health test separately. */
     1114        if (ret == 0) {
     1115            ret = wc_RNG_HealthTest_ex(0,
     1116                                    seedB + 32, sizeof(seedB) - 32,
     1117                                    seedB, 32,
     1118                                    NULL, 0,
     1119                                    check, RNG_HEALTH_TEST_CHECK_SIZE,
     1120                                    NULL, INVALID_DEVID);
     1121            if (ret == 0) {
     1122                if (ConstantCompare(check, outputB, sizeof(outputB)) != 0)
     1123                    ret = -1;
     1124            }
    8751125        }
    8761126    }
     
    9951245#ifdef HAVE_INTEL_RDSEED
    9961246
     1247#ifndef USE_WINDOWS_API
     1248
    9971249/* return 0 on success */
    998 static INLINE int IntelRDseed64(word64* seed)
     1250    static WC_INLINE int IntelRDseed64(word64* seed)
    9991251{
    10001252    unsigned char ok;
     
    10041256}
    10051257
     1258#else /* USE_WINDOWS_API */
     1259    /* The compiler Visual Studio uses does not allow inline assembly.
     1260     * It does allow for Intel intrinsic functions. */
     1261
    10061262/* return 0 on success */
    1007 static INLINE int IntelRDseed64_r(word64* rnd)
     1263    static WC_INLINE int IntelRDseed64(word64* seed)
     1264    {
     1265        int ok;
     1266
     1267        ok = _rdseed64_step(seed);
     1268        return (ok) ? 0 : -1;
     1269    }
     1270
     1271#endif /* USE_WINDOWS_API */
     1272
     1273/* return 0 on success */
     1274static WC_INLINE int IntelRDseed64_r(word64* rnd)
    10081275{
    10091276    int i;
     
    10411308
    10421309    XMEMCPY(output, &rndTmp, sz);
     1310    ForceZero(&rndTmp, sizeof(rndTmp));
    10431311
    10441312    return 0;
     
    10491317#ifdef HAVE_INTEL_RDRAND
    10501318
     1319#ifndef USE_WINDOWS_API
     1320
    10511321/* return 0 on success */
    1052 static INLINE int IntelRDrand64(word64 *rnd)
     1322static WC_INLINE int IntelRDrand64(word64 *rnd)
    10531323{
    10541324    unsigned char ok;
     
    10591329}
    10601330
     1331#else /* USE_WINDOWS_API */
     1332    /* The compiler Visual Studio uses does not allow inline assembly.
     1333     * It does allow for Intel intrinsic functions. */
     1334
    10611335/* return 0 on success */
    1062 static INLINE int IntelRDrand64_r(word64 *rnd)
     1336static WC_INLINE int IntelRDrand64(word64 *rnd)
     1337{
     1338    int ok;
     1339
     1340    ok = _rdrand64_step(rnd);
     1341
     1342    return (ok) ? 0 : -1;
     1343}
     1344
     1345#endif /* USE_WINDOWS_API */
     1346
     1347/* return 0 on success */
     1348static WC_INLINE int IntelRDrand64_r(word64 *rnd)
    10631349{
    10641350    int i;
     
    11821468int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
    11831469{
     1470    #ifdef HAVE_INTEL_RDSEED
     1471        if (IS_INTEL_RDSEED(intel_flags)) {
     1472             if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) {
     1473                 /* success, we're done */
     1474                 return 0;
     1475             }
     1476        #ifdef FORCE_FAILURE_RDSEED
     1477             /* don't fall back to CryptoAPI */
     1478             return READ_RAN_E;
     1479        #endif
     1480        }
     1481    #endif /* HAVE_INTEL_RDSEED */
     1482
    11841483    if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
    11851484                            CRYPT_VERIFYCONTEXT))
     
    13021601        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
    13031602        {
    1304             int i;
     1603            word32 i;
    13051604
    13061605            /* turn on RNGA module */
     
    14181717
    14191718#elif defined(STM32_RNG)
    1420     /*
    1421      * wc_Generate a RNG seed using the hardware random number generator
     1719     /* Generate a RNG seed using the hardware random number generator
    14221720     * on the STM32F2/F4/F7. */
    14231721
     
    14431741        return 0;
    14441742    }
     1743    #elif defined(WOLFSSL_STM32F427_RNG)
     1744
     1745    /* Generate a RNG seed using the hardware RNG on the STM32F427
     1746     * directly, following steps outlined in STM32F4 Reference
     1747     * Manual (Chapter 24) for STM32F4xx family. */
     1748    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     1749    {
     1750        int i;
     1751        (void)os;
     1752
     1753        /* enable RNG peripheral clock */
     1754        RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
     1755
     1756        /* enable RNG interrupt, set IE bit in RNG->CR register */
     1757        RNG->CR |= RNG_CR_IE;
     1758
     1759        /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,
     1760         * RNG_LFSR, and error detector */
     1761        RNG->CR |= RNG_CR_RNGEN;
     1762
     1763        /* verify no errors, make sure SEIS and CEIS bits are 0
     1764         * in RNG->SR register */
     1765        if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS))
     1766            return RNG_FAILURE_E;
     1767
     1768        for (i = 0; i < (int)sz; i++) {
     1769            /* wait until RNG number is ready */
     1770            while ((RNG->SR & RNG_SR_DRDY) == 0) { }
     1771
     1772            /* get value */
     1773            output[i] = RNG->DR;
     1774        }
     1775
     1776        return 0;
     1777    }
     1778
    14451779    #else
     1780
     1781    /* Generate a RNG seed using the STM32 Standard Peripheral Library */
    14461782    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
    14471783    {
     
    14931829    }
    14941830
     1831#elif defined(WOLFSSL_PB)
     1832
     1833    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     1834    {
     1835        word32 i;
     1836        for (i = 0; i < sz; i++)
     1837            output[i] = UTL_Rand();
     1838
     1839        (void)os;
     1840
     1841        return 0;
     1842    }
     1843
     1844#elif defined(WOLFSSL_NUCLEUS)
     1845#include "nucleus.h"
     1846#include "kernel/plus_common.h"
     1847
     1848#warning "potential for not enough entropy, currently being used for testing"
     1849int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     1850{
     1851    int i;
     1852    srand(NU_Get_Time_Stamp());
     1853
     1854    for (i = 0; i < sz; i++ ) {
     1855        output[i] = rand() % 256;
     1856        if ((i % 8) == 7) {
     1857            srand(NU_Get_Time_Stamp());
     1858        }
     1859    }
     1860
     1861    return 0;
     1862}
    14951863#elif defined(WOLFSSL_VXWORKS)
    14961864
     
    16301998    }
    16311999
     2000#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG))
     2001
     2002    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
     2003    #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>
     2004
     2005    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     2006    {
     2007        Buffer buf[1];
     2008        int ret  = 0;
     2009        int times = 1000, i;
     2010
     2011        (void)os;
     2012
     2013        if (output == NULL) {
     2014            return BUFFER_E;
     2015        }
     2016
     2017        buf[0].BufferType = DataBuffer | LastBuffer;
     2018        buf[0].TheAddress = (Address)output;
     2019        buf[0].Length     = sz;
     2020
     2021        /* Check Waiting to make sure entropy is ready */
     2022        for (i = 0; i < times; i++) {
     2023            ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY);
     2024            if (ret == Success) {
     2025                break;
     2026            }
     2027
     2028            /* driver could be waiting for entropy */
     2029            if (ret != RAN_BLOCK_E) {
     2030                return ret;
     2031            }
     2032            usleep(100);
     2033        }
     2034
     2035        if (i == times && ret != Success) {
     2036             return RNG_FAILURE_E;
     2037        }
     2038        else { /* Success case */
     2039            ret = 0;
     2040        }
     2041
     2042        return ret;
     2043    }
     2044
     2045#elif defined(WOLFSSL_APACHE_MYNEWT)
     2046
     2047    #include <stdlib.h>
     2048    #include "os/os_time.h"
     2049    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     2050    {
     2051        int i;
     2052        srand(os_time_get());
     2053
     2054        for (i = 0; i < sz; i++ ) {
     2055            output[i] = rand() % 256;
     2056            if ((i % 8) == 7) {
     2057                srand(os_time_get());
     2058            }
     2059        }
     2060
     2061        return 0;
     2062    }
     2063
     2064#elif defined(WOLFSSL_ESPIDF)
     2065    #if defined(WOLFSSL_ESPWROOM32)
     2066        #include <esp_system.h>
     2067       
     2068        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
     2069        {
     2070            int i;
     2071           
     2072            for (i = 0; i< sz; i++) {
     2073               output[i] =  esp_random( );
     2074            }
     2075       
     2076            return 0;
     2077        }
     2078    #endif /* end WOLFSSL_ESPWROOM32 */
     2079 
    16322080#elif defined(CUSTOM_RAND_GENERATE_BLOCK)
    16332081    /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc
     
    16402088      defined(WOLFSSL_LPC43xx)  || defined(WOLFSSL_STM32F2xx) || \
    16412089      defined(MBED)             || defined(WOLFSSL_EMBOS) || \
    1642       defined(WOLFSSL_GENSEED_FORTEST)
     2090      defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \
     2091      defined(WOLFSSL_CONTIKI)
    16432092
    16442093    /* these platforms do not have a default random seed and
     
    16772126             return ret;
    16782127    #else
    1679              /* fallback to /dev/urandom attempt */
     2128             /* reset error and fallback to using /dev/urandom */
    16802129             ret = 0;
    16812130    #endif
    16822131        }
    1683 
    16842132    #endif /* HAVE_INTEL_RDSEED */
    16852133
     2134    #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */
    16862135        os->fd = open("/dev/urandom",O_RDONLY);
    1687         if (os->fd == -1) {
     2136        if (os->fd == -1)
     2137    #endif
     2138        {
    16882139            /* may still have /dev/random */
    16892140            os->fd = open("/dev/random",O_RDONLY);
     
    17032154
    17042155            if (sz) {
    1705     #ifdef BLOCKING
     2156    #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)
    17062157                sleep(0);             /* context switch */
    17072158    #else
     
    17382189
    17392190/* End wc_GenerateSeed */
    1740 
    17412191#endif /* WC_NO_RNG */
    17422192#endif /* HAVE_FIPS */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/ripemd.c

    r352 r372  
    272272
    273273
    274 static INLINE void AddLength(RipeMd* ripemd, word32 len)
     274static WC_INLINE void AddLength(RipeMd* ripemd, word32 len)
    275275{
    276276    word32 tmp = ripemd->loLen;
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/rsa.c

    r352 r372  
    3030#ifndef NO_RSA
    3131
     32#if defined(HAVE_FIPS) && \
     33    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     34
     35    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     36    #define FIPS_NO_WRAPPERS
     37
     38       #ifdef USE_WINDOWS_API
     39               #pragma code_seg(".fipsA$e")
     40               #pragma const_seg(".fipsB$e")
     41       #endif
     42#endif
     43
    3244#include <wolfssl/wolfcrypt/rsa.h>
    3345
     
    4456 * RSA_LOW_MEM:         NON CRT Private Operations, less memory     default: off
    4557 * WC_NO_RSA_OAEP:      Disables RSA OAEP padding                   default: on (not defined)
    46 
     58 * WC_RSA_NONBLOCK:     Enables support for RSA non-blocking        default: off
     59 * WC_RSA_NONBLOCK_TIME:Enables support for time based blocking     default: off
     60 *                      time calculation.
    4761*/
    4862
     
    5569
    5670
    57 #ifdef HAVE_FIPS
     71/* If building for old FIPS. */
     72#if defined(HAVE_FIPS) && \
     73    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     74
    5875int  wc_InitRsaKey(RsaKey* key, void* ptr)
    5976{
     
    6481    return InitRsaKey_fips(key, ptr);
    6582}
     83
    6684
    6785int  wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)
     
    7492}
    7593
     94
    7695int  wc_FreeRsaKey(RsaKey* key)
    7796{
     
    8099
    81100
     101#ifndef WOLFSSL_RSA_VERIFY_ONLY
    82102int  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
    83103                                 word32 outLen, RsaKey* key, WC_RNG* rng)
     
    88108    return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);
    89109}
    90 
    91 
     110#endif
     111
     112
     113#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    92114int  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
    93115                                        RsaKey* key)
     
    118140    return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);
    119141}
     142#endif
    120143
    121144
     
    148171
    149172
     173#ifndef WOLFSSL_RSA_VERIFY_ONLY
    150174int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
    151175                           word32* bSz)
     
    155179    return RsaFlattenPublicKey(key, a, aSz, b, bSz);
    156180}
     181#endif
     182
     183
    157184#ifdef WOLFSSL_KEY_GEN
    158185    int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
     
    168195*/
    169196
    170 #else /* else build without fips */
     197#else /* else build without fips, or for new fips */
    171198
    172199#include <wolfssl/wolfcrypt/random.h>
    173200#include <wolfssl/wolfcrypt/logging.h>
     201#ifdef WOLF_CRYPTO_DEV
     202    #include <wolfssl/wolfcrypt/cryptodev.h>
     203#endif
    174204#ifdef NO_INLINE
    175205    #include <wolfssl/wolfcrypt/misc.h>
     
    179209#endif
    180210
    181 #define ERROR_OUT(x) { ret = (x); goto done;}
    182 
    183211
    184212enum {
     
    196224static void wc_RsaCleanup(RsaKey* key)
    197225{
     226#ifndef WOLFSSL_RSA_VERIFY_INLINE
    198227    if (key && key->data) {
    199228        /* make sure any allocated memory is free'd */
    200229        if (key->dataIsAlloc) {
     230        #ifndef WOLFSSL_RSA_PUBLIC_ONLY
    201231            if (key->type == RSA_PRIVATE_DECRYPT ||
    202232                key->type == RSA_PRIVATE_ENCRYPT) {
    203233                ForceZero(key->data, key->dataLen);
    204234            }
     235        #endif
    205236            XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
    206237            key->dataIsAlloc = 0;
     
    209240        key->dataLen = 0;
    210241    }
     242#else
     243    (void)key;
     244#endif
    211245}
    212246
     
    218252        return BAD_FUNC_ARG;
    219253    }
     254
     255    XMEMSET(key, 0, sizeof(RsaKey));
    220256
    221257    key->type = RSA_TYPE_UNKNOWN;
    222258    key->state = RSA_STATE_NONE;
    223259    key->heap = heap;
     260#ifndef WOLFSSL_RSA_VERIFY_INLINE
     261    key->dataIsAlloc = 0;
    224262    key->data = NULL;
     263#endif
    225264    key->dataLen = 0;
    226     key->dataIsAlloc = 0;
    227265#ifdef WC_RSA_BLINDING
    228266    key->rng = NULL;
     267#endif
     268
     269#ifdef WOLF_CRYPTO_DEV
     270    key->devId = devId;
     271#else
     272    (void)devId;
    229273#endif
    230274
     
    241285            return ret;
    242286    #endif /* WC_ASYNC_ENABLE_RSA */
    243 #else
    244     (void)devId;
    245287#endif /* WOLFSSL_ASYNC_CRYPT */
    246288
     289#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    247290    ret = mp_init_multi(&key->n, &key->e, NULL, NULL, NULL, NULL);
    248291    if (ret != MP_OKAY)
    249292        return ret;
    250293
     294#if !defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)
     295    ret = mp_init_multi(&key->d, &key->p, &key->q, NULL, NULL, NULL);
     296#else
    251297    ret = mp_init_multi(&key->d, &key->p, &key->q, &key->dP, &key->dQ, &key->u);
     298#endif
    252299    if (ret != MP_OKAY) {
    253300        mp_clear(&key->n);
     
    255302        return ret;
    256303    }
     304#else
     305    ret = mp_init(&key->n);
     306    if (ret != MP_OKAY)
     307        return ret;
     308    ret = mp_init(&key->e);
     309    if (ret != MP_OKAY) {
     310        mp_clear(&key->n);
     311        return ret;
     312    }
     313#endif
    257314
    258315#ifdef WOLFSSL_XILINX_CRYPT
     
    268325    return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);
    269326}
     327
     328#ifdef HAVE_PKCS11
     329int wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len, void* heap,
     330                     int devId)
     331{
     332    int ret = 0;
     333
     334    if (key == NULL)
     335        ret = BAD_FUNC_ARG;
     336    if (ret == 0 && (len < 0 || len > RSA_MAX_ID_LEN))
     337        ret = BUFFER_E;
     338
     339    if (ret == 0)
     340        ret = wc_InitRsaKey_ex(key, heap, devId);
     341
     342    if (ret == 0 && id != NULL && len != 0) {
     343        XMEMCPY(key->id, id, len);
     344        key->idLen = len;
     345    }
     346
     347    return ret;
     348}
     349#endif
    270350
    271351
     
    359439#endif
    360440
     441#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    361442    if (key->type == RSA_PRIVATE) {
     443#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
    362444        mp_forcezero(&key->u);
    363445        mp_forcezero(&key->dQ);
    364446        mp_forcezero(&key->dP);
     447#endif
    365448        mp_forcezero(&key->q);
    366449        mp_forcezero(&key->p);
     
    368451    }
    369452    /* private part */
     453#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
    370454    mp_clear(&key->u);
    371455    mp_clear(&key->dQ);
    372456    mp_clear(&key->dP);
     457#endif
    373458    mp_clear(&key->q);
    374459    mp_clear(&key->p);
    375460    mp_clear(&key->d);
     461#endif /* WOLFSSL_RSA_PUBLIC_ONLY */
    376462
    377463    /* public part */
     
    386472    return ret;
    387473}
     474
     475#ifndef WOLFSSL_RSA_PUBLIC_ONLY
     476/* Check the pair-wise consistency of the RSA key.
     477 * From NIST SP 800-56B, section 6.4.1.1.
     478 * Verify that k = (k^e)^d, for some k: 1 < k < n-1. */
     479int wc_CheckRsaKey(RsaKey* key)
     480{
     481#ifdef WOLFSSL_SMALL_STACK
     482    mp_int *k = NULL, *tmp = NULL;
     483#else
     484    mp_int k[1], tmp[1];
     485#endif
     486    int ret = 0;
     487
     488#ifdef WOLFSSL_SMALL_STACK
     489    k = (mp_int*)XMALLOC(sizeof(mp_int) * 2, NULL, DYNAMIC_TYPE_RSA);
     490    if (k == NULL)
     491        return MEMORY_E;
     492    tmp = k + 1;
     493#endif
     494
     495    if (mp_init_multi(k, tmp, NULL, NULL, NULL, NULL) != MP_OKAY)
     496        ret = MP_INIT_E;
     497
     498    if (ret == 0) {
     499        if (key == NULL)
     500            ret = BAD_FUNC_ARG;
     501    }
     502
     503    if (ret == 0) {
     504        if (mp_set_int(k, 0x2342) != MP_OKAY)
     505            ret = MP_READ_E;
     506    }
     507
     508#ifdef WOLFSSL_SP_RSA
     509#ifndef WOLFSSL_SP_NO_2048
     510    if (mp_count_bits(&key->n) == 2048) {
     511        ret = sp_ModExp_2048(k, &key->e, &key->n, tmp);
     512        if (ret != 0)
     513            ret = MP_EXPTMOD_E;
     514        ret = sp_ModExp_2048(tmp, &key->d, &key->n, tmp);
     515        if (ret != 0)
     516            ret = MP_EXPTMOD_E;
     517    }
     518    else
     519#endif
     520#ifndef WOLFSSL_SP_NO_3072
     521    if (mp_count_bits(&key->n) == 3072) {
     522        ret = sp_ModExp_3072(k, &key->e, &key->n, tmp);
     523        if (ret != 0)
     524            ret = MP_EXPTMOD_E;
     525        ret = sp_ModExp_3072(tmp, &key->d, &key->n, tmp);
     526        if (ret != 0)
     527            ret = MP_EXPTMOD_E;
     528    }
     529    else
     530#endif
     531#endif
     532#ifdef WOLFSSL_SP_MATH
     533    {
     534        ret = WC_KEY_SIZE_E;
     535    }
     536#else
     537    {
     538        if (ret == 0) {
     539            if (mp_exptmod(k, &key->e, &key->n, tmp) != MP_OKAY)
     540                ret = MP_EXPTMOD_E;
     541        }
     542
     543        if (ret == 0) {
     544            if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)
     545                ret = MP_EXPTMOD_E;
     546        }
     547    }
     548#endif
     549
     550    if (ret == 0) {
     551        if (mp_cmp(k, tmp) != MP_EQ)
     552            ret = RSA_KEY_PAIR_E;
     553    }
     554
     555    mp_forcezero(tmp);
     556    mp_clear(tmp);
     557    mp_clear(k);
     558#ifdef WOLFSSL_SMALL_STACK
     559    XFREE(k, NULL, DYNAMIC_TYPE_RSA);
     560#endif
     561
     562    return ret;
     563}
     564#endif
    388565
    389566
     
    494671            break;
    495672    #endif
    496     #ifdef WOLFSSL_SHA512
    497673    #ifdef WOLFSSL_SHA384
    498674        case WC_MGF1SHA384:
     
    500676            break;
    501677    #endif
     678    #ifdef WOLFSSL_SHA512
    502679        case WC_MGF1SHA512:
    503680            ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap);
     
    522699
    523700/* Padding */
     701#ifndef WOLFSSL_RSA_VERIFY_ONLY
     702#ifndef WC_NO_RNG
    524703#ifndef WC_NO_RSA_OAEP
    525704static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
     
    700879
    701880#ifdef WC_RSA_PSS
     881
    702882/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc
    703883 * XOR MGF over all bytes down to end of Salt
    704884 * Gen Hash = HASH(8 * 0x00 | Message Hash | Salt)
     885 *
     886 * input         Digest of the message.
     887 * inputLen      Length of digest.
     888 * pkcsBlock     Buffer to write to.
     889 * pkcsBlockLen  Length of buffer to write to.
     890 * rng           Random number generator (for salt).
     891 * htype         Hash function to use.
     892 * mgf           Mask generation function.
     893 * saltLen       Length of salt to put in padding.
     894 * bits          Length of key in bits.
     895 * heap          Used for dynamic memory allocation.
     896 * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid
     897 * and other negative values on error.
    705898 */
    706899static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,
    707900        word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf,
    708         int bits, void* heap)
     901        int saltLen, int bits, void* heap)
    709902{
    710903    int   ret;
     
    719912        return hLen;
    720913
     914    if (saltLen == -1) {
     915        saltLen = hLen;
     916        #ifdef WOLFSSL_SHA512
     917            /* See FIPS 186-4 section 5.5 item (e). */
     918            if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)
     919                saltLen = RSA_PSS_SALT_MAX_SZ;
     920        #endif
     921    }
     922    else if (saltLen > hLen || saltLen < -1)
     923        return PSS_SALTLEN_E;
     924    if ((int)pkcsBlockLen - hLen < saltLen + 2)
     925        return PSS_SALTLEN_E;
     926
    721927    s = m = pkcsBlock;
    722     XMEMSET(m, 0, 8);
    723     m += 8;
     928    XMEMSET(m, 0, RSA_PSS_PAD_SZ);
     929    m += RSA_PSS_PAD_SZ;
    724930    XMEMCPY(m, input, inputLen);
    725931    m += inputLen;
    726     if ((ret = wc_RNG_GenerateBlock(rng, salt, hLen)) != 0)
     932    if ((ret = wc_RNG_GenerateBlock(rng, salt, saltLen)) != 0)
    727933        return ret;
    728     XMEMCPY(m, salt, hLen);
    729     m += hLen;
     934    XMEMCPY(m, salt, saltLen);
     935    m += saltLen;
    730936
    731937    h = pkcsBlock + pkcsBlockLen - 1 - hLen;
    732938    if ((ret = wc_Hash(hType, s, (word32)(m - s), h, hLen)) != 0)
    733939        return ret;
    734     pkcsBlock[pkcsBlockLen - 1] = 0xbc;
     940    pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM;
    735941
    736942    ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap);
     
    739945    pkcsBlock[0] &= (1 << ((bits - 1) & 0x7)) - 1;
    740946
    741     m = pkcsBlock + pkcsBlockLen - 1 - hLen - hLen - 1;
     947    m = pkcsBlock + pkcsBlockLen - 1 - saltLen - hLen - 1;
    742948    *(m++) ^= 0x01;
    743     for (i = 0; i < hLen; i++)
     949    for (i = 0; i < saltLen; i++)
    744950        m[i] ^= salt[i];
    745951
    746952    return 0;
    747953}
    748 #endif
     954#endif /* WC_RSA_PSS */
    749955
    750956static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
     
    770976    }
    771977    else {
     978#ifndef WOLFSSL_RSA_VERIFY_ONLY
    772979        /* pad with non-zero random bytes */
    773980        word32 padLen, i;
     
    789996            if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
    790997        }
     998#else
     999        (void)rng;
     1000        return RSA_WRONG_TYPE_E;
     1001#endif
    7911002    }
    7921003
     
    7961007    return 0;
    7971008}
     1009#endif /* !WC_NO_RNG */
    7981010
    7991011/* helper function to direct which padding is used */
    8001012static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
    8011013    word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,
    802     enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, int bits,
    803     void* heap)
     1014    enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
     1015    int saltLen, int bits, void* heap)
    8041016{
    8051017    int ret;
     
    8071019    switch (padType)
    8081020    {
     1021#ifndef WC_NO_RNG
    8091022        case WC_RSA_PKCSV15_PAD:
    8101023            /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");*/
     
    8251038            WOLFSSL_MSG("wolfSSL Using RSA PSS padding");
    8261039            ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen, rng,
    827                                                         hType, mgf, bits, heap);
     1040                                               hType, mgf, saltLen, bits, heap);
     1041            break;
     1042    #endif
     1043#endif /* !WC_NO_RNG */
     1044
     1045    #ifdef WC_RSA_NO_PADDING
     1046        case WC_RSA_NO_PAD:
     1047            WOLFSSL_MSG("wolfSSL Using NO padding");
     1048
     1049            /* In the case of no padding being used check that input is exactly
     1050             * the RSA key length */
     1051            if (bits <= 0 || inputLen != ((word32)bits/WOLFSSL_BIT_SIZE)) {
     1052                WOLFSSL_MSG("Bad input size");
     1053                ret = RSA_PAD_E;
     1054            }
     1055            else {
     1056                XMEMCPY(pkcsBlock, input, inputLen);
     1057                ret = 0;
     1058            }
    8281059            break;
    8291060    #endif
     
    8351066
    8361067    /* silence warning if not used with padding scheme */
     1068    (void)input;
     1069    (void)inputLen;
     1070    (void)pkcsBlock;
     1071    (void)pkcsBlockLen;
     1072    (void)padValue;
     1073    (void)rng;
     1074    (void)padType;
    8371075    (void)hType;
    8381076    (void)mgf;
    8391077    (void)optLabel;
    8401078    (void)labelLen;
     1079    (void)saltLen;
    8411080    (void)bits;
    8421081    (void)heap;
     
    8441083    return ret;
    8451084}
     1085#endif /* WOLFSSL_RSA_VERIFY_ONLY */
    8461086
    8471087
     
    9231163    ret += pkcsBlock[0]     ^ 0x00; /* Y, the first value, should be 0 */
    9241164
    925     if (ret != 0) {
    926         WOLFSSL_MSG("RsaUnPad_OAEP: Padding Error");
    927         return BAD_PADDING_E;
    928     }
     1165    /* Return 0 data length on error. */
     1166    idx = ctMaskSelInt(ctMaskEq(ret, 0), idx, pkcsBlockLen);
    9291167
    9301168    /* adjust pointer to correct location in array and return size of M */
     
    9351173
    9361174#ifdef WC_RSA_PSS
     1175/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc
     1176 * MGF over all bytes down to end of Salt
     1177 *
     1178 * pkcsBlock     Buffer holding decrypted data.
     1179 * pkcsBlockLen  Length of buffer.
     1180 * htype         Hash function to use.
     1181 * mgf           Mask generation function.
     1182 * saltLen       Length of salt to put in padding.
     1183 * bits          Length of key in bits.
     1184 * heap          Used for dynamic memory allocation.
     1185 * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid,
     1186 * BAD_PADDING_E when the padding is not valid, MEMORY_E when allocation fails
     1187 * and other negative values on error.
     1188 */
    9371189static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
    9381190                        byte **output, enum wc_HashType hType, int mgf,
    939                         int bits, void* heap)
     1191                        int saltLen, int bits, void* heap)
    9401192{
    9411193    int   ret;
     
    9471199        return hLen;
    9481200
    949     if (pkcsBlock[pkcsBlockLen - 1] != 0xbc) {
    950         WOLFSSL_MSG("RsaUnPad_PSS: Padding Error 0xBC");
     1201    if (saltLen == -1) {
     1202        saltLen = hLen;
     1203        #ifdef WOLFSSL_SHA512
     1204            /* See FIPS 186-4 section 5.5 item (e). */
     1205            if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)
     1206                saltLen = RSA_PSS_SALT_MAX_SZ;
     1207        #endif
     1208    }
     1209    else if (saltLen > hLen || saltLen < -1)
     1210        return PSS_SALTLEN_E;
     1211    if ((int)pkcsBlockLen - hLen < saltLen + 2)
     1212        return PSS_SALTLEN_E;
     1213
     1214    if (pkcsBlock[pkcsBlockLen - 1] != RSA_PSS_PAD_TERM) {
     1215        WOLFSSL_MSG("RsaUnPad_PSS: Padding Term Error");
    9511216        return BAD_PADDING_E;
    9521217    }
    9531218
    9541219    tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER);
    955     if (tmp == NULL) {
     1220    if (tmp == NULL)
    9561221        return MEMORY_E;
    957     }
    9581222
    9591223    if ((ret = RsaMGF(mgf, pkcsBlock + pkcsBlockLen - 1 - hLen, hLen,
     
    9641228
    9651229    tmp[0] &= (1 << ((bits - 1) & 0x7)) - 1;
    966     for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) {
     1230    for (i = 0; i < (int)(pkcsBlockLen - 1 - saltLen - hLen - 1); i++) {
    9671231        if (tmp[i] != pkcsBlock[i]) {
    9681232            XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
     
    9811245    XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
    9821246
    983     i = pkcsBlockLen - (RSA_PSS_PAD_SZ + 3 * hLen + 1);
    984     XMEMSET(pkcsBlock + i, 0, RSA_PSS_PAD_SZ);
    985 
    986     *output = pkcsBlock + i;
    987     return RSA_PSS_PAD_SZ + 3 * hLen;
     1247    *output = pkcsBlock + pkcsBlockLen - (hLen + saltLen + 1);
     1248    return saltLen + hLen;
    9881249}
    9891250#endif
     
    9941255                                               byte **output, byte padValue)
    9951256{
    996     word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0;
    997     word32 invalid = 0;
    998     word32 i = 1;
    999     word32 outputLen;
     1257    int    ret = BAD_FUNC_ARG;
     1258    word32 i;
     1259#ifndef WOLFSSL_RSA_VERIFY_ONLY
     1260    byte   invalid = 0;
     1261#endif
    10001262
    10011263    if (output == NULL || pkcsBlockLen == 0) {
     
    10031265    }
    10041266
    1005     if (pkcsBlock[0] != 0x0) { /* skip past zero */
    1006         invalid = 1;
    1007     }
    1008     pkcsBlock++; pkcsBlockLen--;
    1009 
    1010     /* Require block type padValue */
    1011     invalid = (pkcsBlock[0] != padValue) || invalid;
    1012 
    1013     /* verify the padding until we find the separator */
    10141267    if (padValue == RSA_BLOCK_TYPE_1) {
    1015         while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
    1016     }
    1017     else {
    1018         while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
    1019     }
    1020 
    1021     if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
     1268        /* First byte must be 0x00 and Second byte, block type, 0x01 */
     1269        if (pkcsBlock[0] != 0 || pkcsBlock[1] != RSA_BLOCK_TYPE_1) {
     1270            WOLFSSL_MSG("RsaUnPad error, invalid formatting");
     1271            return RSA_PAD_E;
     1272    }
     1273
     1274        /* check the padding until we find the separator */
     1275        for (i = 2; i < pkcsBlockLen && pkcsBlock[i++] == 0xFF; ) { }
     1276
     1277        /* Minimum of 11 bytes of pre-message data and must have separator. */
     1278        if (i < RSA_MIN_PAD_SZ || pkcsBlock[i-1] != 0) {
    10221279        WOLFSSL_MSG("RsaUnPad error, bad formatting");
    10231280        return RSA_PAD_E;
    10241281    }
    10251282
    1026     outputLen = pkcsBlockLen - i;
    1027     invalid = (outputLen > maxOutputLen) || invalid;
    1028 
    1029     if (invalid) {
    1030         WOLFSSL_MSG("RsaUnPad error, invalid formatting");
    1031         return RSA_PAD_E;
    1032     }
     1283        *output = (byte *)(pkcsBlock + i);
     1284        ret = pkcsBlockLen - i;
     1285    }
     1286#ifndef WOLFSSL_RSA_VERIFY_ONLY
     1287    else {
     1288        word32 j;
     1289        byte   pastSep = 0;
     1290
     1291        /* Decrypted with private key - unpad must be constant time. */
     1292        for (i = 0, j = 2; j < pkcsBlockLen; j++) {
     1293           /* Update i if not passed the separator and at separator. */
     1294           i |= (~pastSep) & ctMaskEq(pkcsBlock[j], 0x00) & (j + 1);
     1295           pastSep |= ctMaskEq(pkcsBlock[j], 0x00);
     1296        }
     1297
     1298        /* Minimum of 11 bytes of pre-message data - including leading 0x00. */
     1299        invalid |= ctMaskLT(i, RSA_MIN_PAD_SZ);
     1300        /* Must have seen separator. */
     1301        invalid |= ~pastSep;
     1302        /* First byte must be 0x00. */
     1303        invalid |= ctMaskNotEq(pkcsBlock[0], 0x00);
     1304        /* Check against expected block type: padValue */
     1305        invalid |= ctMaskNotEq(pkcsBlock[1], padValue);
    10331306
    10341307    *output = (byte *)(pkcsBlock + i);
    1035     return outputLen;
    1036 }
    1037 
    1038 /* helper function to direct unpadding */
     1308        ret = ((int)~invalid) & (pkcsBlockLen - i);
     1309    }
     1310#endif
     1311
     1312    return ret;
     1313}
     1314
     1315/* helper function to direct unpadding
     1316 *
     1317 * bits is the key modulus size in bits
     1318 */
    10391319static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
    10401320                          byte padValue, int padType, enum wc_HashType hType,
    1041                           int mgf, byte* optLabel, word32 labelLen, int bits,
    1042                           void* heap)
     1321                          int mgf, byte* optLabel, word32 labelLen, int saltLen,
     1322                          int bits, void* heap)
    10431323{
    10441324    int ret;
     
    10621342            WOLFSSL_MSG("wolfSSL Using RSA PSS un-padding");
    10631343            ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf,
    1064                                                                    bits, heap);
     1344                                                           saltLen, bits, heap);
    10651345            break;
    10661346    #endif
     1347
     1348    #ifdef WC_RSA_NO_PADDING
     1349        case WC_RSA_NO_PAD:
     1350            WOLFSSL_MSG("wolfSSL Using NO un-padding");
     1351
     1352            /* In the case of no padding being used check that input is exactly
     1353             * the RSA key length */
     1354            if (bits <= 0 || pkcsBlockLen != ((word32)bits/WOLFSSL_BIT_SIZE)) {
     1355                WOLFSSL_MSG("Bad input size");
     1356                ret = RSA_PAD_E;
     1357            }
     1358            else {
     1359                if (out != NULL) {
     1360                    *out = pkcsBlock;
     1361                }
     1362                ret = pkcsBlockLen;
     1363            }
     1364            break;
     1365    #endif /* WC_RSA_NO_PADDING */
    10671366
    10681367        default:
     
    10761375    (void)optLabel;
    10771376    (void)labelLen;
     1377    (void)saltLen;
    10781378    (void)bits;
    10791379    (void)heap;
     
    11311431#endif /* WOLFSSL_XILINX_CRYPT */
    11321432
     1433#ifdef WC_RSA_NONBLOCK
     1434static int wc_RsaFunctionNonBlock(const byte* in, word32 inLen, byte* out,
     1435                          word32* outLen, int type, RsaKey* key)
     1436{
     1437    int    ret = 0;
     1438    word32 keyLen, len;
     1439
     1440    if (key == NULL || key->nb == NULL) {
     1441        return BAD_FUNC_ARG;
     1442    }
     1443
     1444    if (key->nb->exptmod.state == TFM_EXPTMOD_NB_INIT) {
     1445        if (mp_init(&key->nb->tmp) != MP_OKAY) {
     1446            ret = MP_INIT_E;
     1447        }
     1448
     1449        if (ret == 0) {
     1450            if (mp_read_unsigned_bin(&key->nb->tmp, (byte*)in, inLen) != MP_OKAY) {
     1451                ret = MP_READ_E;
     1452            }
     1453        }
     1454    }
     1455
     1456    if (ret == 0) {
     1457        switch(type) {
     1458        case RSA_PRIVATE_DECRYPT:
     1459        case RSA_PRIVATE_ENCRYPT:
     1460            ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->d,
     1461                &key->n, &key->nb->tmp);
     1462            if (ret == FP_WOULDBLOCK)
     1463                return ret;
     1464            if (ret != MP_OKAY)
     1465                ret = MP_EXPTMOD_E;
     1466            break;
     1467
     1468        case RSA_PUBLIC_ENCRYPT:
     1469        case RSA_PUBLIC_DECRYPT:
     1470            ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->e,
     1471                &key->n, &key->nb->tmp);
     1472            if (ret == FP_WOULDBLOCK)
     1473                return ret;
     1474            if (ret != MP_OKAY)
     1475                ret = MP_EXPTMOD_E;
     1476            break;
     1477        default:
     1478            ret = RSA_WRONG_TYPE_E;
     1479            break;
     1480        }
     1481    }
     1482
     1483    if (ret == 0) {
     1484        keyLen = wc_RsaEncryptSize(key);
     1485        if (keyLen > *outLen)
     1486            ret = RSA_BUFFER_E;
     1487    }
     1488    if (ret == 0) {
     1489        len = mp_unsigned_bin_size(&key->nb->tmp);
     1490
     1491        /* pad front w/ zeros to match key length */
     1492        while (len < keyLen) {
     1493            *out++ = 0x00;
     1494            len++;
     1495        }
     1496
     1497        *outLen = keyLen;
     1498
     1499        /* convert */
     1500        if (mp_to_unsigned_bin(&key->nb->tmp, out) != MP_OKAY) {
     1501             ret = MP_TO_E;
     1502        }
     1503    }
     1504
     1505    mp_clear(&key->nb->tmp);
     1506
     1507    return ret;
     1508}
     1509#endif /* WC_RSA_NONBLOCK */
     1510
    11331511static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
    11341512                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)
    11351513{
    1136     mp_int tmp;
     1514#ifndef WOLFSSL_SP_MATH
     1515#ifdef WOLFSSL_SMALL_STACK
     1516    mp_int* tmp = NULL;
    11371517#ifdef WC_RSA_BLINDING
    1138     mp_int rnd, rndi;
     1518    mp_int* rnd = NULL;
     1519    mp_int* rndi = NULL;
     1520#endif
     1521#else
     1522    mp_int tmp[1];
     1523#ifdef WC_RSA_BLINDING
     1524    mp_int rnd[1], rndi[1];
     1525#endif
    11391526#endif
    11401527    int    ret = 0;
    1141     word32 keyLen, len;
     1528    word32 keyLen = 0;
     1529#endif
    11421530
    11431531#ifdef WOLFSSL_HAVE_SP_RSA
     
    11451533    if (mp_count_bits(&key->n) == 2048) {
    11461534        switch(type) {
     1535#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    11471536        case RSA_PRIVATE_DECRYPT:
    11481537        case RSA_PRIVATE_ENCRYPT:
     
    11511540                return MISSING_RNG_E;
    11521541    #endif
     1542    #ifndef RSA_LOW_MEM
    11531543            return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q,
    11541544                                      &key->dP, &key->dQ, &key->u, &key->n,
    11551545                                      out, outLen);
     1546    #else
     1547            return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q,
     1548                                      NULL, NULL, NULL, &key->n, out, outLen);
     1549    #endif
     1550#endif
    11561551        case RSA_PUBLIC_ENCRYPT:
    11571552        case RSA_PUBLIC_DECRYPT:
     
    11631558    if (mp_count_bits(&key->n) == 3072) {
    11641559        switch(type) {
     1560#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    11651561        case RSA_PRIVATE_DECRYPT:
    11661562        case RSA_PRIVATE_ENCRYPT:
     
    11691565                return MISSING_RNG_E;
    11701566    #endif
     1567    #ifndef RSA_LOW_MEM
    11711568            return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q,
    11721569                                      &key->dP, &key->dQ, &key->u, &key->n,
    11731570                                      out, outLen);
     1571    #else
     1572            return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q,
     1573                                      NULL, NULL, NULL, &key->n, out, outLen);
     1574    #endif
     1575#endif
    11741576        case RSA_PUBLIC_ENCRYPT:
    11751577        case RSA_PUBLIC_DECRYPT:
     
    11801582#endif /* WOLFSSL_HAVE_SP_RSA */
    11811583
     1584#ifdef WOLFSSL_SP_MATH
    11821585    (void)rng;
    1183 
    1184     if (mp_init(&tmp) != MP_OKAY)
    1185         return MP_INIT_E;
    1186 
     1586    return WC_KEY_SIZE_E;
     1587#else
     1588    (void)rng;
     1589
     1590#ifdef WOLFSSL_SMALL_STACK
     1591    tmp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);
     1592    if (tmp == NULL)
     1593        return MEMORY_E;
    11871594#ifdef WC_RSA_BLINDING
     1595    rnd = (mp_int*)XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA);
     1596    if (rnd == NULL) {
     1597        XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
     1598        return MEMORY_E;
     1599    }
     1600    rndi = rnd + 1;
     1601#endif /* WC_RSA_BLINDING */
     1602#endif /* WOLFSSL_SMALL_STACK */
     1603
     1604    if (mp_init(tmp) != MP_OKAY)
     1605        ret = MP_INIT_E;
     1606
     1607#ifdef WC_RSA_BLINDING
     1608    if (ret == 0) {
    11881609    if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
    1189         if (mp_init_multi(&rnd, &rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
    1190             mp_clear(&tmp);
    1191             return MP_INIT_E;
    1192         }
    1193     }
    1194 #endif
    1195 
    1196     if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
    1197         ERROR_OUT(MP_READ_E);
    1198 
     1610            if (mp_init_multi(rnd, rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
     1611                mp_clear(tmp);
     1612                ret = MP_INIT_E;
     1613            }
     1614        }
     1615    }
     1616#endif
     1617
     1618#ifndef TEST_UNPAD_CONSTANT_TIME
     1619    if (ret == 0 && mp_read_unsigned_bin(tmp, (byte*)in, inLen) != MP_OKAY)
     1620        ret = MP_READ_E;
     1621
     1622    if (ret == 0) {
    11991623    switch(type) {
     1624    #ifndef WOLFSSL_RSA_PUBLIC_ONLY
    12001625    case RSA_PRIVATE_DECRYPT:
    12011626    case RSA_PRIVATE_ENCRYPT:
    12021627    {
    1203     #ifdef WC_RSA_BLINDING
     1628        #if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
    12041629        /* blind */
    1205         ret = mp_rand(&rnd, get_digit_count(&key->n), rng);
    1206         if (ret != MP_OKAY)
    1207             goto done;
     1630            ret = mp_rand(rnd, get_digit_count(&key->n), rng);
    12081631
    12091632        /* rndi = 1/rnd mod n */
    1210         if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY)
    1211             ERROR_OUT(MP_INVMOD_E);
     1633            if (ret == 0 && mp_invmod(rnd, &key->n, rndi) != MP_OKAY)
     1634                ret = MP_INVMOD_E;
    12121635
    12131636        /* rnd = rnd^e */
    1214         if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY)
    1215             ERROR_OUT(MP_EXPTMOD_E);
     1637            if (ret == 0 && mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY)
     1638                ret = MP_EXPTMOD_E;
    12161639
    12171640        /* tmp = tmp*rnd mod n */
    1218         if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY)
    1219             ERROR_OUT(MP_MULMOD_E);
    1220     #endif /* WC_RSA_BLINGING */
     1641            if (ret == 0 && mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY)
     1642                ret = MP_MULMOD_E;
     1643        #endif /* WC_RSA_BLINDING && !WC_NO_RNG */
    12211644
    12221645    #ifdef RSA_LOW_MEM      /* half as much memory but twice as slow */
    1223         if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
    1224             ERROR_OUT(MP_EXPTMOD_E);
     1646            if (ret == 0 && mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)
     1647                ret = MP_EXPTMOD_E;
    12251648    #else
    1226         /* Return 0 when cond is false and n when cond is true. */
    1227         #define COND_N(cond, n)    ((0 - (cond)) & (n))
    1228         /* If ret has an error value return it otherwise if r is OK then return
    1229          * 0 otherwise return e.
    1230          */
    1231         #define RET_ERR(ret, r, e) \
    1232             ((ret) | (COND_N((ret) == 0, COND_N((r) != MP_OKAY, (e)))))
    1233 
    1234         { /* tmpa/b scope */
    1235         mp_int tmpa, tmpb;
    1236         int r;
    1237 
    1238         if (mp_init(&tmpa) != MP_OKAY)
    1239             ERROR_OUT(MP_INIT_E);
    1240 
    1241         if (mp_init(&tmpb) != MP_OKAY) {
    1242             mp_clear(&tmpa);
    1243             ERROR_OUT(MP_INIT_E);
     1649            if (ret == 0) {
     1650            #ifdef WOLFSSL_SMALL_STACK
     1651                mp_int* tmpa = NULL;
     1652                mp_int* tmpb = NULL;
     1653            #else
     1654                mp_int tmpa[1], tmpb[1];
     1655            #endif
     1656                int cleara = 0, clearb = 0;
     1657
     1658            #ifdef WOLFSSL_SMALL_STACK
     1659                tmpa = XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA);
     1660                if (tmpa != NULL)
     1661                    tmpb = tmpa + 1;
     1662                else
     1663                    ret = MEMORY_E;
     1664            #endif
     1665
     1666                if (ret == 0) {
     1667                    if (mp_init(tmpa) != MP_OKAY)
     1668                        ret = MP_INIT_E;
     1669                    else
     1670                        cleara = 1;
     1671                }
     1672
     1673                if (ret == 0) {
     1674                    if (mp_init(tmpb) != MP_OKAY)
     1675                        ret = MP_INIT_E;
     1676                    else
     1677                        clearb = 1;
    12441678        }
    12451679
    12461680        /* tmpa = tmp^dP mod p */
    1247         r = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa);
    1248         ret = RET_ERR(ret, r, MP_EXPTMOD_E);
     1681                if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p,
     1682                                                               tmpa) != MP_OKAY)
     1683                    ret = MP_EXPTMOD_E;
    12491684
    12501685        /* tmpb = tmp^dQ mod q */
    1251         r = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb);
    1252         ret = RET_ERR(ret, r, MP_EXPTMOD_E);
     1686                if (ret == 0 && mp_exptmod(tmp, &key->dQ, &key->q,
     1687                                                               tmpb) != MP_OKAY)
     1688                    ret = MP_EXPTMOD_E;
    12531689
    12541690        /* tmp = (tmpa - tmpb) * qInv (mod p) */
    1255         r = mp_sub(&tmpa, &tmpb, &tmp);
    1256         ret = RET_ERR(ret, r, MP_SUB_E);
    1257 
    1258         r = mp_mulmod(&tmp, &key->u, &key->p, &tmp);
    1259         ret = RET_ERR(ret, r, MP_MULMOD_E);
     1691                if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY)
     1692                    ret = MP_SUB_E;
     1693
     1694                if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p,
     1695                                                                tmp) != MP_OKAY)
     1696                    ret = MP_MULMOD_E;
    12601697
    12611698        /* tmp = tmpb + q * tmp */
    1262         r = mp_mul(&tmp, &key->q, &tmp);
    1263         ret = RET_ERR(ret, r, MP_MUL_E);
    1264 
    1265         r = mp_add(&tmp, &tmpb, &tmp);
    1266         ret = RET_ERR(ret, r, MP_ADD_E);
    1267 
    1268         mp_clear(&tmpa);
    1269         mp_clear(&tmpb);
    1270 
    1271         if (ret != 0) {
    1272             goto done;
    1273         }
    1274         #undef RET_ERR
    1275         #undef COND_N
     1699                if (ret == 0 && mp_mul(tmp, &key->q, tmp) != MP_OKAY)
     1700                    ret = MP_MUL_E;
     1701
     1702                if (ret == 0 && mp_add(tmp, tmpb, tmp) != MP_OKAY)
     1703                    ret = MP_ADD_E;
     1704
     1705            #ifdef WOLFSSL_SMALL_STACK
     1706                if (tmpa != NULL)
     1707            #endif
     1708                {
     1709                    if (cleara)
     1710                        mp_clear(tmpa);
     1711                    if (clearb)
     1712                        mp_clear(tmpb);
     1713            #ifdef WOLFSSL_SMALL_STACK
     1714                    XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA);
     1715            #endif
     1716        }
    12761717        } /* tmpa/b scope */
    12771718    #endif   /* RSA_LOW_MEM */
     
    12791720    #ifdef WC_RSA_BLINDING
    12801721        /* unblind */
    1281         if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY)
    1282             ERROR_OUT(MP_MULMOD_E);
     1722            if (ret == 0 && mp_mulmod(tmp, rndi, &key->n, tmp) != MP_OKAY)
     1723                ret = MP_MULMOD_E;
    12831724    #endif   /* WC_RSA_BLINDING */
    12841725
    12851726        break;
    12861727    }
     1728    #endif
    12871729    case RSA_PUBLIC_ENCRYPT:
    12881730    case RSA_PUBLIC_DECRYPT:
    12891731    #ifdef WOLFSSL_XILINX_CRYPT
    12901732        ret = wc_RsaFunctionXil(in, inLen, out, outLen, type, key, rng);
    1291         goto done;
    12921733    #else
    1293         if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
    1294             ERROR_OUT(MP_EXPTMOD_E);
     1734            if (mp_exptmod(tmp, &key->e, &key->n, tmp) != MP_OKAY)
     1735                ret = MP_EXPTMOD_E;
    12951736        break;
    12961737    #endif
    12971738    default:
    1298         ERROR_OUT(RSA_WRONG_TYPE_E);
    1299     }
    1300 
    1301     keyLen = wc_RsaEncryptSize(key);
    1302     if (keyLen > *outLen) {
    1303         ERROR_OUT(RSA_BUFFER_E);
    1304     }
    1305 
    1306     len = mp_unsigned_bin_size(&tmp);
    1307 
    1308     /* pad front w/ zeros to match key length */
    1309     while (len < keyLen) {
    1310         *out++ = 0x00;
    1311         len++;
    1312     }
    1313 
     1739            ret = RSA_WRONG_TYPE_E;
     1740            break;
     1741    }
     1742    }
     1743
     1744    if (ret == 0) {
     1745        keyLen = wc_RsaEncryptSize(key);
     1746        if (keyLen > *outLen)
     1747            ret = RSA_BUFFER_E;
     1748    }
     1749    if (ret == 0) {
    13141750    *outLen = keyLen;
    1315 
    1316     /* convert */
    1317     if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
    1318         ERROR_OUT(MP_TO_E);
    1319 
    1320 done:
    1321     mp_clear(&tmp);
     1751        if (mp_to_unsigned_bin_len(tmp, out, keyLen) != MP_OKAY)
     1752             ret = MP_TO_E;
     1753    }
     1754#else
     1755    (void)type;
     1756    (void)key;
     1757    (void)keyLen;
     1758    XMEMCPY(out, in, inLen);
     1759    *outLen = inLen;
     1760#endif
     1761
     1762    mp_clear(tmp);
     1763#ifdef WOLFSSL_SMALL_STACK
     1764    XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
     1765#endif
    13221766#ifdef WC_RSA_BLINDING
    13231767    if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
    1324         mp_clear(&rndi);
    1325         mp_clear(&rnd);
    1326     }
    1327 #endif
     1768        mp_clear(rndi);
     1769        mp_clear(rnd);
     1770    }
     1771#ifdef WOLFSSL_SMALL_STACK
     1772    XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA);
     1773#endif
     1774#endif /* WC_RSA_BLINDING */
    13281775    return ret;
     1776#endif /* WOLFSSL_SP_MATH */
    13291777}
    13301778
     
    13521800
    13531801    switch(type) {
     1802#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    13541803    case RSA_PRIVATE_DECRYPT:
    13551804    case RSA_PRIVATE_ENCRYPT:
    13561805    #ifdef HAVE_CAVIUM
     1806        key->dataLen = key->n.raw.len;
    13571807        ret = NitroxRsaExptMod(in, inLen,
    13581808                               key->d.raw.buf, key->d.raw.len,
     
    13751825    #endif
    13761826        break;
     1827#endif
    13771828
    13781829    case RSA_PUBLIC_ENCRYPT:
    13791830    case RSA_PUBLIC_DECRYPT:
    13801831    #ifdef HAVE_CAVIUM
     1832        key->dataLen = key->n.raw.len;
    13811833        ret = NitroxRsaExptMod(in, inLen,
    13821834                               key->e.raw.buf, key->e.raw.len,
     
    14001852#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_RSA */
    14011853
     1854#if defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING)
     1855/* Function that does the RSA operation directly with no padding.
     1856 *
     1857 * in       buffer to do operation on
     1858 * inLen    length of input buffer
     1859 * out      buffer to hold results
     1860 * outSz    gets set to size of result buffer. Should be passed in as length
     1861 *          of out buffer. If the pointer "out" is null then outSz gets set to
     1862 *          the expected buffer size needed and LENGTH_ONLY_E gets returned.
     1863 * key      RSA key to use for encrypt/decrypt
     1864 * type     if using private or public key {RSA_PUBLIC_ENCRYPT,
     1865 *          RSA_PUBLIC_DECRYPT, RSA_PRIVATE_ENCRYPT, RSA_PRIVATE_DECRYPT}
     1866 * rng      wolfSSL RNG to use if needed
     1867 *
     1868 * returns size of result on success
     1869 */
     1870int wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz,
     1871        RsaKey* key, int type, WC_RNG* rng)
     1872{
     1873    int ret;
     1874
     1875    if (in == NULL || outSz == NULL || key == NULL) {
     1876        return BAD_FUNC_ARG;
     1877    }
     1878
     1879    /* sanity check on type of RSA operation */
     1880    switch (type) {
     1881        case RSA_PUBLIC_ENCRYPT:
     1882        case RSA_PUBLIC_DECRYPT:
     1883        case RSA_PRIVATE_ENCRYPT:
     1884        case RSA_PRIVATE_DECRYPT:
     1885            break;
     1886        default:
     1887            WOLFSSL_MSG("Bad RSA type");
     1888            return BAD_FUNC_ARG;
     1889    }
     1890
     1891    if ((ret = wc_RsaEncryptSize(key)) < 0) {
     1892        return BAD_FUNC_ARG;
     1893    }
     1894
     1895    if (inLen != (word32)ret) {
     1896        WOLFSSL_MSG("Bad input length. Should be RSA key size");
     1897        return BAD_FUNC_ARG;
     1898    }
     1899
     1900    if (out == NULL) {
     1901        *outSz = inLen;
     1902        return LENGTH_ONLY_E;
     1903    }
     1904
     1905    switch (key->state) {
     1906        case RSA_STATE_NONE:
     1907        case RSA_STATE_ENCRYPT_PAD:
     1908        case RSA_STATE_ENCRYPT_EXPTMOD:
     1909        case RSA_STATE_DECRYPT_EXPTMOD:
     1910        case RSA_STATE_DECRYPT_UNPAD:
     1911            key->state = (type == RSA_PRIVATE_ENCRYPT ||
     1912                    type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_EXPTMOD:
     1913                                                  RSA_STATE_DECRYPT_EXPTMOD;
     1914
     1915            key->dataLen = *outSz;
     1916
     1917            ret = wc_RsaFunction(in, inLen, out, &key->dataLen, type, key, rng);
     1918            if (ret >= 0 || ret == WC_PENDING_E) {
     1919                key->state = (type == RSA_PRIVATE_ENCRYPT ||
     1920                    type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_RES:
     1921                                                  RSA_STATE_DECRYPT_RES;
     1922            }
     1923            if (ret < 0) {
     1924                break;
     1925            }
     1926
     1927            FALL_THROUGH;
     1928
     1929        case RSA_STATE_ENCRYPT_RES:
     1930        case RSA_STATE_DECRYPT_RES:
     1931            ret = key->dataLen;
     1932            break;
     1933
     1934        default:
     1935            ret = BAD_STATE_E;
     1936    }
     1937
     1938    /* if async pending then skip cleanup*/
     1939    if (ret == WC_PENDING_E
     1940    #ifdef WC_RSA_NONBLOCK
     1941        || ret == FP_WOULDBLOCK
     1942    #endif
     1943    ) {
     1944        return ret;
     1945    }
     1946
     1947    key->state = RSA_STATE_NONE;
     1948    wc_RsaCleanup(key);
     1949
     1950    return ret;
     1951}
     1952#endif /* WC_RSA_DIRECT || WC_RSA_NO_PADDING */
     1953
     1954
    14021955int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
    14031956                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)
    14041957{
    1405     int ret;
     1958    int ret = 0;
    14061959
    14071960    if (key == NULL || in == NULL || inLen == 0 || out == NULL ||
     
    14091962        return BAD_FUNC_ARG;
    14101963    }
     1964
     1965#ifdef WOLF_CRYPTO_DEV
     1966    if (key->devId != INVALID_DEVID) {
     1967        ret = wc_CryptoDev_Rsa(in, inLen, out, outLen, type, key, rng);
     1968        if (ret != NOT_COMPILED_IN)
     1969            return ret;
     1970        ret = 0; /* reset error code and try using software */
     1971    }
     1972#endif
     1973
     1974#ifndef TEST_UNPAD_CONSTANT_TIME
     1975#ifndef NO_RSA_BOUNDS_CHECK
     1976    if (type == RSA_PRIVATE_DECRYPT &&
     1977        key->state == RSA_STATE_DECRYPT_EXPTMOD) {
     1978
     1979        /* Check that 1 < in < n-1. (Requirement of 800-56B.) */
     1980#ifdef WOLFSSL_SMALL_STACK
     1981        mp_int* c = NULL;
     1982#else
     1983        mp_int c[1];
     1984#endif
     1985
     1986#ifdef WOLFSSL_SMALL_STACK
     1987        c = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);
     1988        if (c == NULL)
     1989            ret = MEMORY_E;
     1990#endif
     1991
     1992        if (mp_init(c) != MP_OKAY)
     1993            ret = MEMORY_E;
     1994        if (ret == 0) {
     1995            if (mp_read_unsigned_bin(c, in, inLen) != 0)
     1996                ret = MP_READ_E;
     1997        }
     1998        if (ret == 0) {
     1999            /* check c > 1 */
     2000            if (mp_cmp_d(c, 1) != MP_GT)
     2001                ret = RSA_OUT_OF_RANGE_E;
     2002        }
     2003        if (ret == 0) {
     2004            /* add c+1 */
     2005            if (mp_add_d(c, 1, c) != MP_OKAY)
     2006                ret = MP_ADD_E;
     2007        }
     2008        if (ret == 0) {
     2009            /* check c+1 < n */
     2010            if (mp_cmp(c, &key->n) != MP_LT)
     2011                ret = RSA_OUT_OF_RANGE_E;
     2012        }
     2013        mp_clear(c);
     2014
     2015#ifdef WOLFSSL_SMALL_STACK
     2016        XFREE(c, key->heap, DYNAMIC_TYPE_RSA);
     2017#endif
     2018
     2019        if (ret != 0)
     2020            return ret;
     2021    }
     2022#endif /* NO_RSA_BOUNDS_CHECK */
     2023#endif
    14112024
    14122025#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
     
    14172030    else
    14182031#endif
     2032#ifdef WC_RSA_NONBLOCK
     2033    if (key->nb) {
     2034        ret = wc_RsaFunctionNonBlock(in, inLen, out, outLen, type, key);
     2035    }
     2036    else
     2037#endif
    14192038    {
    14202039        ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
     
    14222041
    14232042    /* handle error */
    1424     if (ret < 0 && ret != WC_PENDING_E) {
     2043    if (ret < 0 && ret != WC_PENDING_E
     2044    #ifdef WC_RSA_NONBLOCK
     2045        && ret != FP_WOULDBLOCK
     2046    #endif
     2047    ) {
    14252048        if (ret == MP_EXPTMOD_E) {
    14262049            /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
     
    14362059
    14372060
     2061#ifndef WOLFSSL_RSA_VERIFY_ONLY
    14382062/* Internal Wrappers */
    14392063/* Gives the option of choosing padding type
     
    14472071        RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
    14482072   pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
    1449    pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD or
    1450         WC_RSA_PSS_PAD
     2073   pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD,
     2074        WC_RSA_NO_PAD or WC_RSA_PSS_PAD
    14512075   hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
    14522076   mgf   : type of mask generation function to use
    14532077   label : optional label
    1454    labelSz : size of optional label buffer */
     2078   labelSz : size of optional label buffer
     2079   saltLen : Length of salt used in PSS
     2080   rng : random number generator */
    14552081static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
    14562082                            word32 outLen, RsaKey* key, int rsa_type,
    14572083                            byte pad_value, int pad_type,
    14582084                            enum wc_HashType hash, int mgf,
    1459                             byte* label, word32 labelSz, WC_RNG* rng)
     2085                            byte* label, word32 labelSz, int saltLen,
     2086                            WC_RNG* rng)
    14602087{
    14612088    int ret, sz;
     
    14752102
    14762103    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {
     2104#ifdef WC_RSA_NO_PADDING
     2105        /* In the case that no padding is used the input length can and should
     2106         * be the same size as the RSA key. */
     2107        if (pad_type != WC_RSA_NO_PAD)
     2108#endif
    14772109        return RSA_BUFFER_E;
    14782110    }
     
    14812113    case RSA_STATE_NONE:
    14822114    case RSA_STATE_ENCRYPT_PAD:
    1483         key->state = RSA_STATE_ENCRYPT_PAD;
    1484 
    14852115    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
    14862116            defined(HAVE_CAVIUM)
    1487         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && key->n.raw.buf) {
     2117        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
     2118                                 pad_type != WC_RSA_PSS_PAD && key->n.raw.buf) {
    14882119            /* Async operations that include padding */
    14892120            if (rsa_type == RSA_PUBLIC_ENCRYPT &&
     
    15022133    #endif
    15032134
     2135        key->state = RSA_STATE_ENCRYPT_PAD;
    15042136        ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
    1505                            mgf, label, labelSz, mp_count_bits(&key->n),
     2137                           mgf, label, labelSz, saltLen, mp_count_bits(&key->n),
    15062138                           key->heap);
    15072139        if (ret < 0) {
     
    15102142
    15112143        key->state = RSA_STATE_ENCRYPT_EXPTMOD;
    1512 
    15132144        FALL_THROUGH;
    15142145
     
    15372168
    15382169    /* if async pending then return and skip done cleanup below */
    1539     if (ret == WC_PENDING_E) {
     2170    if (ret == WC_PENDING_E
     2171    #ifdef WC_RSA_NONBLOCK
     2172        || ret == FP_WOULDBLOCK
     2173    #endif
     2174    ) {
    15402175        return ret;
    15412176    }
     
    15462181    return ret;
    15472182}
     2183#endif
    15482184
    15492185/* Gives the option of choosing padding type
     
    15572193        RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
    15582194   pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
    1559    pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD
    1560         WC_RSA_PSS_PAD
     2195   pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD,
     2196        WC_RSA_NO_PAD, WC_RSA_PSS_PAD
    15612197   hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
    15622198   mgf   : type of mask generation function to use
    15632199   label : optional label
    1564    labelSz : size of optional label buffer */
     2200   labelSz : size of optional label buffer
     2201   saltLen : Length of salt used in PSS
     2202   rng : random number generator */
    15652203static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
    15662204                            word32 outLen, byte** outPtr, RsaKey* key,
    15672205                            int rsa_type, byte pad_value, int pad_type,
    15682206                            enum wc_HashType hash, int mgf,
    1569                             byte* label, word32 labelSz, WC_RNG* rng)
     2207                            byte* label, word32 labelSz, int saltLen,
     2208                            WC_RNG* rng)
    15702209{
    15712210    int ret = RSA_WRONG_TYPE_E;
     
    15772216    switch (key->state) {
    15782217    case RSA_STATE_NONE:
    1579     case RSA_STATE_DECRYPT_EXPTMOD:
    1580         key->state = RSA_STATE_DECRYPT_EXPTMOD;
    15812218        key->dataLen = inLen;
    15822219
     
    15842221            defined(HAVE_CAVIUM)
    15852222        /* Async operations that include padding */
    1586         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
     2223        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
     2224                                                   pad_type != WC_RSA_PSS_PAD) {
     2225#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    15872226            if (rsa_type == RSA_PRIVATE_DECRYPT &&
    15882227                                                pad_value == RSA_BLOCK_TYPE_2) {
    15892228                key->state = RSA_STATE_DECRYPT_RES;
    15902229                key->data = NULL;
    1591                 if (outPtr)
    1592                     *outPtr = in;
    1593                 return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, key);
     2230                return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen,
     2231                                               key);
     2232#endif
    15942233            }
    15952234            else if (rsa_type == RSA_PUBLIC_DECRYPT &&
     
    16022241    #endif
    16032242
     2243#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)
    16042244        /* verify the tmp ptr is NULL, otherwise indicates bad state */
    16052245        if (key->data != NULL) {
     
    16102250        /* if not doing this inline then allocate a buffer for it */
    16112251        if (outPtr == NULL) {
    1612             key->data = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
     2252            key->data = (byte*)XMALLOC(inLen, key->heap,
     2253                                                      DYNAMIC_TYPE_WOLF_BIGINT);
    16132254            key->dataIsAlloc = 1;
    16142255            if (key->data == NULL) {
     
    16212262            key->data = out;
    16222263        }
    1623         ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen, rsa_type,
    1624                                                                       key, rng);
     2264#endif
     2265
     2266        key->state = RSA_STATE_DECRYPT_EXPTMOD;
     2267        FALL_THROUGH;
     2268
     2269    case RSA_STATE_DECRYPT_EXPTMOD:
     2270#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)
     2271        ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen,
     2272                                                            rsa_type, key, rng);
     2273#else
     2274        ret = wc_RsaFunction(out, inLen, out, &key->dataLen, rsa_type, key,
     2275                                                                           rng);
     2276#endif
    16252277
    16262278        if (ret >= 0 || ret == WC_PENDING_E) {
     
    16362288    {
    16372289        byte* pad = NULL;
     2290#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)
    16382291        ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,
    1639                              hash, mgf, label, labelSz, mp_count_bits(&key->n),
    1640                              key->heap);
    1641         if (ret > 0 && ret <= (int)outLen && pad != NULL) {
     2292                             hash, mgf, label, labelSz, saltLen,
     2293                             mp_count_bits(&key->n), key->heap);
     2294#else
     2295        ret = wc_RsaUnPad_ex(out, key->dataLen, &pad, pad_value, pad_type, hash,
     2296                             mgf, label, labelSz, saltLen,
     2297                             mp_count_bits(&key->n), key->heap);
     2298#endif
     2299        if (rsa_type == RSA_PUBLIC_DECRYPT && ret > (int)outLen)
     2300            ret = RSA_BUFFER_E;
     2301        else if (ret >= 0 && pad != NULL) {
     2302#if !defined(WOLFSSL_RSA_VERIFY_ONLY)
     2303            signed char c;
     2304#endif
     2305
    16422306            /* only copy output if not inline */
    16432307            if (outPtr == NULL) {
     2308#if !defined(WOLFSSL_RSA_VERIFY_ONLY)
     2309                word32 i, j;
     2310                int start = (int)((size_t)pad - (size_t)key->data);
     2311
     2312                for (i = 0, j = 0; j < key->dataLen; j++) {
     2313                    out[i] = key->data[j];
     2314                    c  = ctMaskGTE(j, start);
     2315                    c &= ctMaskLT(i, outLen);
     2316                    /* 0 - no add, -1 add */
     2317                    i += -c;
     2318                }
     2319#else
    16442320                XMEMCPY(out, pad, ret);
     2321#endif
    16452322            }
    1646             else {
     2323            else
    16472324                *outPtr = pad;
    1648             }
    1649         }
    1650         else if (ret >= 0) {
     2325
     2326#if !defined(WOLFSSL_RSA_VERIFY_ONLY)
     2327            ret = ctMaskSelInt(ctMaskLTE(ret, outLen), ret, RSA_BUFFER_E);
     2328            ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret, RSA_BUFFER_E);
     2329#else
     2330            if (outLen < (word32)ret)
    16512331            ret = RSA_BUFFER_E;
    1652         }
    1653         if (ret < 0) {
    1654             break;
     2332#endif
    16552333        }
    16562334
     
    16622340    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
    16632341            defined(HAVE_CAVIUM)
    1664         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
    1665             /* return event ret */
    1666             ret = key->asyncDev.event.ret;
    1667             if (ret == 0) {
     2342        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
     2343                                                   pad_type != WC_RSA_PSS_PAD) {
     2344            if (ret > 0) {
    16682345                /* convert result */
    16692346                byte* dataLen = (byte*)&key->dataLen;
    16702347                ret = (dataLen[0] << 8) | (dataLen[1]);
     2348
     2349                if (outPtr)
     2350                    *outPtr = in;
    16712351            }
    16722352        }
     
    16802360
    16812361    /* if async pending then return and skip done cleanup below */
    1682     if (ret == WC_PENDING_E) {
     2362    if (ret == WC_PENDING_E
     2363    #ifdef WC_RSA_NONBLOCK
     2364        || ret == FP_WOULDBLOCK
     2365    #endif
     2366    ) {
    16832367        return ret;
    16842368    }
     
    16912375
    16922376
     2377#ifndef WOLFSSL_RSA_VERIFY_ONLY
    16932378/* Public RSA Functions */
    16942379int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
     
    16972382    return RsaPublicEncryptEx(in, inLen, out, outLen, key,
    16982383        RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
    1699         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
    1700 }
    1701 
    1702 
    1703 #ifndef WC_NO_RSA_OAEP
     2384        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
     2385}
     2386
     2387
     2388#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
    17042389int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
    17052390                    word32 outLen, RsaKey* key, WC_RNG* rng, int type,
     
    17082393{
    17092394    return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT,
    1710         RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, rng);
     2395        RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, 0, rng);
    17112396}
    17122397#endif /* WC_NO_RSA_OAEP */
    1713 
    1714 
     2398#endif
     2399
     2400
     2401#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    17152402int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
    17162403{
     
    17212408    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
    17222409        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
    1723         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
     2410        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
    17242411}
    17252412
     
    17362423    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
    17372424        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash,
    1738         mgf, label, labelSz, rng);
     2425        mgf, label, labelSz, 0, rng);
    17392426}
    17402427#endif /* WC_NO_RSA_OAEP */
     
    17502437    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
    17512438        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
    1752         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
    1753 }
    1754 
    1755 #ifndef WC_NO_RSA_OAEP
     2439        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
     2440}
     2441
     2442#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
    17562443int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out,
    17572444                            word32 outLen, RsaKey* key, int type,
     
    17652452    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
    17662453        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label,
    1767         labelSz, rng);
    1768 }
    1769 #endif /* WC_NO_RSA_OAEP */
     2454        labelSz, 0, rng);
     2455}
     2456#endif /* WC_NO_RSA_OAEP || WC_RSA_NO_PADDING */
     2457#endif /* WOLFSSL_RSA_PUBLIC_ONLY */
    17702458
    17712459
     
    17782466    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
    17792467        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
    1780         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
    1781 }
    1782 
     2468        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
     2469}
     2470
     2471#ifndef WOLFSSL_RSA_VERIFY_ONLY
    17832472int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
    17842473                                                                 RsaKey* key)
     
    17962485    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
    17972486        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
    1798         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
    1799 }
     2487        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
     2488}
     2489#endif
    18002490
    18012491#ifdef WC_RSA_PSS
     2492/* Verify the message signed with RSA-PSS.
     2493 * The input buffer is reused for the ouput buffer.
     2494 * Salt length is equal to hash length.
     2495 *
     2496 * in     Buffer holding encrypted data.
     2497 * inLen  Length of data in buffer.
     2498 * out    Pointer to address containing the PSS data.
     2499 * hash   Hash algorithm.
     2500 * mgf    Mask generation function.
     2501 * key    Public RSA key.
     2502 * returns the length of the PSS data on success and negative indicates failure.
     2503 */
    18022504int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
    18032505                           enum wc_HashType hash, int mgf, RsaKey* key)
     2506{
     2507    return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, -1, key);
     2508}
     2509
     2510/* Verify the message signed with RSA-PSS.
     2511 * The input buffer is reused for the ouput buffer.
     2512 *
     2513 * in       Buffer holding encrypted data.
     2514 * inLen    Length of data in buffer.
     2515 * out      Pointer to address containing the PSS data.
     2516 * hash     Hash algorithm.
     2517 * mgf      Mask generation function.
     2518 * key      Public RSA key.
     2519 * saltLen  Length of salt used. -1 indicates salt length is the same as the
     2520 *          hash length.
     2521 * returns the length of the PSS data on success and negative indicates failure.
     2522 */
     2523int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out,
     2524                              enum wc_HashType hash, int mgf, int saltLen,
     2525                              RsaKey* key)
    18042526{
    18052527    WC_RNG* rng = NULL;
     
    18092531    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
    18102532        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
    1811         hash, mgf, NULL, 0, rng);
    1812 }
    1813 
    1814 /* Sig = 8 * 0x00 | Space for Message Hash | Salt | Exp Hash
    1815  * Exp Hash = HASH(8 * 0x00 | Message Hash | Salt)
     2533        hash, mgf, NULL, 0, saltLen, rng);
     2534}
     2535
     2536/* Verify the message signed with RSA-PSS.
     2537 * Salt length is equal to hash length.
     2538 *
     2539 * in     Buffer holding encrypted data.
     2540 * inLen  Length of data in buffer.
     2541 * out    Pointer to address containing the PSS data.
     2542 * hash   Hash algorithm.
     2543 * mgf    Mask generation function.
     2544 * key    Public RSA key.
     2545 * returns the length of the PSS data on success and negative indicates failure.
     2546 */
     2547int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen,
     2548                     enum wc_HashType hash, int mgf, RsaKey* key)
     2549{
     2550    return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf, -1, key);
     2551}
     2552
     2553/* Verify the message signed with RSA-PSS.
     2554 *
     2555 * in       Buffer holding encrypted data.
     2556 * inLen    Length of data in buffer.
     2557 * out      Pointer to address containing the PSS data.
     2558 * hash     Hash algorithm.
     2559 * mgf      Mask generation function.
     2560 * key      Public RSA key.
     2561 * saltLen  Length of salt used. -1 indicates salt length is the same as the
     2562 *          hash length.
     2563 * returns the length of the PSS data on success and negative indicates failure.
     2564 */
     2565int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen,
     2566                        enum wc_HashType hash, int mgf, int saltLen,
     2567                        RsaKey* key)
     2568{
     2569    WC_RNG* rng = NULL;
     2570#ifdef WC_RSA_BLINDING
     2571    rng = key->rng;
     2572#endif
     2573    return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key,
     2574        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
     2575        hash, mgf, NULL, 0, saltLen, rng);
     2576}
     2577
     2578
     2579/* Checks the PSS data to ensure that the signature matches.
     2580 * Salt length is equal to hash length.
     2581 *
     2582 * in        Hash of the data that is being verified.
     2583 * inSz      Length of hash.
     2584 * sig       Buffer holding PSS data.
     2585 * sigSz     Size of PSS data.
     2586 * hashType  Hash algorithm.
     2587 * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when
     2588 * NULL is passed in to in or sig or inSz is not the same as the hash
     2589 * algorithm length and 0 on success.
    18162590 */
    18172591int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig,
    18182592                           word32 sigSz, enum wc_HashType hashType)
    18192593{
    1820     int ret;
     2594    return wc_RsaPSS_CheckPadding_ex(in, inSz, sig, sigSz, hashType, inSz, 0);
     2595}
     2596
     2597/* Checks the PSS data to ensure that the signature matches.
     2598 *
     2599 * in        Hash of the data that is being verified.
     2600 * inSz      Length of hash.
     2601 * sig       Buffer holding PSS data.
     2602 * sigSz     Size of PSS data.
     2603 * hashType  Hash algorithm.
     2604 * saltLen   Length of salt used. -1 indicates salt length is the same as the
     2605 *           hash length.
     2606 * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when
     2607 * NULL is passed in to in or sig or inSz is not the same as the hash
     2608 * algorithm length and 0 on success.
     2609 */
     2610int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inSz, byte* sig,
     2611                              word32 sigSz, enum wc_HashType hashType,
     2612                              int saltLen, int bits)
     2613{
     2614    int ret = 0;
     2615    byte sigCheck[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ];
     2616
     2617    (void)bits;
    18212618
    18222619    if (in == NULL || sig == NULL ||
    1823                       inSz != (word32)wc_HashGetDigestSize(hashType) ||
    1824                       sigSz != RSA_PSS_PAD_SZ + inSz * 3)
     2620                      inSz != (word32)wc_HashGetDigestSize(hashType))
    18252621        ret = BAD_FUNC_ARG;
    1826     else {
    1827         XMEMCPY(sig + RSA_PSS_PAD_SZ, in, inSz);
    1828         ret = wc_Hash(hashType, sig, RSA_PSS_PAD_SZ + inSz * 2, sig, inSz);
    1829         if (ret != 0)
    1830             return ret;
    1831         if (XMEMCMP(sig, sig + RSA_PSS_PAD_SZ + inSz * 2, inSz) != 0) {
     2622
     2623    if (ret == 0) {
     2624        if (saltLen == -1) {
     2625            saltLen = inSz;
     2626            #ifdef WOLFSSL_SHA512
     2627                /* See FIPS 186-4 section 5.5 item (e). */
     2628                if (bits == 1024 && inSz == WC_SHA512_DIGEST_SIZE)
     2629                    saltLen = RSA_PSS_SALT_MAX_SZ;
     2630            #endif
     2631        }
     2632        else if (saltLen < -1 || (word32)saltLen > inSz)
     2633            ret = PSS_SALTLEN_E;
     2634    }
     2635
     2636    /* Sig = Salt | Exp Hash */
     2637    if (ret == 0) {
     2638        if (sigSz != inSz + saltLen)
     2639            ret = BAD_PADDING_E;
     2640    }
     2641
     2642    /* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt) */
     2643    if (ret == 0) {
     2644        XMEMSET(sigCheck, 0, RSA_PSS_PAD_SZ);
     2645        XMEMCPY(sigCheck + RSA_PSS_PAD_SZ, in, inSz);
     2646        XMEMCPY(sigCheck + RSA_PSS_PAD_SZ + inSz, sig, saltLen);
     2647        ret = wc_Hash(hashType, sigCheck, RSA_PSS_PAD_SZ + inSz + saltLen,
     2648                      sigCheck, inSz);
     2649    }
     2650    if (ret == 0) {
     2651        if (XMEMCMP(sigCheck, sig + saltLen, inSz) != 0) {
    18322652            WOLFSSL_MSG("RsaPSS_CheckPadding: Padding Error");
    18332653            ret = BAD_PADDING_E;
    18342654        }
    1835         else
    1836             ret = 0;
    18372655    }
    18382656
    18392657    return ret;
    18402658}
    1841 #endif
    1842 
     2659
     2660
     2661/* Verify the message signed with RSA-PSS.
     2662 * The input buffer is reused for the ouput buffer.
     2663 * Salt length is equal to hash length.
     2664 *
     2665 * in     Buffer holding encrypted data.
     2666 * inLen  Length of data in buffer.
     2667 * out    Pointer to address containing the PSS data.
     2668 * digest Hash of the data that is being verified.
     2669 * digestLen Length of hash.
     2670 * hash   Hash algorithm.
     2671 * mgf    Mask generation function.
     2672 * key    Public RSA key.
     2673 * returns the length of the PSS data on success and negative indicates failure.
     2674 */
     2675int wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out,
     2676                           const byte* digest, word32 digestLen,
     2677                           enum wc_HashType hash, int mgf, RsaKey* key)
     2678{
     2679    int ret = 0, verify, saltLen, hLen, bits = 0;
     2680
     2681    hLen = wc_HashGetDigestSize(hash);
     2682    if (hLen < 0)
     2683        return hLen;
     2684    if ((word32)hLen != digestLen)
     2685        return BAD_FUNC_ARG;
     2686
     2687    saltLen = hLen;
     2688    #ifdef WOLFSSL_SHA512
     2689        /* See FIPS 186-4 section 5.5 item (e). */
     2690        bits = mp_count_bits(&key->n);
     2691        if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)
     2692            saltLen = RSA_PSS_SALT_MAX_SZ;
     2693    #endif
     2694
     2695    verify = wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, saltLen, key);
     2696    if (verify > 0)
     2697        ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, *out, verify,
     2698                                        hash, saltLen, bits);
     2699    if (ret == 0)
     2700        ret = verify;
     2701
     2702    return ret;
     2703}
     2704
     2705
     2706/* Verify the message signed with RSA-PSS.
     2707 * Salt length is equal to hash length.
     2708 *
     2709 * in     Buffer holding encrypted data.
     2710 * inLen  Length of data in buffer.
     2711 * out    Pointer to address containing the PSS data.
     2712 * outLen Length of the output.
     2713 * digest Hash of the data that is being verified.
     2714 * digestLen Length of hash.
     2715 * hash   Hash algorithm.
     2716 * mgf    Mask generation function.
     2717 * key    Public RSA key.
     2718 * returns the length of the PSS data on success and negative indicates failure.
     2719 */
     2720int wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, byte* out, word32 outLen,
     2721                          const byte* digest, word32 digestLen,
     2722                          enum wc_HashType hash, int mgf,
     2723                          RsaKey* key)
     2724{
     2725    int ret = 0, verify, saltLen, hLen, bits = 0;
     2726
     2727    hLen = wc_HashGetDigestSize(hash);
     2728    if (hLen < 0)
     2729        return hLen;
     2730    if ((word32)hLen != digestLen)
     2731        return BAD_FUNC_ARG;
     2732
     2733    saltLen = hLen;
     2734    #ifdef WOLFSSL_SHA512
     2735        /* See FIPS 186-4 section 5.5 item (e). */
     2736        bits = mp_count_bits(&key->n);
     2737        if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)
     2738            saltLen = RSA_PSS_SALT_MAX_SZ;
     2739    #endif
     2740
     2741    verify = wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash,
     2742                                 mgf, saltLen, key);
     2743    if (verify > 0)
     2744        ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, out, verify,
     2745                                        hash, saltLen, bits);
     2746    if (ret == 0)
     2747        ret = verify;
     2748
     2749    return ret;
     2750}
     2751
     2752#endif
     2753
     2754#ifndef WOLFSSL_RSA_PUBLIC_ONLY
    18432755int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
    18442756                                                   RsaKey* key, WC_RNG* rng)
     
    18462758    return RsaPublicEncryptEx(in, inLen, out, outLen, key,
    18472759        RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
    1848         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
     2760        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);
    18492761}
    18502762
    18512763#ifdef WC_RSA_PSS
     2764/* Sign the hash of a message using RSA-PSS.
     2765 * Salt length is equal to hash length.
     2766 *
     2767 * in      Buffer holding hash of message.
     2768 * inLen   Length of data in buffer (hash length).
     2769 * out     Buffer to write encrypted signature into.
     2770 * outLen  Size of buffer to write to.
     2771 * hash    Hash algorithm.
     2772 * mgf     Mask generation function.
     2773 * key     Public RSA key.
     2774 * rng     Random number generator.
     2775 * returns the length of the encrypted signature on success, a negative value
     2776 * indicates failure.
     2777 */
    18522778int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
    18532779                       enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng)
    18542780{
     2781    return wc_RsaPSS_Sign_ex(in, inLen, out, outLen, hash, mgf, -1, key, rng);
     2782}
     2783
     2784/* Sign the hash of a message using RSA-PSS.
     2785 *
     2786 * in       Buffer holding hash of message.
     2787 * inLen    Length of data in buffer (hash length).
     2788 * out      Buffer to write encrypted signature into.
     2789 * outLen   Size of buffer to write to.
     2790 * hash     Hash algorithm.
     2791 * mgf      Mask generation function.
     2792 * saltLen  Length of salt used. -1 indicates salt length is the same as the
     2793 *          hash length.
     2794 * key      Public RSA key.
     2795 * rng      Random number generator.
     2796 * returns the length of the encrypted signature on success, a negative value
     2797 * indicates failure.
     2798 */
     2799int wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out, word32 outLen,
     2800                      enum wc_HashType hash, int mgf, int saltLen, RsaKey* key,
     2801                      WC_RNG* rng)
     2802{
    18552803    return RsaPublicEncryptEx(in, inLen, out, outLen, key,
    18562804        RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
    1857         hash, mgf, NULL, 0, rng);
    1858 }
    1859 #endif
    1860 
     2805        hash, mgf, NULL, 0, saltLen, rng);
     2806}
     2807#endif
     2808#endif
     2809
     2810#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || !defined(WOLFSSL_SP_MATH)
    18612811int wc_RsaEncryptSize(RsaKey* key)
    18622812{
     2813    int ret;
     2814
    18632815    if (key == NULL) {
    18642816        return BAD_FUNC_ARG;
    18652817    }
    1866     return mp_unsigned_bin_size(&key->n);
    1867 }
    1868 
    1869 
     2818
     2819    ret = mp_unsigned_bin_size(&key->n);
     2820
     2821#ifdef WOLF_CRYPTO_DEV
     2822    if (ret == 0 && key->devId != INVALID_DEVID) {
     2823        ret = 2048/8; /* hardware handles, use 2048-bit as default */
     2824}
     2825#endif
     2826
     2827    return ret;
     2828}
     2829#endif
     2830
     2831#ifndef WOLFSSL_RSA_VERIFY_ONLY
    18702832/* flatten RsaKey structure into individual elements (e, n) */
    18712833int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
     
    18962858    return 0;
    18972859}
     2860#endif
     2861
     2862#endif /* HAVE_FIPS */
     2863
     2864
     2865#ifndef WOLFSSL_RSA_VERIFY_ONLY
     2866static int RsaGetValue(mp_int* in, byte* out, word32* outSz)
     2867{
     2868    word32 sz;
     2869    int ret = 0;
     2870
     2871    /* Parameters ensured by calling function. */
     2872
     2873    sz = (word32)mp_unsigned_bin_size(in);
     2874    if (sz > *outSz)
     2875        ret = RSA_BUFFER_E;
     2876
     2877    if (ret == 0)
     2878        ret = mp_to_unsigned_bin(in, out);
     2879
     2880    if (ret == MP_OKAY)
     2881        *outSz = sz;
     2882
     2883    return ret;
     2884}
     2885
     2886
     2887int wc_RsaExportKey(RsaKey* key,
     2888                    byte* e, word32* eSz, byte* n, word32* nSz,
     2889                    byte* d, word32* dSz, byte* p, word32* pSz,
     2890                    byte* q, word32* qSz)
     2891{
     2892    int ret = BAD_FUNC_ARG;
     2893
     2894    if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz)
     2895        ret = 0;
     2896
     2897    if (ret == 0)
     2898        ret = RsaGetValue(&key->e, e, eSz);
     2899    if (ret == 0)
     2900        ret = RsaGetValue(&key->n, n, nSz);
     2901#ifndef WOLFSSL_RSA_PUBLIC_ONLY
     2902    if (ret == 0)
     2903        ret = RsaGetValue(&key->d, d, dSz);
     2904    if (ret == 0)
     2905        ret = RsaGetValue(&key->p, p, pSz);
     2906    if (ret == 0)
     2907        ret = RsaGetValue(&key->q, q, qSz);
     2908#else
     2909    /* no private parts to key */
     2910    if (d == NULL || p == NULL || q == NULL || dSz == NULL || pSz == NULL
     2911            || qSz == NULL) {
     2912        ret = BAD_FUNC_ARG;
     2913    }
     2914    else {
     2915        *dSz = 0;
     2916        *pSz = 0;
     2917        *qSz = 0;
     2918    }
     2919#endif /* WOLFSSL_RSA_PUBLIC_ONLY */
     2920
     2921    return ret;
     2922}
     2923#endif
     2924
    18982925
    18992926#ifdef WOLFSSL_KEY_GEN
     2927
     2928/* Check that |p-q| > 2^((size/2)-100) */
     2929static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size)
     2930{
     2931    mp_int c, d;
     2932    int ret;
     2933
     2934    if (p == NULL || q == NULL)
     2935        return BAD_FUNC_ARG;
     2936
     2937    ret = mp_init_multi(&c, &d, NULL, NULL, NULL, NULL);
     2938
     2939    /* c = 2^((size/2)-100) */
     2940    if (ret == 0)
     2941        ret = mp_2expt(&c, (size/2)-100);
     2942
     2943    /* d = |p-q| */
     2944    if (ret == 0)
     2945        ret = mp_sub(p, q, &d);
     2946
     2947    if (ret == 0)
     2948        ret = mp_abs(&d, &d);
     2949
     2950    /* compare */
     2951    if (ret == 0)
     2952        ret = mp_cmp(&d, &c);
     2953
     2954    if (ret == MP_GT)
     2955        ret = MP_OKAY;
     2956
     2957    mp_clear(&d);
     2958    mp_clear(&c);
     2959
     2960    return ret;
     2961}
     2962
     2963
     2964/* The lower_bound value is floor(2^(0.5) * 2^((nlen/2)-1)) where nlen is 4096.
     2965 * This number was calculated using a small test tool written with a common
     2966 * large number math library. Other values of nlen may be checked with a subset
     2967 * of lower_bound. */
     2968static const byte lower_bound[] = {
     2969    0xB5, 0x04, 0xF3, 0x33, 0xF9, 0xDE, 0x64, 0x84,
     2970    0x59, 0x7D, 0x89, 0xB3, 0x75, 0x4A, 0xBE, 0x9F,
     2971    0x1D, 0x6F, 0x60, 0xBA, 0x89, 0x3B, 0xA8, 0x4C,
     2972    0xED, 0x17, 0xAC, 0x85, 0x83, 0x33, 0x99, 0x15,
     2973/* 512 */
     2974    0x4A, 0xFC, 0x83, 0x04, 0x3A, 0xB8, 0xA2, 0xC3,
     2975    0xA8, 0xB1, 0xFE, 0x6F, 0xDC, 0x83, 0xDB, 0x39,
     2976    0x0F, 0x74, 0xA8, 0x5E, 0x43, 0x9C, 0x7B, 0x4A,
     2977    0x78, 0x04, 0x87, 0x36, 0x3D, 0xFA, 0x27, 0x68,
     2978/* 1024 */
     2979    0xD2, 0x20, 0x2E, 0x87, 0x42, 0xAF, 0x1F, 0x4E,
     2980    0x53, 0x05, 0x9C, 0x60, 0x11, 0xBC, 0x33, 0x7B,
     2981    0xCA, 0xB1, 0xBC, 0x91, 0x16, 0x88, 0x45, 0x8A,
     2982    0x46, 0x0A, 0xBC, 0x72, 0x2F, 0x7C, 0x4E, 0x33,
     2983    0xC6, 0xD5, 0xA8, 0xA3, 0x8B, 0xB7, 0xE9, 0xDC,
     2984    0xCB, 0x2A, 0x63, 0x43, 0x31, 0xF3, 0xC8, 0x4D,
     2985    0xF5, 0x2F, 0x12, 0x0F, 0x83, 0x6E, 0x58, 0x2E,
     2986    0xEA, 0xA4, 0xA0, 0x89, 0x90, 0x40, 0xCA, 0x4A,
     2987/* 2048 */
     2988    0x81, 0x39, 0x4A, 0xB6, 0xD8, 0xFD, 0x0E, 0xFD,
     2989    0xF4, 0xD3, 0xA0, 0x2C, 0xEB, 0xC9, 0x3E, 0x0C,
     2990    0x42, 0x64, 0xDA, 0xBC, 0xD5, 0x28, 0xB6, 0x51,
     2991    0xB8, 0xCF, 0x34, 0x1B, 0x6F, 0x82, 0x36, 0xC7,
     2992    0x01, 0x04, 0xDC, 0x01, 0xFE, 0x32, 0x35, 0x2F,
     2993    0x33, 0x2A, 0x5E, 0x9F, 0x7B, 0xDA, 0x1E, 0xBF,
     2994    0xF6, 0xA1, 0xBE, 0x3F, 0xCA, 0x22, 0x13, 0x07,
     2995    0xDE, 0xA0, 0x62, 0x41, 0xF7, 0xAA, 0x81, 0xC2,
     2996/* 3072 */
     2997    0xC1, 0xFC, 0xBD, 0xDE, 0xA2, 0xF7, 0xDC, 0x33,
     2998    0x18, 0x83, 0x8A, 0x2E, 0xAF, 0xF5, 0xF3, 0xB2,
     2999    0xD2, 0x4F, 0x4A, 0x76, 0x3F, 0xAC, 0xB8, 0x82,
     3000    0xFD, 0xFE, 0x17, 0x0F, 0xD3, 0xB1, 0xF7, 0x80,
     3001    0xF9, 0xAC, 0xCE, 0x41, 0x79, 0x7F, 0x28, 0x05,
     3002    0xC2, 0x46, 0x78, 0x5E, 0x92, 0x95, 0x70, 0x23,
     3003    0x5F, 0xCF, 0x8F, 0x7B, 0xCA, 0x3E, 0xA3, 0x3B,
     3004    0x4D, 0x7C, 0x60, 0xA5, 0xE6, 0x33, 0xE3, 0xE1
     3005/* 4096 */
     3006};
     3007
     3008
     3009/* returns 1 on key size ok and 0 if not ok */
     3010static WC_INLINE int RsaSizeCheck(int size)
     3011{
     3012    if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE) {
     3013        return 0;
     3014    }
     3015
     3016#ifdef HAVE_FIPS
     3017    /* Key size requirements for CAVP */
     3018    switch (size) {
     3019        case 1024:
     3020        case 2048:
     3021        case 3072:
     3022        case 4096:
     3023            return 1;
     3024    }
     3025
     3026    return 0;
     3027#else
     3028    return 1; /* allow unusual key sizes in non FIPS mode */
     3029#endif /* HAVE_FIPS */
     3030}
     3031
     3032
     3033static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen,
     3034                                    int* isPrime, WC_RNG* rng)
     3035{
     3036    int ret;
     3037    mp_int tmp1, tmp2;
     3038    mp_int* prime;
     3039
     3040    if (p == NULL || e == NULL || isPrime == NULL)
     3041        return BAD_FUNC_ARG;
     3042
     3043    if (!RsaSizeCheck(nlen))
     3044        return BAD_FUNC_ARG;
     3045
     3046    *isPrime = MP_NO;
     3047
     3048    if (q != NULL) {
     3049        /* 5.4 - check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */
     3050        ret = wc_CompareDiffPQ(p, q, nlen);
     3051        if (ret != MP_OKAY) goto notOkay;
     3052        prime = q;
     3053    }
     3054    else
     3055        prime = p;
     3056
     3057    ret = mp_init_multi(&tmp1, &tmp2, NULL, NULL, NULL, NULL);
     3058    if (ret != MP_OKAY) goto notOkay;
     3059
     3060    /* 4.4,5.5 - Check that prime >= (2^(1/2))(2^((nlen/2)-1))
     3061     *           This is a comparison against lowerBound */
     3062    ret = mp_read_unsigned_bin(&tmp1, lower_bound, nlen/16);
     3063    if (ret != MP_OKAY) goto notOkay;
     3064    ret = mp_cmp(prime, &tmp1);
     3065    if (ret == MP_LT) goto exit;
     3066
     3067    /* 4.5,5.6 - Check that GCD(p-1, e) == 1 */
     3068    ret = mp_sub_d(prime, 1, &tmp1);  /* tmp1 = prime-1 */
     3069    if (ret != MP_OKAY) goto notOkay;
     3070    ret = mp_gcd(&tmp1, e, &tmp2);  /* tmp2 = gcd(prime-1, e) */
     3071    if (ret != MP_OKAY) goto notOkay;
     3072    ret = mp_cmp_d(&tmp2, 1);
     3073    if (ret != MP_EQ) goto exit; /* e divides p-1 */
     3074
     3075    /* 4.5.1,5.6.1 - Check primality of p with 8 rounds of M-R.
     3076     * mp_prime_is_prime_ex() performs test divisions against the first 256
     3077     * prime numbers. After that it performs 8 rounds of M-R using random
     3078     * bases between 2 and n-2.
     3079     * mp_prime_is_prime() performs the same test divisions and then does
     3080     * M-R with the first 8 primes. Both functions set isPrime as a
     3081     * side-effect. */
     3082    if (rng != NULL)
     3083        ret = mp_prime_is_prime_ex(prime, 8, isPrime, rng);
     3084    else
     3085        ret = mp_prime_is_prime(prime, 8, isPrime);
     3086    if (ret != MP_OKAY) goto notOkay;
     3087
     3088exit:
     3089    ret = MP_OKAY;
     3090notOkay:
     3091    mp_clear(&tmp1);
     3092    mp_clear(&tmp2);
     3093    return ret;
     3094}
     3095
     3096
     3097int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz,
     3098                          const byte* qRaw, word32 qRawSz,
     3099                          const byte* eRaw, word32 eRawSz,
     3100                          int nlen, int* isPrime, WC_RNG* rng)
     3101{
     3102    mp_int p, q, e;
     3103    mp_int* Q = NULL;
     3104    int ret;
     3105
     3106    if (pRaw == NULL || pRawSz == 0 ||
     3107        eRaw == NULL || eRawSz == 0 ||
     3108        isPrime == NULL) {
     3109
     3110        return BAD_FUNC_ARG;
     3111    }
     3112
     3113    if ((qRaw != NULL && qRawSz == 0) || (qRaw == NULL && qRawSz != 0))
     3114        return BAD_FUNC_ARG;
     3115
     3116    ret = mp_init_multi(&p, &q, &e, NULL, NULL, NULL);
     3117
     3118    if (ret == MP_OKAY)
     3119        ret = mp_read_unsigned_bin(&p, pRaw, pRawSz);
     3120
     3121    if (ret == MP_OKAY) {
     3122        if (qRaw != NULL) {
     3123            ret = mp_read_unsigned_bin(&q, qRaw, qRawSz);
     3124            if (ret == MP_OKAY)
     3125                Q = &q;
     3126        }
     3127    }
     3128
     3129    if (ret == MP_OKAY)
     3130        ret = mp_read_unsigned_bin(&e, eRaw, eRawSz);
     3131
     3132    if (ret == MP_OKAY)
     3133        ret = _CheckProbablePrime(&p, Q, &e, nlen, isPrime, rng);
     3134
     3135    ret = (ret == MP_OKAY) ? 0 : PRIME_GEN_E;
     3136
     3137    mp_clear(&p);
     3138    mp_clear(&q);
     3139    mp_clear(&e);
     3140
     3141    return ret;
     3142}
     3143
     3144
     3145int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz,
     3146                          const byte* qRaw, word32 qRawSz,
     3147                          const byte* eRaw, word32 eRawSz,
     3148                          int nlen, int* isPrime)
     3149{
     3150    return wc_CheckProbablePrime_ex(pRaw, pRawSz, qRaw, qRawSz,
     3151                          eRaw, eRawSz, nlen, isPrime, NULL);
     3152}
     3153
     3154#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && \
     3155        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
    19003156/* Make an RSA key for size bits, with e specified, 65537 is a good e */
    19013157int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
    19023158{
     3159#ifndef WC_NO_RNG
    19033160    mp_int p, q, tmp1, tmp2, tmp3;
    1904     int    err;
     3161    int err, i, failCount, primeSz, isPrime = 0;
     3162    byte* buf = NULL;
    19053163
    19063164    if (key == NULL || rng == NULL)
    19073165        return BAD_FUNC_ARG;
    19083166
    1909     if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
     3167    if (!RsaSizeCheck(size))
    19103168        return BAD_FUNC_ARG;
    19113169
     
    19133171        return BAD_FUNC_ARG;
    19143172
    1915 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
     3173#ifdef WOLF_CRYPTO_DEV
     3174    if (key->devId != INVALID_DEVID) {
     3175        int ret = wc_CryptoDev_MakeRsaKey(key, size, e, rng);
     3176        if (ret != NOT_COMPILED_IN)
     3177            return ret;
     3178    }
     3179#endif
     3180
     3181#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
     3182    defined(WC_ASYNC_ENABLE_RSA_KEYGEN)
    19163183    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
    19173184    #ifdef HAVE_CAVIUM
    19183185        /* TODO: Not implemented */
    19193186    #elif defined(HAVE_INTEL_QA)
    1920         /* TODO: Not implemented */
     3187        return IntelQaRsaKeyGen(&key->asyncDev, key, size, e, rng);
    19213188    #else
    19223189        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_MAKE)) {
     
    19323199#endif
    19333200
    1934     if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
    1935         return err;
    1936 
     3201    err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL);
     3202
     3203    if (err == MP_OKAY)
    19373204    err = mp_set_int(&tmp3, e);
     3205
     3206    /* The failCount value comes from NIST FIPS 186-4, section B.3.3,
     3207     * process steps 4.7 and 5.8. */
     3208    failCount = 5 * (size / 2);
     3209    primeSz = size / 16; /* size is the size of n in bits.
     3210                            primeSz is in bytes. */
     3211
     3212    /* allocate buffer to work with */
     3213    if (err == MP_OKAY) {
     3214        buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA);
     3215        if (buf == NULL)
     3216            err = MEMORY_E;
     3217    }
    19383218
    19393219    /* make p */
    19403220    if (err == MP_OKAY) {
     3221        isPrime = 0;
     3222        i = 0;
    19413223        do {
    1942             err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
     3224#ifdef SHOW_GEN
     3225            printf(".");
     3226            fflush(stdout);
     3227#endif
     3228            /* generate value */
     3229            err = wc_RNG_GenerateBlock(rng, buf, primeSz);
     3230            if (err == 0) {
     3231                /* prime lower bound has the MSB set, set it in candidate */
     3232                buf[0] |= 0x80;
     3233                /* make candidate odd */
     3234                buf[primeSz-1] |= 0x01;
     3235                /* load value */
     3236                err = mp_read_unsigned_bin(&p, buf, primeSz);
     3237            }
    19433238
    19443239            if (err == MP_OKAY)
    1945                 err = mp_sub_d(&p, 1, &tmp1);  /* tmp1 = p-1 */
    1946 
    1947             if (err == MP_OKAY)
    1948                 err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(p-1, e) */
    1949         } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divides p-1 */
    1950     }
     3240                err = _CheckProbablePrime(&p, NULL, &tmp3, size, &isPrime, rng);
     3241
     3242#ifdef WOLFSSL_FIPS
     3243            i++;
     3244#else
     3245            /* Keep the old retry behavior in non-FIPS build. */
     3246            (void)i;
     3247#endif
     3248        } while (err == MP_OKAY && !isPrime && i < failCount);
     3249    }
     3250
     3251    if (err == MP_OKAY && !isPrime)
     3252        err = PRIME_GEN_E;
    19513253
    19523254    /* make q */
    19533255    if (err == MP_OKAY) {
     3256        isPrime = 0;
     3257        i = 0;
    19543258        do {
    1955             err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
     3259#ifdef SHOW_GEN
     3260            printf(".");
     3261            fflush(stdout);
     3262#endif
     3263            /* generate value */
     3264            err = wc_RNG_GenerateBlock(rng, buf, primeSz);
     3265            if (err == 0) {
     3266                /* prime lower bound has the MSB set, set it in candidate */
     3267                buf[0] |= 0x80;
     3268                /* make candidate odd */
     3269                buf[primeSz-1] |= 0x01;
     3270                /* load value */
     3271                err = mp_read_unsigned_bin(&q, buf, primeSz);
     3272            }
    19563273
    19573274            if (err == MP_OKAY)
    1958                 err = mp_sub_d(&q, 1, &tmp1);  /* tmp1 = q-1 */
    1959 
    1960             if (err == MP_OKAY)
    1961                 err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(q-1, e) */
    1962         } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divides q-1 */
    1963     }
    1964 
     3275                err = _CheckProbablePrime(&p, &q, &tmp3, size, &isPrime, rng);
     3276
     3277#ifdef WOLFSSL_FIPS
     3278            i++;
     3279#else
     3280            /* Keep the old retry behavior in non-FIPS build. */
     3281            (void)i;
     3282#endif
     3283        } while (err == MP_OKAY && !isPrime && i < failCount);
     3284    }
     3285
     3286    if (err == MP_OKAY && !isPrime)
     3287        err = PRIME_GEN_E;
     3288
     3289    if (buf) {
     3290        ForceZero(buf, primeSz);
     3291        XFREE(buf, key->heap, DYNAMIC_TYPE_RSA);
     3292    }
     3293
     3294
     3295    /* Setup RsaKey buffers */
    19653296    if (err == MP_OKAY)
    19663297        err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
    1967 
    19683298    if (err == MP_OKAY)
    19693299        err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
    19703300
    1971     if (err == MP_OKAY)
    1972         err = mp_sub_d(&p, 1, &tmp2);  /* tmp2 = p-1 */
    1973 
    1974     if (err == MP_OKAY)
    1975         err = mp_lcm(&tmp1, &tmp2, &tmp1);  /* tmp1 = lcm(p-1, q-1),last loop */
    1976 
     3301    /* Software Key Calculation */
     3302    if (err == MP_OKAY)                /* tmp1 = p-1 */
     3303        err = mp_sub_d(&p, 1, &tmp1);
     3304    if (err == MP_OKAY)                /* tmp2 = q-1 */
     3305        err = mp_sub_d(&q, 1, &tmp2);
     3306    if (err == MP_OKAY)                /* tmp3 = lcm(p-1, q-1), last loop */
     3307        err = mp_lcm(&tmp1, &tmp2, &tmp3);
    19773308    /* make key */
    1978     if (err == MP_OKAY)
    1979         err = mp_set_int(&key->e, (mp_digit)e);  /* key->e = e */
    1980 
     3309    if (err == MP_OKAY)                /* key->e = e */
     3310        err = mp_set_int(&key->e, (mp_digit)e);
    19813311    if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */
    1982         err = mp_invmod(&key->e, &tmp1, &key->d);
    1983 
    1984     if (err == MP_OKAY)
    1985         err = mp_mul(&p, &q, &key->n);  /* key->n = pq */
    1986 
    1987     if (err == MP_OKAY)
    1988         err = mp_sub_d(&p, 1, &tmp1);
    1989 
    1990     if (err == MP_OKAY)
    1991         err = mp_sub_d(&q, 1, &tmp2);
    1992 
    1993     if (err == MP_OKAY)
     3312        err = mp_invmod(&key->e, &tmp3, &key->d);
     3313    if (err == MP_OKAY)                /* key->n = pq */
     3314        err = mp_mul(&p, &q, &key->n);
     3315    if (err == MP_OKAY)                /* key->dP = d mod(p-1) */
    19943316        err = mp_mod(&key->d, &tmp1, &key->dP);
    1995 
    1996     if (err == MP_OKAY)
     3317    if (err == MP_OKAY)                /* key->dQ = d mod(q-1) */
    19973318        err = mp_mod(&key->d, &tmp2, &key->dQ);
    1998 
    1999     if (err == MP_OKAY)
     3319    if (err == MP_OKAY)                /* key->u = 1/q mod p */
    20003320        err = mp_invmod(&q, &p, &key->u);
    2001 
    20023321    if (err == MP_OKAY)
    20033322        err = mp_copy(&p, &key->p);
    2004 
    20053323    if (err == MP_OKAY)
    20063324        err = mp_copy(&q, &key->q);
    20073325
     3326#ifdef HAVE_WOLF_BIGINT
     3327    /* make sure raw unsigned bin version is available */
     3328    if (err == MP_OKAY)
     3329         err = wc_mp_to_bigint(&key->n, &key->n.raw);
     3330    if (err == MP_OKAY)
     3331         err = wc_mp_to_bigint(&key->e, &key->e.raw);
     3332    if (err == MP_OKAY)
     3333         err = wc_mp_to_bigint(&key->d, &key->d.raw);
     3334    if (err == MP_OKAY)
     3335         err = wc_mp_to_bigint(&key->p, &key->p.raw);
     3336    if (err == MP_OKAY)
     3337         err = wc_mp_to_bigint(&key->q, &key->q.raw);
     3338    if (err == MP_OKAY)
     3339         err = wc_mp_to_bigint(&key->dP, &key->dP.raw);
     3340    if (err == MP_OKAY)
     3341         err = wc_mp_to_bigint(&key->dQ, &key->dQ.raw);
     3342    if (err == MP_OKAY)
     3343         err = wc_mp_to_bigint(&key->u, &key->u.raw);
     3344#endif
     3345
    20083346    if (err == MP_OKAY)
    20093347        key->type = RSA_PRIVATE;
    20103348
     3349    mp_clear(&tmp1);
     3350    mp_clear(&tmp2);
    20113351    mp_clear(&tmp3);
    2012     mp_clear(&tmp2);
    2013     mp_clear(&tmp1);
     3352    mp_clear(&p);
    20143353    mp_clear(&q);
    2015     mp_clear(&p);
    2016 
    2017     if (err != MP_OKAY) {
     3354
     3355    /* Perform the pair-wise consistency test on the new key. */
     3356    if (err == 0)
     3357        err = wc_CheckRsaKey(key);
     3358
     3359    if (err != 0) {
    20183360        wc_FreeRsaKey(key);
    20193361        return err;
     
    20253367    }
    20263368#endif
    2027 
    20283369    return 0;
    2029 }
     3370#else
     3371    return NOT_COMPILED_IN;
     3372#endif
     3373}
     3374#endif /* !FIPS || FIPS_VER >= 2 */
    20303375#endif /* WOLFSSL_KEY_GEN */
    20313376
    20323377
    20333378#ifdef WC_RSA_BLINDING
    2034 
    20353379int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
    20363380{
     
    20423386    return 0;
    20433387}
    2044 
    20453388#endif /* WC_RSA_BLINDING */
    20463389
    2047 
    2048 #undef ERROR_OUT
    2049 
    2050 #endif /* HAVE_FIPS */
     3390#ifdef WC_RSA_NONBLOCK
     3391int wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb)
     3392{
     3393    if (key == NULL)
     3394        return BAD_FUNC_ARG;
     3395
     3396    if (nb) {
     3397        XMEMSET(nb, 0, sizeof(RsaNb));
     3398    }
     3399
     3400    /* Allow nb == NULL to clear non-block mode */
     3401    key->nb = nb;
     3402
     3403    return 0;
     3404}
     3405#ifdef WC_RSA_NONBLOCK_TIME
     3406int wc_RsaSetNonBlockTime(RsaKey* key, word32 maxBlockUs, word32 cpuMHz)
     3407{
     3408    if (key == NULL || key->nb == NULL) {
     3409        return BAD_FUNC_ARG;
     3410    }
     3411
     3412    /* calculate maximum number of instructions to block */
     3413    key->nb->exptmod.maxBlockInst = cpuMHz * maxBlockUs;
     3414
     3415    return 0;
     3416}
     3417#endif /* WC_RSA_NONBLOCK_TIME */
     3418#endif /* WC_RSA_NONBLOCK */
     3419
    20513420#endif /* NO_RSA */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/sha.c

    r352 r372  
    2929#if !defined(NO_SHA)
    3030
     31#if defined(HAVE_FIPS) && \
     32        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     33
     34    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     35    #define FIPS_NO_WRAPPERS
     36
     37    #ifdef USE_WINDOWS_API
     38        #pragma code_seg(".fipsA$j")
     39        #pragma const_seg(".fipsB$j")
     40    #endif
     41#endif
     42
    3143#include <wolfssl/wolfcrypt/sha.h>
    3244#include <wolfssl/wolfcrypt/error-crypt.h>
    3345
    3446/* fips wrapper calls, user can call direct */
    35 #ifdef HAVE_FIPS
     47#if defined(HAVE_FIPS) && \
     48    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     49
    3650    int wc_InitSha(wc_Sha* sha)
    3751    {
     
    7286    }
    7387
    74 #else /* else build without fips */
     88#else /* else build without fips, or for FIPS v2 */
    7589
    7690
     
    88102#endif
    89103
    90 static INLINE void AddLength(wc_Sha* sha, word32 len);
    91 
    92104
    93105/* Hardware Acceleration */
     
    97109#elif defined(STM32_HASH)
    98110
    99     /*
    100      * STM32F2/F4/F7 hardware SHA1 support through the HASH_* API's from the
    101      * Standard Peripheral Library or CubeMX (See note in README).
    102      */
    103 
    104     /* STM32 register size, bytes */
    105     #ifdef WOLFSSL_STM32_CUBEMX
    106         #define SHA_REG_SIZE  WC_SHA_BLOCK_SIZE
    107     #else
    108         #define SHA_REG_SIZE  4
    109         /* STM32 struct notes:
    110          * sha->buffer  = first 4 bytes used to hold partial block if needed
    111          * sha->buffLen = num bytes currently stored in sha->buffer
    112          * sha->loLen   = num bytes that have been written to STM32 FIFO
    113          */
    114     #endif
    115     #define SHA_HW_TIMEOUT 0xFF
    116 
     111    /* Supports CubeMX HAL or Standard Peripheral Library */
    117112        int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
    118113    {
    119                 if (sha == NULL)
     114        if (sha == NULL) {
    120115                        return BAD_FUNC_ARG;
    121 
    122                 sha->heap = heap;
    123         XMEMSET(sha->buffer, 0, sizeof(sha->buffer));
    124         sha->buffLen = 0;
    125         sha->loLen = 0;
    126         sha->hiLen = 0;
    127 
    128         /* initialize HASH peripheral */
    129     #ifdef WOLFSSL_STM32_CUBEMX
    130         HAL_HASH_DeInit(&sha->hashHandle);
    131         sha->hashHandle.Init.DataType = HASH_DATATYPE_8B;
    132         if (HAL_HASH_Init(&sha->hashHandle) != HAL_OK) {
    133             return ASYNC_INIT_E;
    134         }
    135 
    136         /* reset the hash control register */
    137         /* required because Cube MX is not clearing algo bits */
    138         HASH->CR &= ~HASH_CR_ALGO;
    139     #else
    140         HASH_DeInit();
    141 
    142         /* reset the hash control register */
    143         HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
    144 
    145         /* configure algo used, algo mode, datatype */
    146         HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH
    147                    | HASH_DataType_8b);
    148 
    149         /* reset HASH processor */
    150         HASH->CR |= HASH_CR_INIT;
    151     #endif
     116        }
     117
     118        (void)devId;
     119        (void)heap;
     120
     121        wc_Stm32_Hash_Init(&sha->stmCtx);
    152122
    153123        return 0;
     
    156126    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
    157127    {
    158         int ret = 0;
    159         byte* local;
     128        int ret;
    160129
    161130        if (sha == NULL || (data == NULL && len > 0)) {
     
    163132        }
    164133
    165         /* do block size increments */
    166         local = (byte*)sha->buffer;
    167 
    168         /* check that internal buffLen is valid */
    169         if (sha->buffLen >= SHA_REG_SIZE)
    170             return BUFFER_E;
    171 
    172         while (len) {
    173             word32 add = min(len, SHA_REG_SIZE - sha->buffLen);
    174             XMEMCPY(&local[sha->buffLen], data, add);
    175 
    176             sha->buffLen += add;
    177             data         += add;
    178             len          -= add;
    179 
    180             if (sha->buffLen == SHA_REG_SIZE) {
    181             #ifdef WOLFSSL_STM32_CUBEMX
    182                 if (HAL_HASH_SHA1_Accumulate(
    183                         &sha->hashHandle, local, SHA_REG_SIZE) != HAL_OK) {
    184                     ret = ASYNC_OP_E;
    185                 }
    186             #else
    187                 HASH_DataIn(*(uint32_t*)local);
    188             #endif
    189 
    190                 AddLength(sha, SHA_REG_SIZE);
    191                 sha->buffLen = 0;
    192             }
     134        ret = wolfSSL_CryptHwMutexLock();
     135        if (ret == 0) {
     136            ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1,
     137                data, len);
     138            wolfSSL_CryptHwMutexUnLock();
    193139        }
    194140        return ret;
     
    197143    int wc_ShaFinal(wc_Sha* sha, byte* hash)
    198144    {
    199         int ret = 0;
    200 
    201         if (sha == NULL || hash == NULL)
     145        int ret;
     146
     147        if (sha == NULL || hash == NULL) {
    202148            return BAD_FUNC_ARG;
    203 
    204     #ifdef WOLFSSL_STM32_CUBEMX
    205         if (HAL_HASH_SHA1_Start(&sha->hashHandle,
    206                 (byte*)sha->buffer, sha->buffLen,
    207                 (byte*)sha->digest, SHA_HW_TIMEOUT) != HAL_OK) {
    208             ret = ASYNC_OP_E;
    209         }
    210         HAL_HASH_DeInit(&sha->hashHandle);
    211     #else
    212         __IO uint16_t nbvalidbitsdata = 0;
    213 
    214         /* finish reading any trailing bytes into FIFO */
    215         if (sha->buffLen > 0) {
    216             HASH_DataIn(*(uint32_t*)sha->buffer);
    217             AddLength(sha, sha->buffLen);
    218         }
    219 
    220         /* calculate number of valid bits in last word of input data */
    221         nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);
    222 
    223         /* configure number of valid bits in last word of the data */
    224         HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
    225 
    226         /* start HASH processor */
    227         HASH_StartDigest();
    228 
    229         /* wait until Busy flag == RESET */
    230         while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
    231 
    232         /* read message digest */
    233         sha->digest[0] = HASH->HR[0];
    234         sha->digest[1] = HASH->HR[1];
    235         sha->digest[2] = HASH->HR[2];
    236         sha->digest[3] = HASH->HR[3];
    237         sha->digest[4] = HASH->HR[4];
    238 
    239         ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE);
    240     #endif /* WOLFSSL_STM32_CUBEMX */
    241 
    242         XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
    243 
    244         (void)wc_InitSha_ex(sha, sha->heap, INVALID_DEVID);  /* reset state */
     149        }
     150
     151        ret = wolfSSL_CryptHwMutexLock();
     152        if (ret == 0) {
     153            ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1,
     154                hash, WC_SHA_DIGEST_SIZE);
     155            wolfSSL_CryptHwMutexUnLock();
     156        }
     157
     158        (void)wc_InitSha(sha);  /* reset state */
    245159
    246160        return ret;
     
    251165
    252166    #include "fsl_ltc.h"
    253     static int InitSha(wc_Sha* sha)
    254     {
     167    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
     168    {
     169        if (sha == NULL) {
     170            return BAD_FUNC_ARG;
     171        }
     172
     173        (void)devId;
     174        (void)heap;
     175
    255176        LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0);
    256177        return 0;
     
    317238    }
    318239
     240#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     241    /* wolfcrypt/src/port/caam/caam_sha.c */
    319242#else
    320243
     
    342265
    343266
    344 #if defined(USE_SHA_SOFTWARE_IMPL) || defined(STM32_HASH)
    345 static INLINE void AddLength(wc_Sha* sha, word32 len)
     267/* Software implementation */
     268#ifdef USE_SHA_SOFTWARE_IMPL
     269
     270static WC_INLINE void AddLength(wc_Sha* sha, word32 len)
    346271{
    347272    word32 tmp = sha->loLen;
     
    349274        sha->hiLen++;                       /* carry low to high */
    350275}
    351 #endif
    352 
    353 
    354 /* Software implementation */
    355 #ifdef USE_SHA_SOFTWARE_IMPL
    356276
    357277/* Check if custom wc_Sha transform is used */
     
    367287    #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
    368288    #define f4(x,y,z) ((x)^(y)^(z))
     289
     290    #ifdef WOLFSSL_NUCLEUS_1_2
     291        /* nucleus.h also defines R1-R4 */
     292        #undef R1
     293        #undef R2
     294        #undef R3
     295        #undef R4
     296    #endif
    369297
    370298    /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
     
    526454}
    527455
     456int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
     457{
     458#ifdef LITTLE_ENDIAN_ORDER
     459    word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)];
     460#endif
     461
     462    if (sha == NULL || hash == NULL) {
     463        return BAD_FUNC_ARG;
     464    }
     465
     466#ifdef LITTLE_ENDIAN_ORDER
     467    ByteReverseWords((word32*)digest, (word32*)sha->digest, WC_SHA_DIGEST_SIZE);
     468    XMEMCPY(hash, digest, WC_SHA_DIGEST_SIZE);
     469#else
     470    XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
     471#endif
     472
     473    return 0;
     474}
     475
    528476int wc_ShaFinal(wc_Sha* sha, byte* hash)
    529477{
     
    606554    wolfAsync_DevCtxFree(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA);
    607555#endif /* WOLFSSL_ASYNC_CRYPT */
     556
     557#ifdef WOLFSSL_PIC32MZ_HASH
     558    wc_ShaPic32Free(sha);
     559#endif
    608560}
    609561
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/sha256.c

    r352 r372  
    2929#include <wolfssl/wolfcrypt/settings.h>
    3030
    31 #if !defined(NO_SHA256)
     31#if !defined(NO_SHA256) && !defined(WOLFSSL_ARMASM)
     32
     33#if defined(HAVE_FIPS) && \
     34        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     35
     36    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     37    #define FIPS_NO_WRAPPERS
     38
     39    #ifdef USE_WINDOWS_API
     40        #pragma code_seg(".fipsA$d")
     41        #pragma const_seg(".fipsB$d")
     42    #endif
     43#endif
    3244
    3345#include <wolfssl/wolfcrypt/sha256.h>
     
    3648
    3749/* fips wrapper calls, user can call direct */
    38 #ifdef HAVE_FIPS
     50#if defined(HAVE_FIPS) && \
     51    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
    3952
    4053    int wc_InitSha256(wc_Sha256* sha)
     
    5972            return BAD_FUNC_ARG;
    6073        }
     74
     75        if (data == NULL && len == 0) {
     76            /* valid, but do nothing */
     77            return 0;
     78        }
     79
    6180        return Sha256Update_fips(sha, data, len);
    6281    }
     
    7493    }
    7594
    76 #else /* else build without fips */
     95#else /* else build without fips, or for FIPS v2 */
    7796
    7897
     
    90109#endif
    91110
     111#ifdef WOLFSSL_DEVCRYPTO_HASH
     112    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
     113#endif
     114
     115
    92116
    93117#if defined(USE_INTEL_SPEEDUP)
     118    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
     119                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
     120        #undef  NO_AVX2_SUPPORT
     121        #define NO_AVX2_SUPPORT
     122    #endif
     123    #if defined(__clang__) && ((__clang_major__ < 3) || \
     124                               (__clang_major__ == 3 && __clang_minor__ <= 5))
     125        #define NO_AVX2_SUPPORT
     126    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
     127        #undef NO_AVX2_SUPPORT
     128    #endif
     129
    94130    #define HAVE_INTEL_AVX1
     131    #ifndef NO_AVX2_SUPPORT
    95132    #define HAVE_INTEL_AVX2
     133    #endif
    96134#endif /* USE_INTEL_SPEEDUP */
    97135
     
    101139
    102140
    103 static INLINE void AddLength(wc_Sha256* sha256, word32 len);
    104 
    105 #if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH)
     141#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \
     142    (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH)) && \
     143    !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH)
    106144static int InitSha256(wc_Sha256* sha256)
    107145{
     
    151189
    152190    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
    153       Transform(); Function prototype
     191      Transform_Sha256(); Function prototype
    154192    #else
    155       Transform() {   }
     193      Transform_Sha256() {   }
    156194      int Sha256Final() {
    157195         Save/Recover XMM, YMM
     
    172210       #define XMM Instructions/inline asm
    173211
    174        int Transform() {
     212       int Transform_Sha256() {
    175213           Stitched Message Sched/Round
    176214        }
     
    180218      #define YMM Instructions/inline asm
    181219
    182       int Transform() {
     220      int Transform_Sha256() {
    183221          More granural Stitched Message Sched/Round
    184222      }
     
    193231
    194232    /* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha256 */
    195     static int Transform(wc_Sha256* sha256);
     233    static int Transform_Sha256(wc_Sha256* sha256);
    196234    #if defined(HAVE_INTEL_AVX1)
    197         static int Transform_AVX1(wc_Sha256 *sha256);
     235        static int Transform_Sha256_AVX1(wc_Sha256 *sha256);
     236        static int Transform_Sha256_AVX1_Len(wc_Sha256* sha256, word32 len);
    198237    #endif
    199238    #if defined(HAVE_INTEL_AVX2)
    200         static int Transform_AVX2(wc_Sha256 *sha256);
    201         static int Transform_AVX1_RORX(wc_Sha256 *sha256);
    202     #endif
    203     static int (*Transform_p)(wc_Sha256* sha256) /* = _Transform */;
     239        static int Transform_Sha256_AVX2(wc_Sha256 *sha256);
     240        static int Transform_Sha256_AVX2_Len(wc_Sha256* sha256, word32 len);
     241        #ifdef HAVE_INTEL_RORX
     242        static int Transform_Sha256_AVX1_RORX(wc_Sha256 *sha256);
     243        static int Transform_Sha256_AVX1_RORX_Len(wc_Sha256* sha256, word32 len);
     244        static int Transform_Sha256_AVX2_RORX(wc_Sha256 *sha256);
     245        static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, word32 len);
     246    #endif
     247    #endif
     248    static int (*Transform_Sha256_p)(wc_Sha256* sha256);
     249                                                       /* = _Transform_Sha256 */
     250    static int (*Transform_Sha256_Len_p)(wc_Sha256* sha256, word32 len);
     251                                                                    /* = NULL */
    204252    static int transform_check = 0;
    205253    static word32 intel_flags;
    206     #define XTRANSFORM(S, B)  (*Transform_p)((S))
     254    #define XTRANSFORM(S)         (*Transform_Sha256_p)((S))
     255    #define XTRANSFORM_LEN(S, L)  (*Transform_Sha256_Len_p)((S),(L))
    207256
    208257    static void Sha256_SetTransform(void)
     
    214263        intel_flags = cpuid_get_flags();
    215264
    216     #if defined(HAVE_INTEL_AVX2)
    217         if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_BMI2(intel_flags)) {
     265    #ifdef HAVE_INTEL_AVX2
     266        if (IS_INTEL_AVX2(intel_flags)) {
     267        #ifdef HAVE_INTEL_RORX
     268            if (IS_INTEL_BMI2(intel_flags)) {
     269                Transform_Sha256_p = Transform_Sha256_AVX2_RORX;
     270                Transform_Sha256_Len_p = Transform_Sha256_AVX2_RORX_Len;
     271            }
     272            else
     273        #endif
    218274            if (1)
    219                 Transform_p = Transform_AVX1_RORX;
    220             else
    221                 Transform_p = Transform_AVX2;
     275            {
     276                Transform_Sha256_p = Transform_Sha256_AVX2;
     277                Transform_Sha256_Len_p = Transform_Sha256_AVX2_Len;
     278            }
     279        #ifdef HAVE_INTEL_RORX
     280            else {
     281                Transform_Sha256_p = Transform_Sha256_AVX1_RORX;
     282                Transform_Sha256_Len_p = Transform_Sha256_AVX1_RORX_Len;
     283            }
     284        #endif
    222285        }
    223286        else
    224287    #endif
    225     #if defined(HAVE_INTEL_AVX1)
    226         if (1) {
    227             Transform_p = ((IS_INTEL_AVX1(intel_flags)) ? Transform_AVX1 :
    228                                                                      Transform);
     288    #ifdef HAVE_INTEL_AVX1
     289        if (IS_INTEL_AVX1(intel_flags)) {
     290            Transform_Sha256_p = Transform_Sha256_AVX1;
     291            Transform_Sha256_Len_p = Transform_Sha256_AVX1_Len;
    229292        }
    230293        else
    231294    #endif
    232             Transform_p = Transform;
     295        {
     296            Transform_Sha256_p = Transform_Sha256;
     297            Transform_Sha256_Len_p = NULL;
     298        }
    233299
    234300        transform_check = 1;
    235301    }
    236 
    237     /* Dummy for saving MM_REGs on behalf of Transform */
    238     #if defined(HAVE_INTEL_AVX2) && !defined(HAVE_INTEL_AVX1)
    239         #define SAVE_XMM_YMM   __asm__ volatile("or %%r8d, %%r8d":::\
    240           "%ymm4","%ymm5","%ymm6","%ymm7","%ymm8","%ymm9","%ymm10","%ymm11","%ymm12","%ymm13","%ymm14","%ymm15")
    241     #elif defined(HAVE_INTEL_AVX1)
    242         #define SAVE_XMM_YMM   __asm__ volatile("or %%r8d, %%r8d":::\
    243             "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10",\
    244             "xmm11","xmm12","xmm13","xmm14","xmm15")
    245     #endif
    246302
    247303    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
     
    289345    #endif
    290346
    291     #define XTRANSFORM(S, B)  Transform((S), (B))
     347    #define XTRANSFORM(S)        Transform_Sha256((S))
     348    #define XTRANSFORM_LEN(S,L)  Transform_Sha256_Len((S),(L))
    292349
    293350    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
     
    316373    }
    317374
    318     static int Transform(wc_Sha256* sha256, byte* buf)
     375    static int Transform_Sha256(wc_Sha256* sha256)
    319376    {
    320377        int ret = wolfSSL_CryptHwMutexLock();
    321378        if (ret == 0) {
    322379    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
    323             cau_sha256_hash_n(buf, 1, sha256->digest);
     380            cau_sha256_hash_n((byte*)sha256->buffer, 1, sha256->digest);
    324381    #else
    325             MMCAU_SHA256_HashN(buf, 1, sha256->digest);
     382            MMCAU_SHA256_HashN((byte*)sha256->buffer, 1, sha256->digest);
    326383    #endif
    327384            wolfSSL_CryptHwMutexUnLock();
     
    333390    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
    334391
    335 #elif defined(STM32_HASH)
    336 
    337     /*
    338      * STM32F2/F4/F7 hardware SHA256 support through the HASH_* API's from the
    339      * Standard Peripheral Library or CubeMX (See note in README).
    340      */
    341 
    342     /* STM32 register size, bytes */
    343     #ifdef WOLFSSL_STM32_CUBEMX
    344         #define SHA256_REG_SIZE  SHA256_BLOCK_SIZE
    345     #else
    346         #define SHA256_REG_SIZE  4
    347         /* STM32 struct notes:
    348          * sha256->buffer  = first 4 bytes used to hold partial block if needed
    349          * sha256->buffLen = num bytes currently stored in sha256->buffer
    350          * sha256->loLen   = num bytes that have been written to STM32 FIFO
    351          */
    352     #endif
    353     #define SHA256_HW_TIMEOUT 0xFF
     392#elif defined(STM32_HASH_SHA2)
     393
     394    /* Supports CubeMX HAL or Standard Peripheral Library */
    354395
    355396    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
     
    358399            return BAD_FUNC_ARG;
    359400
    360         sha256->heap = heap;
    361         XMEMSET(sha256->buffer, 0, sizeof(sha256->buffer));
    362         sha256->buffLen = 0;
    363         sha256->loLen = 0;
    364         sha256->hiLen = 0;
    365 
    366         /* initialize HASH peripheral */
    367     #ifdef WOLFSSL_STM32_CUBEMX
    368         HAL_HASH_DeInit(&sha256->hashHandle);
    369         sha256->hashHandle.Init.DataType = HASH_DATATYPE_8B;
    370         if (HAL_HASH_Init(&sha256->hashHandle) != HAL_OK) {
    371             return ASYNC_INIT_E;
    372         }
    373         /* reset the hash control register */
    374         /* required because Cube MX is not clearing algo bits */
    375         HASH->CR &= ~HASH_CR_ALGO;
    376     #else
    377         HASH_DeInit();
    378 
    379         /* reset the hash control register */
    380         HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
    381 
    382         /* configure algo used, algo mode, datatype */
    383         HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HASH
    384                    | HASH_DataType_8b);
    385 
    386         /* reset HASH processor */
    387         HASH->CR |= HASH_CR_INIT;
    388     #endif
    389 
     401        (void)devId;
     402        (void)heap;
     403
     404        wc_Stm32_Hash_Init(&sha256->stmCtx);
    390405        return 0;
    391406    }
     
    394409    {
    395410        int ret = 0;
    396         byte* local;
    397411
    398412        if (sha256 == NULL || (data == NULL && len > 0)) {
     
    400414        }
    401415
    402         /* do block size increments */
    403         local = (byte*)sha256->buffer;
    404 
    405         /* check that internal buffLen is valid */
    406         if (sha256->buffLen >= SHA256_REG_SIZE)
    407             return BUFFER_E;
    408 
    409         while (len) {
    410             word32 add = min(len, SHA256_REG_SIZE - sha256->buffLen);
    411             XMEMCPY(&local[sha256->buffLen], data, add);
    412 
    413             sha256->buffLen += add;
    414             data            += add;
    415             len             -= add;
    416 
    417             if (sha256->buffLen == SHA256_REG_SIZE) {
    418             #ifdef WOLFSSL_STM32_CUBEMX
    419                 if (HAL_HASHEx_SHA256_Accumulate(
    420                         &sha256->hashHandle, local, SHA256_REG_SIZE) != HAL_OK) {
    421                     ret = ASYNC_OP_E;
    422                 }
    423             #else
    424                 HASH_DataIn(*(uint32_t*)local);
    425             #endif
    426 
    427                 AddLength(sha256, SHA256_REG_SIZE);
    428                 sha256->buffLen = 0;
    429             }
     416        ret = wolfSSL_CryptHwMutexLock();
     417        if (ret == 0) {
     418            ret = wc_Stm32_Hash_Update(&sha256->stmCtx,
     419                HASH_AlgoSelection_SHA256, data, len);
     420            wolfSSL_CryptHwMutexUnLock();
    430421        }
    431422        return ret;
     
    436427        int ret = 0;
    437428
    438         if (sha256 == NULL || hash == NULL)
     429        if (sha256 == NULL || hash == NULL) {
    439430            return BAD_FUNC_ARG;
    440 
    441     #ifdef WOLFSSL_STM32_CUBEMX
    442         if (HAL_HASHEx_SHA256_Start(&sha256->hashHandle,
    443                 (byte*)sha256->buffer, sha256->buffLen,
    444                 (byte*)sha256->digest, SHA256_HW_TIMEOUT) != HAL_OK) {
    445             ret = ASYNC_OP_E;
    446         }
    447     #else
    448         __IO uint16_t nbvalidbitsdata = 0;
    449 
    450         /* finish reading any trailing bytes into FIFO */
    451         if (sha256->buffLen > 0) {
    452             HASH_DataIn(*(uint32_t*)sha256->buffer);
    453             AddLength(sha256, sha256->buffLen);
    454         }
    455 
    456         /* calculate number of valid bits in last word of input data */
    457         nbvalidbitsdata = 8 * (sha256->loLen % SHA256_REG_SIZE);
    458 
    459         /* configure number of valid bits in last word of the data */
    460         HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
    461 
    462         /* start HASH processor */
    463         HASH_StartDigest();
    464 
    465         /* wait until Busy flag == RESET */
    466         while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
    467 
    468         /* read message digest */
    469         sha256->digest[0] = HASH->HR[0];
    470         sha256->digest[1] = HASH->HR[1];
    471         sha256->digest[2] = HASH->HR[2];
    472         sha256->digest[3] = HASH->HR[3];
    473         sha256->digest[4] = HASH->HR[4];
    474         sha256->digest[5] = HASH_DIGEST->HR[5];
    475         sha256->digest[6] = HASH_DIGEST->HR[6];
    476         sha256->digest[7] = HASH_DIGEST->HR[7];
    477 
    478         ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
    479     #endif /* WOLFSSL_STM32_CUBEMX */
    480 
    481         XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE);
    482 
    483         (void)wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID);
     431        }
     432
     433        ret = wolfSSL_CryptHwMutexLock();
     434        if (ret == 0) {
     435            ret = wc_Stm32_Hash_Final(&sha256->stmCtx,
     436                HASH_AlgoSelection_SHA256, hash, WC_SHA256_DIGEST_SIZE);
     437            wolfSSL_CryptHwMutexUnLock();
     438        }
     439
     440        (void)wc_InitSha256(sha256); /* reset state */
    484441
    485442        return ret;
    486443    }
     444
     445#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     446    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
     447
     448#elif defined(WOLFSSL_AFALG_HASH)
     449    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
     450
     451#elif defined(WOLFSSL_DEVCRYPTO_HASH)
     452    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
    487453
    488454#else
     
    500466        if (ret != 0)
    501467            return ret;
     468
     469    #ifdef WOLFSSL_SMALL_STACK_CACHE
     470        sha256->W = NULL;
     471    #endif
    502472
    503473    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
     
    511481    }
    512482#endif /* End Hardware Acceleration */
    513 
    514 #ifndef SAVE_XMM_YMM
    515     #define SAVE_XMM_YMM
    516 #endif
    517483
    518484#ifdef NEED_SOFT_SHA256
     
    544510    #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
    545511
    546     #define RND(a,b,c,d,e,f,g,h,i) \
    547          t0 = (h) + Sigma1((e)) + Ch((e), (f), (g)) + K[(i)] + W[(i)]; \
    548          t1 = Sigma0((a)) + Maj((a), (b), (c)); \
    549          (d) += t0; \
    550          (h)  = t0 + t1;
     512    #define a(i) S[(0-i) & 7]
     513    #define b(i) S[(1-i) & 7]
     514    #define c(i) S[(2-i) & 7]
     515    #define d(i) S[(3-i) & 7]
     516    #define e(i) S[(4-i) & 7]
     517    #define f(i) S[(5-i) & 7]
     518    #define g(i) S[(6-i) & 7]
     519    #define h(i) S[(7-i) & 7]
     520
     521    #define RND(j) \
     522         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + W[i+j]; \
     523         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
     524         d(j) += t0; \
     525         h(j)  = t0 + t1
    551526
    552527    #ifndef XTRANSFORM
    553          #define XTRANSFORM(S, B) Transform((S))
     528         #define XTRANSFORM(S)        Transform_Sha256((S))
     529         #define XTRANSFORM_LEN(S,L)  Transform_Sha256_Len((S),(L))
    554530     #endif
    555531
    556     static int Transform(wc_Sha256* sha256)
     532    static int Transform_Sha256(wc_Sha256* sha256)
    557533    {
    558534        word32 S[8], t0, t1;
    559535        int i;
    560536
    561     #ifdef WOLFSSL_SMALL_STACK
     537    #ifdef WOLFSSL_SMALL_STACK_CACHE
     538        word32* W = sha256->W;
     539        if (W == NULL) {
     540            W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,
     541                                                           DYNAMIC_TYPE_DIGEST);
     542            if (W == NULL)
     543                return MEMORY_E;
     544            sha256->W = W;
     545        }
     546    #elif defined(WOLFSSL_SMALL_STACK)
    562547        word32* W;
    563 
    564548        W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,
    565549            DYNAMIC_TYPE_TMP_BUFFER);
     
    580564            W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
    581565
     566    #ifdef USE_SLOW_SHA256
     567        /* not unrolled - ~2k smaller and ~25% slower */
    582568        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
    583             RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
    584             RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
    585             RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
    586             RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
    587             RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
    588             RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
    589             RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
    590             RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
    591         }
     569            int j;
     570            for (j = 0; j < 8; j++) { /* braces needed here for macros {} */
     571                RND(j);
     572            }
     573        }
     574    #else
     575        /* partially loop unrolled */
     576        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
     577            RND(0); RND(1); RND(2); RND(3);
     578            RND(4); RND(5); RND(6); RND(7);
     579        }
     580    #endif /* USE_SLOW_SHA256 */
    592581
    593582        /* Add the working vars back into digest state[] */
     
    596585        }
    597586
    598     #ifdef WOLFSSL_SMALL_STACK
     587    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
    599588        XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    600589    #endif
    601 
    602590        return 0;
    603591    }
     
    606594
    607595
    608 #if defined(XTRANSFORM) || defined(STM32_HASH)
    609 static INLINE void AddLength(wc_Sha256* sha256, word32 len)
     596#ifdef XTRANSFORM
     597
     598    static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
    610599{
    611600    word32 tmp = sha256->loLen;
     
    613602        sha256->hiLen++;                       /* carry low to high */
    614603}
    615 #endif
    616 
    617 
    618 #ifdef XTRANSFORM
    619 
    620     static INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
     604
     605    static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
    621606    {
    622607        int ret = 0;
     
    625610        if (sha256 == NULL || (data == NULL && len > 0)) {
    626611            return BAD_FUNC_ARG;
     612        }
     613
     614        if (data == NULL && len == 0) {
     615            /* valid, but do nothing */
     616            return 0;
    627617        }
    628618
     
    642632            return BUFFER_E;
    643633
    644         SAVE_XMM_YMM; /* for Intel AVX */
    645 
    646         while (len) {
     634        if (sha256->buffLen > 0) {
    647635            word32 add = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen);
    648636            XMEMCPY(&local[sha256->buffLen], data, add);
     
    662650                }
    663651        #endif
    664                 ret = XTRANSFORM(sha256, local);
    665                 if (ret != 0) {
     652                ret = XTRANSFORM(sha256);
     653                if (ret == 0) {
     654                    AddLength(sha256, WC_SHA256_BLOCK_SIZE);
     655                    sha256->buffLen = 0;
     656                }
     657                else
     658                    len = 0;
     659            }
     660        }
     661
     662    #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     663        if (Transform_Sha256_Len_p != NULL) {
     664            word32 blocksLen = len & ~(WC_SHA256_BLOCK_SIZE-1);
     665
     666            if (blocksLen > 0) {
     667                AddLength(sha256, blocksLen);
     668                sha256->data = data;
     669                /* Byte reversal performed in function if required. */
     670                XTRANSFORM_LEN(sha256, blocksLen);
     671                data += blocksLen;
     672                len  -= blocksLen;
     673            }
     674        }
     675        else
     676    #endif
     677    #if !defined(LITTLE_ENDIAN_ORDER) || defined(FREESCALE_MMCAU_SHA) || \
     678                            defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     679        {
     680            word32 blocksLen = len & ~(WC_SHA256_BLOCK_SIZE-1);
     681
     682            AddLength(sha256, blocksLen);
     683            while (len >= WC_SHA256_BLOCK_SIZE) {
     684                XMEMCPY(local, data, WC_SHA256_BLOCK_SIZE);
     685
     686                data += WC_SHA256_BLOCK_SIZE;
     687                len  -= WC_SHA256_BLOCK_SIZE;
     688
     689                /* Byte reversal performed in function if required. */
     690                ret = XTRANSFORM(sha256);
     691                if (ret != 0)
    666692                    break;
    667693                }
    668 
    669                 AddLength(sha256, WC_SHA256_BLOCK_SIZE);
    670                 sha256->buffLen = 0;
     694        }
     695    #else
     696        {
     697            word32 blocksLen = len & ~(WC_SHA256_BLOCK_SIZE-1);
     698
     699            AddLength(sha256, blocksLen);
     700            while (len >= WC_SHA256_BLOCK_SIZE) {
     701                XMEMCPY(local, data, WC_SHA256_BLOCK_SIZE);
     702
     703                data += WC_SHA256_BLOCK_SIZE;
     704                len  -= WC_SHA256_BLOCK_SIZE;
     705
     706                ByteReverseWords(sha256->buffer, sha256->buffer,
     707                                                          WC_SHA256_BLOCK_SIZE);
     708                ret = XTRANSFORM(sha256);
     709                if (ret != 0)
     710                    break;
    671711            }
     712            }
     713    #endif
     714
     715        if (len > 0) {
     716            XMEMCPY(local, data, len);
     717            sha256->buffLen = len;
    672718        }
    673719
     
    680726    }
    681727
    682     static INLINE int Sha256Final(wc_Sha256* sha256)
     728    static WC_INLINE int Sha256Final(wc_Sha256* sha256)
    683729    {
    684730
     
    689735            return BAD_FUNC_ARG;
    690736        }
    691 
    692         SAVE_XMM_YMM; /* for Intel AVX */
    693737
    694738        AddLength(sha256, sha256->buffLen);  /* before adding pads */
     
    713757            }
    714758
    715             ret = XTRANSFORM(sha256, local);
     759            ret = XTRANSFORM(sha256);
    716760            if (ret != 0)
    717761                return ret;
     
    755799    #endif
    756800
    757         return XTRANSFORM(sha256, local);
     801        return XTRANSFORM(sha256);
     802    }
     803
     804    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
     805    {
     806    #ifdef LITTLE_ENDIAN_ORDER
     807        word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
     808    #endif
     809
     810        if (sha256 == NULL || hash == NULL) {
     811            return BAD_FUNC_ARG;
     812        }
     813
     814    #ifdef LITTLE_ENDIAN_ORDER
     815        ByteReverseWords((word32*)digest, (word32*)sha256->digest,
     816                                                         WC_SHA256_DIGEST_SIZE);
     817        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
     818    #else
     819        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
     820    #endif
     821
     822        return 0;
    758823    }
    759824
     
    792857#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
    793858
    794 #define _DigestToReg(S0, S1, S2, S3, S4, S5, S6, S7) \
    795     "leaq       %[digest], %%r8\n\t"                 \
    796     "movl         (%%r8), %"#S0"\n\t"                \
    797     "movl        4(%%r8), %"#S1"\n\t"                \
    798     "movl        8(%%r8), %"#S2"\n\t"                \
    799     "movl       12(%%r8), %"#S3"\n\t"                \
    800     "movl       16(%%r8), %"#S4"\n\t"                \
    801     "movl       20(%%r8), %"#S5"\n\t"                \
    802     "movl       24(%%r8), %"#S6"\n\t"                \
    803     "movl       28(%%r8), %"#S7"\n\t"
    804 
    805 #define _RegToDigest(S0, S1, S2, S3, S4, S5, S6, S7) \
    806     "leaq       %[digest], %%r8\n\t"                 \
    807     "addl %"#S0",   (%%r8)\n\t"                      \
    808     "addl %"#S1",  4(%%r8)\n\t"                      \
    809     "addl %"#S2",  8(%%r8)\n\t"                      \
    810     "addl %"#S3", 12(%%r8)\n\t"                      \
    811     "addl %"#S4", 16(%%r8)\n\t"                      \
    812     "addl %"#S5", 20(%%r8)\n\t"                      \
    813     "addl %"#S6", 24(%%r8)\n\t"                      \
    814     "addl %"#S7", 28(%%r8)\n\t"
    815 
    816 #define DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    817     _DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
    818 
    819 #define RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    820     _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
    821 
    822 
    823 #define S_0 %r15d
    824 #define S_1 %r10d
    825 #define S_2 %r11d
    826 #define S_3 %r12d
    827 #define S_4 %r13d
    828 #define S_5 %r14d
    829 #define S_6 %ebx
    830 #define S_7 %r9d
    831 
    832 #define SSE_REGs "%edi", "%esi", "%edx", "%ebx","%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15"
     859#define _LOAD_DIGEST()                     \
     860    "movl         (%[sha256]), %%r8d \n\t" \
     861    "movl        4(%[sha256]), %%r9d \n\t" \
     862    "movl        8(%[sha256]), %%r10d\n\t" \
     863    "movl       12(%[sha256]), %%r11d\n\t" \
     864    "movl       16(%[sha256]), %%r12d\n\t" \
     865    "movl       20(%[sha256]), %%r13d\n\t" \
     866    "movl       24(%[sha256]), %%r14d\n\t" \
     867    "movl       28(%[sha256]), %%r15d\n\t"
     868
     869#define _STORE_ADD_DIGEST()                \
     870    "addl       %%r8d ,   (%[sha256])\n\t" \
     871    "addl       %%r9d ,  4(%[sha256])\n\t" \
     872    "addl       %%r10d,  8(%[sha256])\n\t" \
     873    "addl       %%r11d, 12(%[sha256])\n\t" \
     874    "addl       %%r12d, 16(%[sha256])\n\t" \
     875    "addl       %%r13d, 20(%[sha256])\n\t" \
     876    "addl       %%r14d, 24(%[sha256])\n\t" \
     877    "addl       %%r15d, 28(%[sha256])\n\t"
     878
     879#define _ADD_DIGEST()                      \
     880    "addl         (%[sha256]), %%r8d \n\t" \
     881    "addl        4(%[sha256]), %%r9d \n\t" \
     882    "addl        8(%[sha256]), %%r10d\n\t" \
     883    "addl       12(%[sha256]), %%r11d\n\t" \
     884    "addl       16(%[sha256]), %%r12d\n\t" \
     885    "addl       20(%[sha256]), %%r13d\n\t" \
     886    "addl       24(%[sha256]), %%r14d\n\t" \
     887    "addl       28(%[sha256]), %%r15d\n\t"
     888
     889#define _STORE_DIGEST()                    \
     890    "movl       %%r8d ,   (%[sha256])\n\t" \
     891    "movl       %%r9d ,  4(%[sha256])\n\t" \
     892    "movl       %%r10d,  8(%[sha256])\n\t" \
     893    "movl       %%r11d, 12(%[sha256])\n\t" \
     894    "movl       %%r12d, 16(%[sha256])\n\t" \
     895    "movl       %%r13d, 20(%[sha256])\n\t" \
     896    "movl       %%r14d, 24(%[sha256])\n\t" \
     897    "movl       %%r15d, 28(%[sha256])\n\t"
     898
     899#define LOAD_DIGEST() \
     900    _LOAD_DIGEST()
     901
     902#define STORE_ADD_DIGEST() \
     903    _STORE_ADD_DIGEST()
     904
     905#define ADD_DIGEST() \
     906    _ADD_DIGEST()
     907
     908#define STORE_DIGEST() \
     909    _STORE_DIGEST()
     910
     911
     912#define S_0 %r8d
     913#define S_1 %r9d
     914#define S_2 %r10d
     915#define S_3 %r11d
     916#define S_4 %r12d
     917#define S_5 %r13d
     918#define S_6 %r14d
     919#define S_7 %r15d
     920
     921#define L1  "%%edx"
     922#define L2  "%%ecx"
     923#define L3  "%%eax"
     924#define L4  "%%ebx"
     925#define WK  "%%rsp"
     926
     927#define WORK_REGS  "eax", "ebx", "ecx", "edx"
     928#define STATE_REGS "r8","r9","r10","r11","r12","r13","r14","r15"
     929#define XMM_REGS   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6",    \
     930                   "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13"
    833931
    834932#if defined(HAVE_INTEL_RORX)
    835 #define RND_STEP_RORX_1(a,b,c,d,e,f,g,h,i) \
    836     "# edx = e>>>6\n\t"                    \
    837     "rorx       $6, %"#e", %%edx\n\t"
    838 
    839 #define RND_STEP_RORX_2(a,b,c,d,e,f,g,h,i) \
    840     "# edi = e>>>11\n\t"                   \
    841     "rorx       $11, %"#e",%%edi\n\t"      \
    842     "# edi = (e>>11) ^ (e>>6)\n\t"         \
    843     "xorl       %%edx, %%edi\n\t"          \
    844     "# edx = e>>>25\n\t"                   \
    845     "rorx       $25, %"#e", %%edx\n\t"
    846 
    847 #define RND_STEP_RORX_3(a,b,c,d,e,f,g,h,i) \
    848     "# esi = f\n\t"                        \
    849     "movl       %"#f", %%esi\n\t"          \
    850     "# esi = f ^ g\n\t"                    \
    851     "xorl       %"#g", %%esi\n\t"          \
    852     "# edx = Sigma1(e)\n\t"                \
    853     "xorl       %%edi, %%edx\n\t"          \
    854     "# esi = (f ^ g) & e\n\t"              \
    855     "andl       %"#e", %%esi\n\t"          \
    856     "# esi = Ch(e,f,g)\n\t"                \
    857     "xorl       %"#g", %%esi\n\t"
    858 
    859 #define RND_STEP_RORX_4(a,b,c,d,e,f,g,h,i) \
    860     "# h += w_k\n\t"                       \
    861     "leaq       %[W_K], %%r8\n\t"          \
    862     "addl       ("#i")*4(%%r8), %"#h"\n\t" \
    863     "# h = h + w_k + Sigma1(e)\n\t"        \
    864     "addl       %%edx, %"#h"\n\t"          \
    865     "# r8d = a>>>2\n\t"                    \
    866     "rorx       $2, %"#a", %%r8d\n\t"      \
    867     "# edi = a>>>13\n\t"                   \
    868     "rorx       $13, %"#a", %%edi\n\t"
    869 
    870 #define RND_STEP_RORX_5(a,b,c,d,e,f,g,h,i) \
    871     "# edx = a>>22\n\t"                    \
    872     "rorx       $22, %"#a", %%edx\n\t"     \
    873     "# edi = (a>>>2) ^ (a>>>13)\n\t"       \
    874     "xorl       %%r8d, %%edi\n\t"          \
    875     "# edx = Sigma0(a)\n\t"                \
    876     "xorl       %%edi, %%edx\n\t"
    877 
    878 #define RND_STEP_RORX_6(a,b,c,d,e,f,g,h,i) \
    879     "# edi = b\n\t"                        \
    880     "movl       %"#b", %%edi\n\t"          \
    881     "# edi = a | b\n\t"                    \
    882     "orl        %"#a", %%edi\n\t"          \
    883     "# edi = (a | b) & c\n\t"              \
    884     "andl       %"#c", %%edi\n\t"          \
    885     "# r8d = b\n\t"                        \
    886     "movl       %"#b", %%r8d\n\t"
    887 
    888 #define RND_STEP_RORX_7(a,b,c,d,e,f,g,h,i) \
    889     "# h += Ch(e,f,g)\n\t"                 \
    890     "addl       %%esi, %"#h"\n\t"          \
    891     "# r8d = b & a\n\t"                    \
    892     "andl       %"#a", %%r8d\n\t"          \
    893     "# r8d = Maj(a,b,c)\n\t"               \
    894     "orl        %%edi, %%r8d\n\t"
    895 
    896 #define RND_STEP_RORX_8(a,b,c,d,e,f,g,h,i)       \
    897     "# d += h + w_k + Sigma1(e) + Ch(e,f,g)\n\t" \
     933#define RND_STEP_RORX_0_1(a, b, c, d, e, f, g, h, i) \
     934    /* L3 = f */                                     \
     935    "movl       %" #f ", " L3 "\n\t"                 \
     936    /* L2 = e>>>11 */                                \
     937    "rorx       $11, %" #e ", " L2 "\n\t"            \
     938    /* h += w_k */                                   \
     939    "addl       (" #i ")*4(" WK "), %" #h "\n\t"     \
     940
     941#define RND_STEP_RORX_0_2(a, b, c, d, e, f, g, h, i) \
     942    /* L2 = (e>>>6) ^ (e>>>11) */                    \
     943    "xorl       " L1 ", " L2 "\n\t"                  \
     944    /* L3 = f ^ g */                                 \
     945    "xorl       %" #g ", " L3 "\n\t"                 \
     946    /* L1 = e>>>25 */                                \
     947    "rorx       $25, %" #e ", " L1 "\n\t"            \
     948
     949#define RND_STEP_RORX_0_3(a, b, c, d, e, f, g, h, i) \
     950    /* L3 = (f ^ g) & e */                           \
     951    "andl       %" #e ", " L3 "\n\t"                 \
     952    /* L1 = Sigma1(e) */                             \
     953    "xorl       " L2 ", " L1 "\n\t"                  \
     954    /* L2 = a>>>13 */                                \
     955    "rorx       $13, %" #a ", " L2 "\n\t"            \
     956
     957#define RND_STEP_RORX_0_4(a, b, c, d, e, f, g, h, i) \
     958    /* h += Sigma1(e) */                             \
     959    "addl       " L1 ", %" #h "\n\t"                 \
     960    /* L1 = a>>>2 */                                 \
     961    "rorx       $2, %" #a ", " L1 "\n\t"             \
     962    /* L3 = Ch(e,f,g) */                             \
     963    "xorl       %" #g ", " L3 "\n\t"                 \
     964
     965#define RND_STEP_RORX_0_5(a, b, c, d, e, f, g, h, i) \
     966    /* L2 = (a>>>2) ^ (a>>>13) */                    \
     967    "xorl       " L1 ", " L2 "\n\t"                  \
     968    /* L1 = a>>>22 */                                \
     969    "rorx       $22, %" #a ", " L1 "\n\t"            \
     970    /* h += Ch(e,f,g) */                             \
     971    "addl       " L3 ", %" #h "\n\t"                 \
     972
     973#define RND_STEP_RORX_0_6(a, b, c, d, e, f, g, h, i) \
     974    /* L1 = Sigma0(a) */                             \
     975    "xorl       " L2 ", " L1 "\n\t"                  \
     976    /* L3 = b */                                     \
     977    "movl       %" #b ", " L3 "\n\t"                 \
     978    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */       \
     979    "addl       %" #h ", %" #d "\n\t"                \
     980
     981#define RND_STEP_RORX_0_7(a, b, c, d, e, f, g, h, i) \
     982    /* L3 = a ^ b */                                 \
     983    "xorl       %" #a ", " L3 "\n\t"                 \
     984    /* h += Sigma0(a) */                             \
     985    "addl       " L1 ", %" #h "\n\t"                 \
     986    /* L4 = (a ^ b) & (b ^ c) */                     \
     987    "andl       " L3 ", " L4 "\n\t"                  \
     988
     989#define RND_STEP_RORX_0_8(a, b, c, d, e, f, g, h, i) \
     990    /* L4 = Maj(a,b,c) */                            \
     991    "xorl       %" #b ", " L4 "\n\t"                 \
     992    /* L1 = d>>>6 (= e>>>6 next RND) */              \
     993    "rorx       $6, %" #d ", " L1 "\n\t"             \
     994    /* h += Maj(a,b,c) */                            \
     995    "addl       " L4 ", %" #h "\n\t"                 \
     996
     997#define RND_STEP_RORX_1_1(a, b, c, d, e, f, g, h, i) \
     998    /* L4 = f */                                     \
     999    "movl       %" #f ", " L4 "\n\t"                 \
     1000    /* L2 = e>>>11 */                                \
     1001    "rorx       $11, %" #e ", " L2 "\n\t"            \
     1002    /* h += w_k */                                   \
     1003    "addl       (" #i ")*4(" WK "), %" #h "\n\t"     \
     1004
     1005#define RND_STEP_RORX_1_2(a, b, c, d, e, f, g, h, i) \
     1006    /* L2 = (e>>>6) ^ (e>>>11) */                    \
     1007    "xorl       " L1 ", " L2 "\n\t"                  \
     1008    /* L4 = f ^ g */                                 \
     1009    "xorl       %" #g ", " L4 "\n\t"                 \
     1010    /* L1 = e>>>25 */                                \
     1011    "rorx       $25, %" #e ", " L1 "\n\t"            \
     1012
     1013#define RND_STEP_RORX_1_3(a, b, c, d, e, f, g, h, i) \
     1014    /* L4 = (f ^ g) & e */                           \
     1015    "andl       %" #e ", " L4 "\n\t"                 \
     1016    /* L1 = Sigma1(e) */                             \
     1017    "xorl       " L2 ", " L1 "\n\t"                  \
     1018    /* L2 = a>>>13 */                                \
     1019    "rorx       $13, %" #a ", " L2 "\n\t"            \
     1020
     1021#define RND_STEP_RORX_1_4(a, b, c, d, e, f, g, h, i) \
     1022    /* h += Sigma1(e) */                             \
     1023    "addl       " L1 ", %" #h "\n\t"                 \
     1024    /* L1 = a>>>2 */                                 \
     1025    "rorx       $2, %" #a ", " L1 "\n\t"             \
     1026    /* L4 = Ch(e,f,g) */                             \
     1027    "xorl       %" #g ", " L4 "\n\t"                 \
     1028
     1029#define RND_STEP_RORX_1_5(a, b, c, d, e, f, g, h, i) \
     1030    /* L2 = (a>>>2) ^ (a>>>13) */                    \
     1031    "xorl       " L1 ", " L2 "\n\t"                  \
     1032    /* L1 = a>>>22 */                                \
     1033    "rorx       $22, %" #a ", " L1 "\n\t"            \
     1034    /* h += Ch(e,f,g) */                             \
     1035    "addl       " L4 ", %" #h "\n\t"                 \
     1036
     1037#define RND_STEP_RORX_1_6(a, b, c, d, e, f, g, h, i) \
     1038    /* L1 = Sigma0(a) */                             \
     1039    "xorl       " L2 ", " L1 "\n\t"                  \
     1040    /* L4 = b */                                     \
     1041    "movl       %" #b ", " L4 "\n\t"                 \
     1042    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */       \
    8981043    "addl       %"#h", %"#d"\n\t"                \
    899     "addl       %"#h", %%r8d\n\t"                \
    900     "addl       %%edx, %%r8d\n\t"                \
    901     "movl       %%r8d, %"#h"\n\t"
     1044
     1045#define RND_STEP_RORX_1_7(a, b, c, d, e, f, g, h, i) \
     1046    /* L4 = a ^ b */                                 \
     1047    "xorl       %" #a ", " L4 "\n\t"                 \
     1048    /* h += Sigma0(a) */                             \
     1049    "addl       " L1 ", %" #h "\n\t"                 \
     1050    /* L3 = (a ^ b) & (b ^ c) */                     \
     1051    "andl       " L4 ", " L3 "\n\t"                  \
     1052
     1053#define RND_STEP_RORX_1_8(a, b, c, d, e, f, g, h, i) \
     1054    /* L3 = Maj(a,b,c) */                            \
     1055    "xorl       %" #b ", " L3 "\n\t"                 \
     1056    /* L1 = d>>>6 (= e>>>6 next RND) */              \
     1057    "rorx       $6, %" #d ", " L1 "\n\t"             \
     1058    /* h += Maj(a,b,c) */                            \
     1059    "addl       " L3 ", %" #h "\n\t"                 \
     1060
     1061#define _RND_RORX_X_0(a, b, c, d, e, f, g, h, i)     \
     1062    /* L1 = e>>>6 */                                 \
     1063    "rorx       $6, %" #e ", " L1 "\n\t"             \
     1064    /* L2 = e>>>11 */                                \
     1065    "rorx       $11, %" #e ", " L2 "\n\t"            \
     1066    /* Prev RND: h += Maj(a,b,c) */                  \
     1067    "addl       " L3 ", %" #a "\n\t"                 \
     1068    /* h += w_k */                                   \
     1069    "addl       (" #i ")*4(" WK "), %" #h "\n\t"     \
     1070    /* L3 = f */                                     \
     1071    "movl       %" #f ", " L3 "\n\t"                 \
     1072    /* L2 = (e>>>6) ^ (e>>>11) */                    \
     1073    "xorl       " L1 ", " L2 "\n\t"                  \
     1074    /* L3 = f ^ g */                                 \
     1075    "xorl       %" #g ", " L3 "\n\t"                 \
     1076    /* L1 = e>>>25 */                                \
     1077    "rorx       $25, %" #e ", " L1 "\n\t"            \
     1078    /* L1 = Sigma1(e) */                             \
     1079    "xorl       " L2 ", " L1 "\n\t"                  \
     1080    /* L3 = (f ^ g) & e */                           \
     1081    "andl       %" #e ", " L3 "\n\t"                 \
     1082    /* h += Sigma1(e) */                             \
     1083    "addl       " L1 ", %" #h "\n\t"                 \
     1084    /* L1 = a>>>2 */                                 \
     1085    "rorx       $2, %" #a ", " L1 "\n\t"             \
     1086    /* L2 = a>>>13 */                                \
     1087    "rorx       $13, %" #a ", " L2 "\n\t"            \
     1088    /* L3 = Ch(e,f,g) */                             \
     1089    "xorl       %" #g ", " L3 "\n\t"                 \
     1090    /* L2 = (a>>>2) ^ (a>>>13) */                    \
     1091    "xorl       " L1 ", " L2 "\n\t"                  \
     1092    /* L1 = a>>>22 */                                \
     1093    "rorx       $22, %" #a ", " L1 "\n\t"            \
     1094    /* h += Ch(e,f,g) */                             \
     1095    "addl       " L3 ", %" #h "\n\t"                 \
     1096    /* L1 = Sigma0(a) */                             \
     1097    "xorl       " L2 ", " L1 "\n\t"                  \
     1098    /* L3 = b */                                     \
     1099    "movl       %" #b ", " L3 "\n\t"                 \
     1100    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */       \
     1101    "addl       %" #h ", %" #d "\n\t"                \
     1102    /* L3 = a ^ b */                                 \
     1103    "xorl       %" #a ", " L3 "\n\t"                 \
     1104    /* L4 = (a ^ b) & (b ^ c) */                     \
     1105    "andl       " L3 ", " L4 "\n\t"                  \
     1106    /* h += Sigma0(a) */                             \
     1107    "addl       " L1 ", %" #h "\n\t"                 \
     1108    /* L4 = Maj(a,b,c) */                            \
     1109    "xorl       %" #b ", " L4 "\n\t"                 \
     1110
     1111#define _RND_RORX_X_1(a, b, c, d, e, f, g, h, i)     \
     1112    /* L1 = e>>>6 */                                 \
     1113    "rorx       $6, %" #e ", " L1 "\n\t"             \
     1114    /* L2 = e>>>11 */                                \
     1115    "rorx       $11, %" #e ", " L2 "\n\t"            \
     1116    /* Prev RND: h += Maj(a,b,c) */                  \
     1117    "addl       " L4 ", %" #a "\n\t"                 \
     1118    /* h += w_k */                                   \
     1119    "addl       (" #i ")*4(" WK "), %" #h "\n\t"     \
     1120    /* L4 = f */                                     \
     1121    "movl       %" #f ", " L4 "\n\t"                 \
     1122    /* L2 = (e>>>6) ^ (e>>>11) */                    \
     1123    "xorl       " L1 ", " L2 "\n\t"                  \
     1124    /* L4 = f ^ g */                                 \
     1125    "xorl       %" #g ", " L4 "\n\t"                 \
     1126    /* L1 = e>>>25 */                                \
     1127    "rorx       $25, %" #e ", " L1 "\n\t"            \
     1128    /* L1 = Sigma1(e) */                             \
     1129    "xorl       " L2 ", " L1 "\n\t"                  \
     1130    /* L4 = (f ^ g) & e */                           \
     1131    "andl       %" #e ", " L4 "\n\t"                 \
     1132    /* h += Sigma1(e) */                             \
     1133    "addl       " L1 ", %" #h "\n\t"                 \
     1134    /* L1 = a>>>2 */                                 \
     1135    "rorx       $2, %" #a ", " L1 "\n\t"             \
     1136    /* L2 = a>>>13 */                                \
     1137    "rorx       $13, %" #a ", " L2 "\n\t"            \
     1138    /* L4 = Ch(e,f,g) */                             \
     1139    "xorl       %" #g ", " L4 "\n\t"                 \
     1140    /* L2 = (a>>>2) ^ (a>>>13) */                    \
     1141    "xorl       " L1 ", " L2 "\n\t"                  \
     1142    /* L1 = a>>>22 */                                \
     1143    "rorx       $22, %" #a ", " L1 "\n\t"            \
     1144    /* h += Ch(e,f,g) */                             \
     1145    "addl       " L4 ", %" #h "\n\t"                 \
     1146    /* L1 = Sigma0(a) */                             \
     1147    "xorl       " L2 ", " L1 "\n\t"                  \
     1148    /* L4 = b */                                     \
     1149    "movl       %" #b ", " L4 "\n\t"                 \
     1150    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */       \
     1151    "addl       %" #h ", %" #d "\n\t"                \
     1152    /* L4 = a ^ b */                                 \
     1153    "xorl       %" #a ", " L4 "\n\t"                 \
     1154    /* L2 = (a ^ b) & (b ^ c) */                     \
     1155    "andl       " L4 ", " L3 "\n\t"                  \
     1156    /* h += Sigma0(a) */                             \
     1157    "addl       " L1 ", %" #h "\n\t"                 \
     1158    /* L3 = Maj(a,b,c) */                            \
     1159    "xorl       %" #b ", " L3 "\n\t"                 \
     1160
     1161
     1162#define RND_RORX_X_0(a,b,c,d,e,f,g,h,i) \
     1163       _RND_RORX_X_0(a,b,c,d,e,f,g,h,i)
     1164#define RND_RORX_X_1(a,b,c,d,e,f,g,h,i) \
     1165       _RND_RORX_X_1(a,b,c,d,e,f,g,h,i)
     1166
     1167#define RND_RORX_X4(a,b,c,d,e,f,g,h,i)    \
     1168        RND_RORX_X_0(a,b,c,d,e,f,g,h,i+0) \
     1169        RND_RORX_X_1(h,a,b,c,d,e,f,g,i+1) \
     1170        RND_RORX_X_0(g,h,a,b,c,d,e,f,i+2) \
     1171        RND_RORX_X_1(f,g,h,a,b,c,d,e,i+3)
     1172
    9021173#endif /* HAVE_INTEL_RORX */
    9031174
    904 #define RND_STEP_1(a,b,c,d,e,f,g,h,i) \
    905     "movl       %"#e", %%edx\n\t"     \
    906     "# edx = e>>>6\n\t"               \
    907     "roll       $26, %%edx\n\t"       \
    908     "movl       %"#e", %%edi\n\t"
    909 
    910 #define RND_STEP_2(a,b,c,d,e,f,g,h,i) \
    911     "# edi = e>>>11\n\t"              \
    912     "roll       $21, %%edi\n\t"       \
    913     "# edi = (e>>11) ^ (e>>6)\n\t"    \
    914     "xorl       %%edx, %%edi\n\t"     \
    915     "# edx = e\n\t"                   \
    916     "movl       %"#e", %%edx\n\t"     \
    917     "# edx = e>>>25\n\t"              \
    918     "roll       $7, %%edx\n\t"
    919 
    920 #define RND_STEP_3(a,b,c,d,e,f,g,h,i) \
    921     "# esi = f\n\t"                   \
    922     "movl       %"#f", %%esi\n\t"     \
    923     "# esi = f ^ g\n\t"               \
    924     "xorl       %"#g", %%esi\n\t"     \
    925     "# edx = Sigma1(e)\n\t"           \
    926     "xorl       %%edi, %%edx\n\t"     \
    927     "# esi = (f ^ g) & e\n\t"         \
    928     "andl       %"#e", %%esi\n\t"     \
    929     "# esi = Ch(e,f,g)\n\t"           \
    930     "xorl       %"#g", %%esi\n\t"
    931 
    932 #define RND_STEP_4(a,b,c,d,e,f,g,h,i)      \
    933     "# h += w_k\n\t"                       \
    934     "leaq       %[W_K], %%r8\n\t"          \
    935     "addl       ("#i")*4(%%r8), %"#h"\n\t" \
    936     "# h = h + w_k + Sigma1(e)\n\t"        \
    937     "addl       %%edx, %"#h"\n\t"          \
    938     "# r8d = a\n\t"                        \
    939     "movl       %"#a", %%r8d\n\t"          \
    940     "# r8d = a>>>2\n\t"                    \
    941     "roll       $30, %%r8d\n\t"            \
    942     "# edi = a\n\t"                        \
    943     "movl       %"#a", %%edi\n\t"          \
    944     "# edi = a>>>13\n\t"                   \
    945     "roll       $19, %%edi\n\t"            \
    946     "# edx = a\n\t"                        \
    947     "movl       %"#a", %%edx\n\t"
    948 
    949 #define RND_STEP_5(a,b,c,d,e,f,g,h,i) \
    950     "# edx = a>>>22\n\t"              \
    951     "roll       $10, %%edx\n\t"       \
    952     "# edi = (a>>>2) ^ (a>>>13)\n\t"  \
    953     "xorl       %%r8d, %%edi\n\t"     \
    954     "# edx = Sigma0(a)\n\t"           \
    955     "xorl       %%edi, %%edx\n\t"
    956 
    957 #define RND_STEP_6(a,b,c,d,e,f,g,h,i) \
    958     "# edi = b\n\t"                   \
    959     "movl       %"#b", %%edi\n\t"     \
    960     "# edi = a | b\n\t"               \
    961     "orl        %"#a", %%edi\n\t"     \
    962     "# edi = (a | b) & c\n\t"         \
    963     "andl       %"#c", %%edi\n\t"     \
    964     "# r8d = b\n\t"                   \
    965     "movl       %"#b", %%r8d\n\t"
    966 
    967 #define RND_STEP_7(a,b,c,d,e,f,g,h,i) \
    968     "# h += Ch(e,f,g)\n\t"            \
    969     "addl       %%esi, %"#h"\n\t"     \
    970     "#r8d = b & a\n\t"                \
    971     "andl       %"#a", %%r8d\n\t"     \
    972     "# r8d = Maj(a,b,c)\n\t"          \
    973     "orl        %%edi, %%r8d\n\t"
    974 
    975 #define RND_STEP_8(a,b,c,d,e,f,g,h,i)                                    \
    976     "# d += h + w_k + Sigma1(e) + Ch(e,f,g)\n\t"                         \
     1175#define RND_STEP_0_1(a,b,c,d,e,f,g,h,i)                               \
     1176    /* L1 = e>>>14 */                                                 \
     1177    "rorl       $14, " L1 "\n\t"                                      \
     1178
     1179#define RND_STEP_0_2(a,b,c,d,e,f,g,h,i)                               \
     1180    /* L3 = b */                                                      \
     1181    "movl       %" #b ", " L3 "\n\t"                                  \
     1182    /* L2 = f */                                                      \
     1183    "movl       %" #f ", " L2 "\n\t"                                  \
     1184    /* h += w_k */                                                    \
     1185    "addl       (" #i ")*4(" WK "), %" #h "\n\t"                      \
     1186    /* L2 = f ^ g */                                                  \
     1187    "xorl       %" #g ", " L2 "\n\t"                                  \
     1188
     1189#define RND_STEP_0_3(a,b,c,d,e,f,g,h,i)                               \
     1190    /* L1 = (e>>>14) ^ e */                                           \
     1191    "xorl       %" #e ", " L1 "\n\t"                                  \
     1192    /* L2 = (f ^ g) & e */                                            \
     1193    "andl       %" #e ", " L2 "\n\t"                                  \
     1194
     1195#define RND_STEP_0_4(a,b,c,d,e,f,g,h,i)                               \
     1196    /* L1 = ((e>>>14) ^ e) >>> 5 */                                   \
     1197    "rorl       $5, " L1 "\n\t"                                       \
     1198    /* L2 = Ch(e,f,g) */                                              \
     1199    "xorl       %" #g ", " L2 "\n\t"                                  \
     1200    /* L1 = (((e>>>14) ^ e) >>> 5) ^ e */                             \
     1201    "xorl       %" #e ", " L1 "\n\t"                                  \
     1202    /* h += Ch(e,f,g) */                                              \
     1203    "addl       " L2 ", %" #h "\n\t"                                  \
     1204
     1205#define RND_STEP_0_5(a,b,c,d,e,f,g,h,i)                               \
     1206    /* L1 = ((((e>>>14) ^ e) >>> 5) ^ e) >>> 6 */                     \
     1207    "rorl       $6, " L1 "\n\t"                                       \
     1208    /* L3 = a ^ b (= b ^ c of next RND) */                            \
     1209    "xorl       %" #a ", " L3 "\n\t"                                  \
     1210    /* h = h + w_k + Sigma1(e) */                                     \
     1211    "addl       " L1 ", %" #h "\n\t"                                  \
     1212    /* L2 = a */                                                      \
     1213    "movl       %" #a ", " L2 "\n\t"                                  \
     1214
     1215#define RND_STEP_0_6(a,b,c,d,e,f,g,h,i)                               \
     1216    /* L3 = (a ^ b) & (b ^ c) */                                      \
     1217    "andl       " L3 ", " L4 "\n\t"                                   \
     1218    /* L2 = a>>>9 */                                                  \
     1219    "rorl       $9, " L2 "\n\t"                                       \
     1220    /* L2 = (a>>>9) ^ a */                                            \
     1221    "xorl       %" #a ", " L2 "\n\t"                                  \
     1222    /* L1 = Maj(a,b,c) */                                             \
     1223    "xorl       %" #b ", " L4 "\n\t"                                  \
     1224
     1225#define RND_STEP_0_7(a,b,c,d,e,f,g,h,i)                               \
     1226    /* L2 = ((a>>>9) ^ a) >>> 11 */                                   \
     1227    "rorl       $11, " L2 "\n\t"                                      \
     1228    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */                        \
     1229    "addl       %" #h ", %" #d "\n\t"                                 \
     1230    /* L2 = (((a>>>9) ^ a) >>> 11) ^ a */                             \
     1231    "xorl       %" #a ", " L2 "\n\t"                                  \
     1232    /* h = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c) */            \
     1233    "addl       " L4 ", %" #h "\n\t"                                  \
     1234
     1235#define RND_STEP_0_8(a,b,c,d,e,f,g,h,i)                               \
     1236    /* L2 = ((((a>>>9) ^ a) >>> 11) ^ a) >>> 2 */                     \
     1237    "rorl       $2, " L2 "\n\t"                                       \
     1238    /* L1 = d (e of next RND) */                                      \
     1239    "movl       %" #d ", " L1 "\n\t"                                  \
     1240    /* h = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c) */  \
     1241    "addl       " L2 ", %" #h "\n\t"                                  \
     1242
     1243#define RND_STEP_1_1(a,b,c,d,e,f,g,h,i)                               \
     1244    /* L1 = e>>>14 */                                                 \
     1245    "rorl       $14, " L1 "\n\t"                                      \
     1246
     1247#define RND_STEP_1_2(a,b,c,d,e,f,g,h,i)                               \
     1248    /* L3 = b */                                                      \
     1249    "movl       %" #b ", " L4 "\n\t"                                  \
     1250    /* L2 = f */                                                      \
     1251    "movl       %" #f ", " L2 "\n\t"                                  \
     1252    /* h += w_k */                                                    \
     1253    "addl       (" #i ")*4(" WK "), %" #h "\n\t"                      \
     1254    /* L2 = f ^ g */                                                  \
     1255    "xorl       %" #g ", " L2 "\n\t"                                  \
     1256
     1257#define RND_STEP_1_3(a,b,c,d,e,f,g,h,i)                               \
     1258    /* L1 = (e>>>14) ^ e */                                           \
     1259    "xorl       %" #e ", " L1 "\n\t"                                  \
     1260    /* L2 = (f ^ g) & e */                                            \
     1261    "andl       %" #e ", " L2 "\n\t"                                  \
     1262
     1263#define RND_STEP_1_4(a,b,c,d,e,f,g,h,i)                               \
     1264    /* L1 = ((e>>>14) ^ e) >>> 5 */                                   \
     1265    "rorl       $5, " L1 "\n\t"                                       \
     1266    /* L2 = Ch(e,f,g) */                                              \
     1267    "xorl       %" #g ", " L2 "\n\t"                                  \
     1268    /* L1 = (((e>>>14) ^ e) >>> 5) ^ e */                             \
     1269    "xorl       %" #e ", " L1 "\n\t"                                  \
     1270    /* h += Ch(e,f,g) */                                              \
     1271    "addl       " L2 ", %" #h "\n\t"                                  \
     1272
     1273#define RND_STEP_1_5(a,b,c,d,e,f,g,h,i)                               \
     1274    /* L1 = ((((e>>>14) ^ e) >>> 5) ^ e) >>> 6 */                     \
     1275    "rorl       $6, " L1 "\n\t"                                       \
     1276    /* L4 = a ^ b (= b ^ c of next RND) */                            \
     1277    "xorl       %" #a ", " L4 "\n\t"                                  \
     1278    /* h = h + w_k + Sigma1(e) */                                     \
     1279    "addl       " L1 ", %" #h "\n\t"                                  \
     1280    /* L2 = a */                                                      \
     1281    "movl       %" #a ", " L2 "\n\t"                                  \
     1282
     1283#define RND_STEP_1_6(a,b,c,d,e,f,g,h,i)                               \
     1284    /* L3 = (a ^ b) & (b ^ c)  */                                     \
     1285    "andl       " L4 ", " L3 "\n\t"                                   \
     1286    /* L2 = a>>>9 */                                                  \
     1287    "rorl       $9, " L2 "\n\t"                                       \
     1288    /* L2 = (a>>>9) ^ a */                                            \
     1289    "xorl       %" #a ", " L2 "\n\t"                                  \
     1290    /* L1 = Maj(a,b,c) */                                             \
     1291    "xorl       %" #b ", " L3 "\n\t"                                  \
     1292
     1293#define RND_STEP_1_7(a,b,c,d,e,f,g,h,i)                               \
     1294    /* L2 = ((a>>>9) ^ a) >>> 11 */                                   \
     1295    "rorl       $11, " L2 "\n\t"                                      \
     1296    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */                        \
     1297    "addl       %" #h ", %" #d "\n\t"                                 \
     1298    /* L2 = (((a>>>9) ^ a) >>> 11) ^ a */                             \
     1299    "xorl       %" #a ", " L2 "\n\t"                                  \
     1300    /* h = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c) */            \
     1301    "addl       " L3 ", %" #h "\n\t"                                  \
     1302
     1303#define RND_STEP_1_8(a,b,c,d,e,f,g,h,i)                               \
     1304    /* L2 = ((((a>>>9) ^ a) >>> 11) ^ a) >>> 2 */                     \
     1305    "rorl       $2, " L2 "\n\t"                                       \
     1306    /* L1 = d (e of next RND) */                                      \
     1307    "movl       %" #d ", " L1 "\n\t"                                  \
     1308    /* h = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c) */  \
     1309    "addl       " L2 ", %" #h "\n\t"                                  \
     1310
     1311#define _RND_ALL_0(a,b,c,d,e,f,g,h,i)                                 \
     1312    /* h += w_k */                                                    \
     1313    "addl       (" #i ")*4(" WK "), %" #h "\n\t"                      \
     1314    /* L2 = f */                                                      \
     1315    "movl       %" #f ", " L2 "\n\t"                                  \
     1316    /* L3 = b */                                                      \
     1317    "movl       %" #b ", " L3 "\n\t"                                  \
     1318    /* L2 = f ^ g */                                                  \
     1319    "xorl       %" #g ", " L2 "\n\t"                                  \
     1320    /* L1 = e>>>14 */                                                 \
     1321    "rorl       $14, " L1 "\n\t"                                      \
     1322    /* L2 = (f ^ g) & e */                                            \
     1323    "andl       %" #e ", " L2 "\n\t"                                  \
     1324    /* L1 = (e>>>14) ^ e */                                           \
     1325    "xorl       %" #e ", " L1 "\n\t"                                  \
     1326    /* L2 = Ch(e,f,g) */                                              \
     1327    "xorl       %" #g ", " L2 "\n\t"                                  \
     1328    /* L1 = ((e>>>14) ^ e) >>> 5 */                                   \
     1329    "rorl       $5, " L1 "\n\t"                                       \
     1330    /* h += Ch(e,f,g) */                                              \
     1331    "addl       " L2 ", %" #h "\n\t"                                  \
     1332    /* L1 = (((e>>>14) ^ e) >>> 5) ^ e */                             \
     1333    "xorl       %" #e ", " L1 "\n\t"                                  \
     1334    /* L3 = a ^ b */                                                  \
     1335    "xorl       %" #a ", " L3 "\n\t"                                  \
     1336    /* L1 = ((((e>>>14) ^ e) >>> 5) ^ e) >>> 6 */                     \
     1337    "rorl       $6, " L1 "\n\t"                                       \
     1338    /* L2 = a */                                                      \
     1339    "movl       %" #a ", " L2 "\n\t"                                  \
     1340    /* h = h + w_k + Sigma1(e) */                                     \
     1341    "addl       " L1 ", %" #h "\n\t"                                  \
     1342    /* L2 = a>>>9 */                                                  \
     1343    "rorl       $9, " L2 "\n\t"                                       \
     1344    /* L3 = (a ^ b) & (b ^ c) */                                      \
     1345    "andl       " L3 ", " L4 "\n\t"                                   \
     1346    /* L2 = (a>>>9) ^ a */                                            \
     1347    "xorl       %" #a ", " L2 "\n\t"                                  \
     1348    /* L1 = Maj(a,b,c) */                                             \
     1349    "xorl       %" #b ", " L4 "\n\t"                                  \
     1350    /* L2 = ((a>>>9) ^ a) >>> 11 */                                   \
     1351    "rorl       $11, " L2 "\n\t"                                      \
     1352    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */                        \
     1353    "addl       %" #h ", %" #d "\n\t"                                 \
     1354    /* L2 = (((a>>>9) ^ a) >>> 11) ^ a */                             \
     1355    "xorl       %" #a ", " L2 "\n\t"                                  \
     1356    /* h = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c) */            \
     1357    "addl       " L4 ", %" #h "\n\t"                                  \
     1358    /* L2 = ((((a>>>9) ^ a) >>> 11) ^ a) >>> 2 */                     \
     1359    "rorl       $2, " L2 "\n\t"                                       \
     1360    /* L1 = d (e of next RND) */                                      \
     1361    "movl       %" #d ", " L1 "\n\t"                                  \
     1362    /* h = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c) */  \
     1363    "addl       " L2 ", %" #h "\n\t"                                  \
     1364
     1365#define _RND_ALL_1(a,b,c,d,e,f,g,h,i)                                 \
     1366    /* h += w_k */                                                    \
     1367    "addl       (" #i ")*4(" WK "), %" #h "\n\t"                      \
     1368    /* L2 = f */                                                      \
     1369    "movl       %" #f ", " L2 "\n\t"                                  \
     1370    /* L3 = b */                                                      \
     1371    "movl       %" #b ", " L4 "\n\t"                                  \
     1372    /* L2 = f ^ g */                                                  \
     1373    "xorl       %" #g ", " L2 "\n\t"                                  \
     1374    /* L1 = e>>>14 */                                                 \
     1375    "rorl       $14, " L1 "\n\t"                                      \
     1376    /* L2 = (f ^ g) & e */                                            \
     1377    "andl       %" #e ", " L2 "\n\t"                                  \
     1378    /* L1 = (e>>>14) ^ e */                                           \
     1379    "xorl       %" #e ", " L1 "\n\t"                                  \
     1380    /* L2 = Ch(e,f,g) */                                              \
     1381    "xorl       %" #g ", " L2 "\n\t"                                  \
     1382    /* L1 = ((e>>>14) ^ e) >>> 5 */                                   \
     1383    "rorl       $5, " L1 "\n\t"                                       \
     1384    /* h += Ch(e,f,g) */                                              \
     1385    "addl       " L2 ", %" #h "\n\t"                                  \
     1386    /* L1 = (((e>>>14) ^ e) >>> 5) ^ e */                             \
     1387    "xorl       %" #e ", " L1 "\n\t"                                  \
     1388    /* L3 = a ^ b */                                                  \
     1389    "xorl       %" #a ", " L4 "\n\t"                                  \
     1390    /* L1 = ((((e>>>14) ^ e) >>> 5) ^ e) >>> 6 */                     \
     1391    "rorl       $6, " L1 "\n\t"                                       \
     1392    /* L2 = a */                                                      \
     1393    "movl       %" #a ", " L2 "\n\t"                                  \
     1394    /* h = h + w_k + Sigma1(e) */                                     \
     1395    "addl       " L1 ", %" #h "\n\t"                                  \
     1396    /* L2 = a>>>9 */                                                  \
     1397    "rorl       $9, " L2 "\n\t"                                       \
     1398    /* L3 = (a ^ b) & (b ^ c)  */                                     \
     1399    "andl       " L4 ", " L3 "\n\t"                                   \
     1400    /* L2 = (a>>>9) ^ a */                                            \
     1401    "xorl       %" #a", " L2 "\n\t"                                   \
     1402    /* L1 = Maj(a,b,c) */                                             \
     1403    "xorl       %" #b ", " L3 "\n\t"                                  \
     1404    /* L2 = ((a>>>9) ^ a) >>> 11 */                                   \
     1405    "rorl       $11, " L2 "\n\t"                                      \
     1406    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */                        \
    9771407    "addl       %"#h", %"#d"\n\t"                                        \
    978     "# r8b = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c)\n\t"           \
    979     "addl       %"#h", %%r8d\n\t"                                        \
    980     "# r8b = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c)\n\t" \
    981     "addl       %%edx, %%r8d\n\t"                                        \
    982     "# h = h + w_k + Sigma1(e) + Sigma0(a) + Ch(e,f,g) + Maj(a,b,c)\n\t" \
    983     "movl       %%r8d, %"#h"\n\t"
    984 
    985 #define RND_X(a,b,c,d,e,f,g,h,i) \
    986        RND_STEP_1(a,b,c,d,e,f,g,h,i) \
    987        RND_STEP_2(a,b,c,d,e,f,g,h,i) \
    988        RND_STEP_3(a,b,c,d,e,f,g,h,i) \
    989        RND_STEP_4(a,b,c,d,e,f,g,h,i) \
    990        RND_STEP_5(a,b,c,d,e,f,g,h,i) \
    991        RND_STEP_6(a,b,c,d,e,f,g,h,i) \
    992        RND_STEP_7(a,b,c,d,e,f,g,h,i) \
    993        RND_STEP_8(a,b,c,d,e,f,g,h,i)
    994 
    995 #define RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i)
    996 #define RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i)
    997 #define RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i)
    998 #define RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i)
    999 #define RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i)
    1000 #define RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i)
    1001 #define RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i)
    1002 #define RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i)
    1003 
    1004 
    1005 #define RND_1_3(a,b,c,d,e,f,g,h,i) \
    1006        RND_STEP_1(a,b,c,d,e,f,g,h,i) \
    1007        RND_STEP_2(a,b,c,d,e,f,g,h,i) \
    1008        RND_STEP_3(a,b,c,d,e,f,g,h,i)
    1009 
    1010 #define RND_4_6(a,b,c,d,e,f,g,h,i) \
    1011        RND_STEP_4(a,b,c,d,e,f,g,h,i) \
    1012        RND_STEP_5(a,b,c,d,e,f,g,h,i) \
    1013        RND_STEP_6(a,b,c,d,e,f,g,h,i)
    1014 
    1015 #define RND_7_8(a,b,c,d,e,f,g,h,i) \
    1016        RND_STEP_7(a,b,c,d,e,f,g,h,i) \
    1017        RND_STEP_8(a,b,c,d,e,f,g,h,i)
    1018 
    1019 #define RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i)
    1020 #define RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i)
    1021 #define RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i)
    1022 #define RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i)
    1023 #define RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i)
    1024 #define RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i)
    1025 #define RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i)
    1026 #define RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_X(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i)
    1027 
    1028 
    1029 #define RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i)
    1030 #define RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i)
    1031 #define RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i)
    1032 #define RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i)
    1033 #define RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i)
    1034 #define RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i)
    1035 #define RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i)
    1036 #define RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_1_3(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i)
    1037 
    1038 #define RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i)
    1039 #define RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i)
    1040 #define RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i)
    1041 #define RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i)
    1042 #define RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i)
    1043 #define RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i)
    1044 #define RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i)
    1045 #define RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_4_6(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i)
    1046 
    1047 #define RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i)
    1048 #define RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_7,S_0,S_1,S_2,S_3,S_4,S_5,S_6,_i)
    1049 #define RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_6,S_7,S_0,S_1,S_2,S_3,S_4,S_5,_i)
    1050 #define RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_5,S_6,S_7,S_0,S_1,S_2,S_3,S_4,_i)
    1051 #define RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,_i)
    1052 #define RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_3,S_4,S_5,S_6,S_7,S_0,S_1,S_2,_i)
    1053 #define RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_2,S_3,S_4,S_5,S_6,S_7,S_0,S_1,_i)
    1054 #define RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,_i) RND_7_8(S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_0,_i)
    1055 
    1056 #define FOR(cnt, init, max, inc, loop)  \
    1057     __asm__ volatile("movl $"#init", %0\n\t"#loop":"::"m"(cnt):)
    1058 #define END(cnt, init, max, inc, loop)  \
    1059     __asm__ volatile("addl $"#inc", %0\n\tcmpl $"#max", %0\n\tjle "#loop"\n\t":"=m"(cnt)::);
     1408    /* L2 = (((a>>>9) ^ a) >>> 11) ^ a */                             \
     1409    "xorl       %" #a ", " L2 "\n\t"                                  \
     1410    /* h = h + w_k + Sigma1(e) + Ch(e,f,g) + Maj(a,b,c) */            \
     1411    "addl       " L3 ", %" #h "\n\t"                                  \
     1412    /* L2 = ((((a>>>9) ^ a) >>> 11) ^ a) >>> 2 */                     \
     1413    "rorl       $2, " L2 "\n\t"                                       \
     1414    /* L1 = d (e of next RND) */                                      \
     1415    "movl       %" #d ", " L1 "\n\t"                                  \
     1416    /* h = h + w_k + Sigma1(e) Sigma0(a) + Ch(e,f,g) + Maj(a,b,c) */  \
     1417    "addl       " L2 ", %" #h "\n\t"                                  \
     1418
     1419
     1420#define RND_ALL_0(a, b, c, d, e, f, g, h, i) \
     1421       _RND_ALL_0(a, b, c, d, e, f, g, h, i)
     1422#define RND_ALL_1(a, b, c, d, e, f, g, h, i) \
     1423       _RND_ALL_1(a, b, c, d, e, f, g, h, i)
     1424
     1425#define RND_ALL_4(a, b, c, d, e, f, g, h, i)   \
     1426        RND_ALL_0(a, b, c, d, e, f, g, h, i+0) \
     1427        RND_ALL_1(h, a, b, c, d, e, f, g, i+1) \
     1428        RND_ALL_0(g, h, a, b, c, d, e, f, i+2) \
     1429        RND_ALL_1(f, g, h, a, b, c, d, e, i+3)
    10601430
    10611431#endif  /* defined(HAVE_INTEL_AVX1) ||  defined(HAVE_INTEL_AVX2) */
     
    10631433#if defined(HAVE_INTEL_AVX1) /* inline Assember for Intel AVX1 instructions */
    10641434
    1065 #define VPALIGNR(op1,op2,op3,op4) \
     1435#define _VPALIGNR(op1, op2, op3, op4)                    \
    10661436    "vpalignr   $"#op4", %"#op3", %"#op2", %"#op1"\n\t"
    1067 #define VPADDD(op1,op2,op3)       \
     1437#define VPALIGNR(op1, op2, op3, op4)                     \
     1438        _VPALIGNR(op1, op2, op3, op4)
     1439#define _VPADDD(op1, op2, op3)                           \
    10681440    "vpaddd     %"#op3", %"#op2", %"#op1"\n\t"
    1069 #define VPSRLD(op1,op2,op3)       \
     1441#define VPADDD(op1, op2, op3)                            \
     1442       _VPADDD(op1, op2, op3)
     1443#define _VPSRLD(op1, op2, op3)                           \
    10701444    "vpsrld     $"#op3", %"#op2", %"#op1"\n\t"
    1071 #define VPSRLQ(op1,op2,op3)       \
     1445#define VPSRLD(op1, op2, op3)        \
     1446       _VPSRLD(op1, op2, op3)
     1447#define _VPSRLQ(op1, op2, op3)                           \
    10721448    "vpsrlq     $"#op3", %"#op2", %"#op1"\n\t"
    1073 #define VPSLLD(op1,op2,op3)       \
     1449#define VPSRLQ(op1,op2,op3)        \
     1450       _VPSRLQ(op1,op2,op3)
     1451#define _VPSLLD(op1,op2,op3)                             \
    10741452    "vpslld     $"#op3", %"#op2", %"#op1"\n\t"
    1075 #define VPOR(op1,op2,op3)         \
     1453#define VPSLLD(op1,op2,op3)        \
     1454       _VPSLLD(op1,op2,op3)
     1455#define _VPOR(op1,op2,op3)                               \
    10761456    "vpor       %"#op3", %"#op2", %"#op1"\n\t"
    1077 #define VPXOR(op1,op2,op3)        \
     1457#define VPOR(op1,op2,op3)          \
     1458       _VPOR(op1,op2,op3)
     1459#define _VPXOR(op1,op2,op3)                              \
    10781460    "vpxor      %"#op3", %"#op2", %"#op1"\n\t"
    1079 #define VPSHUFD(op1,op2,op3)      \
     1461#define VPXOR(op1,op2,op3)         \
     1462       _VPXOR(op1,op2,op3)
     1463#define _VPSHUFD(op1,op2,op3)                            \
    10801464    "vpshufd    $"#op3", %"#op2", %"#op1"\n\t"
    1081 #define VPSHUFB(op1,op2,op3)      \
     1465#define VPSHUFD(op1,op2,op3)       \
     1466       _VPSHUFD(op1,op2,op3)
     1467#define _VPSHUFB(op1,op2,op3)                            \
    10821468    "vpshufb    %"#op3", %"#op2", %"#op1"\n\t"
    1083 
    1084 #define MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER, SHUF_00BA, SHUF_DC00,\
    1085      a,b,c,d,e,f,g,h,_i)\
    1086             RND_STEP_1(a,b,c,d,e,f,g,h,_i)\
     1469#define VPSHUFB(op1,op2,op3)       \
     1470       _VPSHUFB(op1,op2,op3)
     1471#define _VPSLLDQ(op1,op2,op3)                            \
     1472    "vpslldq    $" #op3", %" #op2", %" #op1"\n\t"
     1473#define VPSLLDQ(op1,op2,op3)       \
     1474       _VPSLLDQ(op1,op2,op3)
     1475
     1476#define MsgSched(X0,X1,X2,X3,a,b,c,d,e,f,g,h,_i)                           \
     1477            RND_STEP_0_1(a,b,c,d,e,f,g,h,_i)                               \
     1478    VPALIGNR (XTMP1, X1, X0, 4)   /* XTMP1 = W[-15] */\
     1479    VPALIGNR (XTMP0, X3, X2, 4)    /* XTMP0 = W[-7] */                     \
     1480            RND_STEP_0_2(a,b,c,d,e,f,g,h,_i)                               \
     1481            RND_STEP_0_3(a,b,c,d,e,f,g,h,_i)                               \
     1482    VPSRLD   (XTMP2, XTMP1, 7)     /* XTMP2 = W[-15] >> 7 */               \
     1483    VPSLLD   (XTMP3, XTMP1, 25)    /* XTEMP3 = W[-15] << (32-7) */         \
     1484            RND_STEP_0_4(a,b,c,d,e,f,g,h,_i)                               \
     1485            RND_STEP_0_5(a,b,c,d,e,f,g,h,_i)                               \
     1486    VPSRLD   (XTMP4, XTMP1, 18)    /* XTEMP4 = W[-15] >> 18 */             \
     1487    VPSLLD   (XTMP5, XTMP1, 14)    /* XTEMP5 = W[-15] << (32-18) */        \
     1488            RND_STEP_0_6(a,b,c,d,e,f,g,h,_i)                               \
     1489            RND_STEP_0_7(a,b,c,d,e,f,g,h,_i)                               \
     1490    VPOR     (XTMP2, XTMP3, XTMP2) /* XTMP2 = W[-15] >>> 7 */              \
     1491    VPOR     (XTMP4, XTMP5, XTMP4) /* XTMP4 = W[-15] >>> 18 */             \
     1492            RND_STEP_0_8(a,b,c,d,e,f,g,h,_i)                               \
     1493            RND_STEP_1_1(h,a,b,c,d,e,f,g,_i+1)                             \
     1494            RND_STEP_1_2(h,a,b,c,d,e,f,g,_i+1)                             \
     1495    VPSRLD   (XTMP5, XTMP1, 3)     /* XTMP4 = W[-15] >> 3 */               \
     1496    VPXOR    (XTMP2, XTMP4, XTMP2)                                         \
     1497                          /* XTMP2 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */ \
     1498            RND_STEP_1_3(h,a,b,c,d,e,f,g,_i+1)                             \
     1499            RND_STEP_1_4(h,a,b,c,d,e,f,g,_i+1)                             \
     1500    VPXOR    (XTMP1, XTMP5, XTMP2)  /* XTMP1 = s0 */                       \
     1501    VPSHUFD(XTMP2, X3, 0b11111010)  /* XTMP2 = W[-2] {BBAA}*/\
     1502            RND_STEP_1_5(h,a,b,c,d,e,f,g,_i+1)                             \
     1503            RND_STEP_1_6(h,a,b,c,d,e,f,g,_i+1)                             \
     1504    VPSRLD   (XTMP4, XTMP2, 10)      /* XTMP4 = W[-2] >> 10 {BBAA} */\
     1505    VPSRLQ   (XTMP3, XTMP2, 19)      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
     1506            RND_STEP_1_7(h,a,b,c,d,e,f,g,_i+1)                             \
     1507            RND_STEP_1_8(h,a,b,c,d,e,f,g,_i+1)                             \
     1508            RND_STEP_0_1(g,h,a,b,c,d,e,f,_i+2)                             \
     1509    VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
     1510    VPADDD   (XTMP0, XTMP0, X0)                                            \
     1511            RND_STEP_0_2(g,h,a,b,c,d,e,f,_i+2)                             \
     1512            RND_STEP_0_3(g,h,a,b,c,d,e,f,_i+2)                             \
     1513            RND_STEP_0_4(g,h,a,b,c,d,e,f,_i+2)                             \
     1514    VPXOR    (XTMP2, XTMP3, XTMP2)                                         \
     1515    VPADDD   (XTMP0, XTMP0, XTMP1)  /* XTMP0 = W[-16] + W[-7] + s0 */      \
     1516            RND_STEP_0_5(g,h,a,b,c,d,e,f,_i+2)                             \
     1517    VPXOR    (XTMP4, XTMP4, XTMP2)   /* XTMP4 = s1 {xBxA} */\
     1518            RND_STEP_0_6(g,h,a,b,c,d,e,f,_i+2)                             \
     1519    VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  /* XTMP4 = s1 {00BA} */\
     1520            RND_STEP_0_7(g,h,a,b,c,d,e,f,_i+2)                             \
     1521    VPADDD   (XTMP0, XTMP0, XTMP4)  /* XTMP0 = {..., ..., W[1], W[0]} */\
     1522            RND_STEP_0_8(g,h,a,b,c,d,e,f,_i+2)                             \
     1523            RND_STEP_1_1(f,g,h,a,b,c,d,e,_i+3)                             \
     1524    VPSHUFD  (XTMP2, XTMP0, 0b01010000) /* XTMP2 = W[-2] {DDCC} */\
     1525            RND_STEP_1_2(f,g,h,a,b,c,d,e,_i+3)                             \
     1526    VPSRLQ   (XTMP4, XTMP2, 17)      /* XTMP4 = W[-2] MY_ROR 17 {xDxC} */  \
     1527    VPSRLQ   (XTMP3, XTMP2, 19)       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
     1528            RND_STEP_1_3(f,g,h,a,b,c,d,e,_i+3)                             \
     1529            RND_STEP_1_4(f,g,h,a,b,c,d,e,_i+3)                             \
     1530    VPSRLD   (XTMP5, XTMP2, 10)       /* XTMP5 = W[-2] >> 10 {DDCC} */     \
     1531    VPXOR    (XTMP4, XTMP3, XTMP4)                                         \
     1532            RND_STEP_1_5(f,g,h,a,b,c,d,e,_i+3)                             \
     1533            RND_STEP_1_6(f,g,h,a,b,c,d,e,_i+3)                             \
     1534    VPXOR    (XTMP5, XTMP4, XTMP5)   /* XTMP5 = s1 {xDxC} */               \
     1535            RND_STEP_1_7(f,g,h,a,b,c,d,e,_i+3)                             \
     1536    VPSHUFB  (XTMP5, XTMP5, SHUF_DC00) /* XTMP5 = s1 {DC00} */\
     1537            RND_STEP_1_8(f,g,h,a,b,c,d,e,_i+3)                             \
     1538    VPADDD   (X0, XTMP5, XTMP0)      /* X0 = {W[3], W[2], W[1], W[0]} */
     1539
     1540#if defined(HAVE_INTEL_RORX)
     1541
     1542#define MsgSched_RORX(X0,X1,X2,X3,a,b,c,d,e,f,g,h,_i)                      \
     1543            RND_STEP_RORX_0_1(a,b,c,d,e,f,g,h,_i)                          \
    10871544    VPALIGNR (XTMP0, X3, X2, 4)\
    1088             RND_STEP_2(a,b,c,d,e,f,g,h,_i)\
    1089     VPADDD   (XTMP0, XTMP0, X0)\
    1090             RND_STEP_3(a,b,c,d,e,f,g,h,_i)\
    10911545    VPALIGNR (XTMP1, X1, X0, 4)   /* XTMP1 = W[-15] */\
    1092             RND_STEP_4(a,b,c,d,e,f,g,h,_i)\
     1546            RND_STEP_RORX_0_2(a,b,c,d,e,f,g,h,_i)                          \
     1547            RND_STEP_RORX_0_3(a,b,c,d,e,f,g,h,_i)                          \
    10931548    VPSRLD   (XTMP2, XTMP1, 7)\
    1094             RND_STEP_5(a,b,c,d,e,f,g,h,_i)\
    10951549    VPSLLD   (XTMP3, XTMP1, 25) /* VPSLLD   (XTMP3, XTMP1, (32-7)) */\
    1096             RND_STEP_6(a,b,c,d,e,f,g,h,_i)\
     1550            RND_STEP_RORX_0_4(a,b,c,d,e,f,g,h,_i)                          \
     1551            RND_STEP_RORX_0_5(a,b,c,d,e,f,g,h,_i)                          \
     1552    VPSRLD   (XTMP4, XTMP1, 3)  /* XTMP4 = W[-15] >> 3 */                  \
    10971553    VPOR     (XTMP3, XTMP3, XTMP2)  /* XTMP1 = W[-15] MY_ROR 7 */\
    1098             RND_STEP_7(a,b,c,d,e,f,g,h,_i)\
    1099     VPSRLD   (XTMP2, XTMP1,18)\
    1100             RND_STEP_8(a,b,c,d,e,f,g,h,_i)\
     1554            RND_STEP_RORX_0_6(a,b,c,d,e,f,g,h,_i)                          \
     1555            RND_STEP_RORX_0_7(a,b,c,d,e,f,g,h,_i)                          \
     1556            RND_STEP_RORX_0_8(a,b,c,d,e,f,g,h,_i)                          \
    11011557\
    1102             RND_STEP_1(h,a,b,c,d,e,f,g,_i+1)\
    1103     VPSRLD   (XTMP4, XTMP1, 3)  /* XTMP4 = W[-15] >> 3 */\
    1104             RND_STEP_2(h,a,b,c,d,e,f,g,_i+1)\
     1558            RND_STEP_RORX_1_1(h,a,b,c,d,e,f,g,_i+1)                        \
     1559    VPSRLD   (XTMP2, XTMP1,18)                                             \
     1560            RND_STEP_RORX_1_2(h,a,b,c,d,e,f,g,_i+1)                        \
    11051561    VPSLLD   (XTMP1, XTMP1, 14) /* VPSLLD   (XTMP1, XTMP1, (32-18)) */\
    1106             RND_STEP_3(h,a,b,c,d,e,f,g,_i+1)\
     1562            RND_STEP_RORX_1_3(h,a,b,c,d,e,f,g,_i+1)                        \
    11071563    VPXOR    (XTMP3, XTMP3, XTMP1)\
    1108             RND_STEP_4(h,a,b,c,d,e,f,g,_i+1)\
    1109     VPXOR    (XTMP3, XTMP3, XTMP2)  /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */\
    1110             RND_STEP_5(h,a,b,c,d,e,f,g,_i+1)\
    1111     VPXOR    (XTMP1, XTMP3, XTMP4)  /* XTMP1 = s0 */\
    1112             RND_STEP_6(h,a,b,c,d,e,f,g,_i+1)\
     1564            RND_STEP_RORX_1_4(h,a,b,c,d,e,f,g,_i+1)                        \
     1565    VPXOR    (XTMP3, XTMP3, XTMP2)                                         \
     1566                          /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */ \
     1567            RND_STEP_RORX_1_5(h,a,b,c,d,e,f,g,_i+1)                        \
    11131568    VPSHUFD(XTMP2, X3, 0b11111010)  /* XTMP2 = W[-2] {BBAA}*/\
    1114             RND_STEP_7(h,a,b,c,d,e,f,g,_i+1)\
    1115     VPADDD   (XTMP0, XTMP0, XTMP1)  /* XTMP0 = W[-16] + W[-7] + s0 */\
    1116             RND_STEP_8(h,a,b,c,d,e,f,g,_i+1)\
     1569            RND_STEP_RORX_1_6(h,a,b,c,d,e,f,g,_i+1)                        \
     1570    VPXOR    (XTMP1, XTMP3, XTMP4)  /* XTMP1 = s0 */                       \
     1571            RND_STEP_RORX_1_7(h,a,b,c,d,e,f,g,_i+1)                        \
     1572    VPSRLD   (XTMP4, XTMP2, 10)      /* XTMP4 = W[-2] >> 10 {BBAA} */\
     1573            RND_STEP_RORX_1_8(h,a,b,c,d,e,f,g,_i+1)                        \
     1574                                                                           \
     1575            RND_STEP_RORX_0_1(g,h,a,b,c,d,e,f,_i+2)                        \
     1576    VPSRLQ   (XTMP3, XTMP2, 19)      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
     1577            RND_STEP_RORX_0_2(g,h,a,b,c,d,e,f,_i+2)                        \
     1578    VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
     1579    VPADDD   (XTMP0, XTMP0, X0)                                            \
     1580            RND_STEP_RORX_0_3(g,h,a,b,c,d,e,f,_i+2)                        \
     1581    VPADDD   (XTMP0, XTMP0, XTMP1)  /* XTMP0 = W[-16] + W[-7] + s0 */      \
     1582            RND_STEP_RORX_0_4(g,h,a,b,c,d,e,f,_i+2)                        \
     1583    VPXOR    (XTMP2, XTMP2, XTMP3)\
     1584            RND_STEP_RORX_0_5(g,h,a,b,c,d,e,f,_i+2)                        \
     1585    VPXOR    (XTMP4, XTMP4, XTMP2)   /* XTMP4 = s1 {xBxA} */\
     1586            RND_STEP_RORX_0_6(g,h,a,b,c,d,e,f,_i+2)                        \
     1587    VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  /* XTMP4 = s1 {00BA} */\
     1588            RND_STEP_RORX_0_7(g,h,a,b,c,d,e,f,_i+2)                        \
     1589    VPADDD   (XTMP0, XTMP0, XTMP4)  /* XTMP0 = {..., ..., W[1], W[0]} */\
     1590            RND_STEP_RORX_0_8(g,h,a,b,c,d,e,f,_i+2)                        \
    11171591\
    1118             RND_STEP_1(g,h,a,b,c,d,e,f,_i+2)\
    1119     VPSRLD   (XTMP4, XTMP2, 10)      /* XTMP4 = W[-2] >> 10 {BBAA} */\
    1120             RND_STEP_2(g,h,a,b,c,d,e,f,_i+2)\
    1121     VPSRLQ   (XTMP3, XTMP2, 19)      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
    1122             RND_STEP_3(g,h,a,b,c,d,e,f,_i+2)\
    1123     VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
    1124             RND_STEP_4(g,h,a,b,c,d,e,f,_i+2)\
     1592            RND_STEP_RORX_1_1(f,g,h,a,b,c,d,e,_i+3)                        \
     1593    VPSHUFD  (XTMP2, XTMP0, 0b01010000) /* XTMP2 = W[-2] {DDCC} */\
     1594            RND_STEP_RORX_1_2(f,g,h,a,b,c,d,e,_i+3)                        \
     1595    VPSRLD   (XTMP5, XTMP2, 10)       /* XTMP5 = W[-2] >> 10 {DDCC} */\
     1596            RND_STEP_RORX_1_3(f,g,h,a,b,c,d,e,_i+3)                        \
     1597    VPSRLQ   (XTMP3, XTMP2, 19)       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
     1598            RND_STEP_RORX_1_4(f,g,h,a,b,c,d,e,_i+3)                        \
     1599    VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */\
     1600            RND_STEP_RORX_1_5(f,g,h,a,b,c,d,e,_i+3)                        \
    11251601    VPXOR    (XTMP2, XTMP2, XTMP3)\
    1126             RND_STEP_5(g,h,a,b,c,d,e,f,_i+2)\
    1127     VPXOR    (XTMP4, XTMP4, XTMP2)   /* XTMP4 = s1 {xBxA} */\
    1128             RND_STEP_6(g,h,a,b,c,d,e,f,_i+2)\
    1129     VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  /* XTMP4 = s1 {00BA} */\
    1130             RND_STEP_7(g,h,a,b,c,d,e,f,_i+2)\
    1131     VPADDD   (XTMP0, XTMP0, XTMP4)  /* XTMP0 = {..., ..., W[1], W[0]} */\
    1132             RND_STEP_8(g,h,a,b,c,d,e,f,_i+2)\
    1133 \
    1134             RND_STEP_1(f,g,h,a,b,c,d,e,_i+3)\
    1135     VPSHUFD  (XTMP2, XTMP0, 0b01010000) /* XTMP2 = W[-2] {DDCC} */\
    1136             RND_STEP_2(f,g,h,a,b,c,d,e,_i+3)\
    1137     VPSRLD   (XTMP5, XTMP2, 10)       /* XTMP5 = W[-2] >> 10 {DDCC} */\
    1138             RND_STEP_3(f,g,h,a,b,c,d,e,_i+3)\
    1139     VPSRLQ   (XTMP3, XTMP2, 19)       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
    1140             RND_STEP_4(f,g,h,a,b,c,d,e,_i+3)\
    1141     VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */\
    1142             RND_STEP_5(f,g,h,a,b,c,d,e,_i+3)\
    1143     VPXOR    (XTMP2, XTMP2, XTMP3)\
    1144             RND_STEP_6(f,g,h,a,b,c,d,e,_i+3)\
     1602            RND_STEP_RORX_1_6(f,g,h,a,b,c,d,e,_i+3)                        \
    11451603    VPXOR    (XTMP5, XTMP5, XTMP2)   /* XTMP5 = s1 {xDxC} */\
    1146             RND_STEP_7(f,g,h,a,b,c,d,e,_i+3)\
     1604            RND_STEP_RORX_1_7(f,g,h,a,b,c,d,e,_i+3)                        \
    11471605    VPSHUFB  (XTMP5, XTMP5, SHUF_DC00) /* XTMP5 = s1 {DC00} */\
    1148             RND_STEP_8(f,g,h,a,b,c,d,e,_i+3)\
    1149     VPADDD   (X0, XTMP5, XTMP0)      /* X0 = {W[3], W[2], W[1], W[0]} */\
    1150 
    1151 #if defined(HAVE_INTEL_RORX)
    1152 
    1153 #define MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, \
    1154                           XFER, SHUF_00BA, SHUF_DC00,a,b,c,d,e,f,g,h,_i)\
    1155             RND_STEP_RORX_1(a,b,c,d,e,f,g,h,_i)\
    1156     VPALIGNR (XTMP0, X3, X2, 4)\
    1157             RND_STEP_RORX_2(a,b,c,d,e,f,g,h,_i)\
    1158     VPADDD   (XTMP0, XTMP0, X0)\
    1159             RND_STEP_RORX_3(a,b,c,d,e,f,g,h,_i)\
    1160     VPALIGNR (XTMP1, X1, X0, 4)   /* XTMP1 = W[-15] */\
    1161             RND_STEP_RORX_4(a,b,c,d,e,f,g,h,_i)\
    1162     VPSRLD   (XTMP2, XTMP1, 7)\
    1163             RND_STEP_RORX_5(a,b,c,d,e,f,g,h,_i)\
    1164     VPSLLD   (XTMP3, XTMP1, 25) /* VPSLLD   (XTMP3, XTMP1, (32-7)) */\
    1165             RND_STEP_RORX_6(a,b,c,d,e,f,g,h,_i)\
    1166     VPOR     (XTMP3, XTMP3, XTMP2)  /* XTMP1 = W[-15] MY_ROR 7 */\
    1167             RND_STEP_RORX_7(a,b,c,d,e,f,g,h,_i)\
    1168     VPSRLD   (XTMP2, XTMP1,18)\
    1169             RND_STEP_RORX_8(a,b,c,d,e,f,g,h,_i)\
    1170 \
    1171             RND_STEP_RORX_1(h,a,b,c,d,e,f,g,_i+1)\
    1172     VPSRLD   (XTMP4, XTMP1, 3)  /* XTMP4 = W[-15] >> 3 */\
    1173             RND_STEP_RORX_2(h,a,b,c,d,e,f,g,_i+1)\
    1174     VPSLLD   (XTMP1, XTMP1, 14) /* VPSLLD   (XTMP1, XTMP1, (32-18)) */\
    1175             RND_STEP_RORX_3(h,a,b,c,d,e,f,g,_i+1)\
    1176     VPXOR    (XTMP3, XTMP3, XTMP1)\
    1177             RND_STEP_RORX_4(h,a,b,c,d,e,f,g,_i+1)\
    1178     VPXOR    (XTMP3, XTMP3, XTMP2)  /* XTMP1 = W[-15] MY_ROR 7 ^ W[-15] MY_ROR 18 */\
    1179             RND_STEP_RORX_5(h,a,b,c,d,e,f,g,_i+1)\
    1180     VPXOR    (XTMP1, XTMP3, XTMP4)  /* XTMP1 = s0 */\
    1181             RND_STEP_RORX_6(h,a,b,c,d,e,f,g,_i+1)\
    1182     VPSHUFD(XTMP2, X3, 0b11111010)  /* XTMP2 = W[-2] {BBAA}*/\
    1183             RND_STEP_RORX_7(h,a,b,c,d,e,f,g,_i+1)\
    1184     VPADDD   (XTMP0, XTMP0, XTMP1)  /* XTMP0 = W[-16] + W[-7] + s0 */\
    1185             RND_STEP_RORX_8(h,a,b,c,d,e,f,g,_i+1)\
    1186 \
    1187             RND_STEP_RORX_1(g,h,a,b,c,d,e,f,_i+2)\
    1188     VPSRLD   (XTMP4, XTMP2, 10)      /* XTMP4 = W[-2] >> 10 {BBAA} */\
    1189             RND_STEP_RORX_2(g,h,a,b,c,d,e,f,_i+2)\
    1190     VPSRLQ   (XTMP3, XTMP2, 19)      /* XTMP3 = W[-2] MY_ROR 19 {xBxA} */\
    1191             RND_STEP_RORX_3(g,h,a,b,c,d,e,f,_i+2)\
    1192     VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xBxA} */\
    1193             RND_STEP_RORX_4(g,h,a,b,c,d,e,f,_i+2)\
    1194     VPXOR    (XTMP2, XTMP2, XTMP3)\
    1195             RND_STEP_RORX_5(g,h,a,b,c,d,e,f,_i+2)\
    1196     VPXOR    (XTMP4, XTMP4, XTMP2)   /* XTMP4 = s1 {xBxA} */\
    1197             RND_STEP_RORX_6(g,h,a,b,c,d,e,f,_i+2)\
    1198     VPSHUFB  (XTMP4, XTMP4, SHUF_00BA)  /* XTMP4 = s1 {00BA} */\
    1199             RND_STEP_RORX_7(g,h,a,b,c,d,e,f,_i+2)\
    1200     VPADDD   (XTMP0, XTMP0, XTMP4)  /* XTMP0 = {..., ..., W[1], W[0]} */\
    1201             RND_STEP_RORX_8(g,h,a,b,c,d,e,f,_i+2)\
    1202 \
    1203             RND_STEP_RORX_1(f,g,h,a,b,c,d,e,_i+3)\
    1204     VPSHUFD  (XTMP2, XTMP0, 0b01010000) /* XTMP2 = W[-2] {DDCC} */\
    1205             RND_STEP_RORX_2(f,g,h,a,b,c,d,e,_i+3)\
    1206     VPSRLD   (XTMP5, XTMP2, 10)       /* XTMP5 = W[-2] >> 10 {DDCC} */\
    1207             RND_STEP_RORX_3(f,g,h,a,b,c,d,e,_i+3)\
    1208     VPSRLQ   (XTMP3, XTMP2, 19)       /* XTMP3 = W[-2] MY_ROR 19 {xDxC} */\
    1209             RND_STEP_RORX_4(f,g,h,a,b,c,d,e,_i+3)\
    1210     VPSRLQ   (XTMP2, XTMP2, 17)      /* XTMP2 = W[-2] MY_ROR 17 {xDxC} */\
    1211             RND_STEP_RORX_5(f,g,h,a,b,c,d,e,_i+3)\
    1212     VPXOR    (XTMP2, XTMP2, XTMP3)\
    1213             RND_STEP_RORX_6(f,g,h,a,b,c,d,e,_i+3)\
    1214     VPXOR    (XTMP5, XTMP5, XTMP2)   /* XTMP5 = s1 {xDxC} */\
    1215             RND_STEP_RORX_7(f,g,h,a,b,c,d,e,_i+3)\
    1216     VPSHUFB  (XTMP5, XTMP5, SHUF_DC00) /* XTMP5 = s1 {DC00} */\
    1217             RND_STEP_RORX_8(f,g,h,a,b,c,d,e,_i+3)\
    1218     VPADDD   (X0, XTMP5, XTMP0)      /* X0 = {W[3], W[2], W[1], W[0]} */\
     1606            RND_STEP_RORX_1_8(f,g,h,a,b,c,d,e,_i+3)                        \
     1607    VPADDD   (X0, XTMP5, XTMP0)      /* X0 = {W[3], W[2], W[1], W[0]} */
    12191608
    12201609#endif /* HAVE_INTEL_RORX */
    12211610
    12221611
    1223 #define W_K_from_buff()                      \
    1224     "leaq       %[buf], %%r8\n\t"            \
    1225     "vmovdqu      (%%r8), %%xmm4\n\t"        \
    1226     "vpshufb    %%xmm13, %%xmm4, %%xmm4\n\t" \
    1227     "vmovdqu    16(%%r8), %%xmm5\n\t"        \
    1228     "vpshufb    %%xmm13, %%xmm5, %%xmm5\n\t" \
    1229     "vmovdqu    32(%%r8), %%xmm6\n\t"        \
    1230     "vpshufb    %%xmm13, %%xmm6, %%xmm6\n\t" \
    1231     "vmovdqu    48(%%r8), %%xmm7\n\t"        \
    1232     "vpshufb    %%xmm13, %%xmm7, %%xmm7\n\t"
    1233 
    1234 #define _SET_W_K_XFER(reg, i)                        \
    1235     "leaq       %[K], %%r8\n\t"                      \
    1236     "vpaddd     ("#i")*4(%%r8), %"#reg", %%xmm9\n\t" \
    1237     "leaq       %[W_K], %%r8\n\t"                    \
    1238     "vmovdqa    %%xmm9, ("#i")*4(%%r8)\n\t"
    1239 
    1240 #define SET_W_K_XFER(reg, i) _SET_W_K_XFER(reg, i)
    1241 
    1242 static const ALIGN32 word64 mSHUF_00BA[] = { 0x0b0a090803020100, 0xFFFFFFFFFFFFFFFF }; /* shuffle xBxA -> 00BA */
    1243 static const ALIGN32 word64 mSHUF_DC00[] = { 0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100 }; /* shuffle xDxC -> DC00 */
    1244 static const ALIGN32 word64 mBYTE_FLIP_MASK[] =  { 0x0405060700010203, 0x0c0d0e0f08090a0b };
    1245 
     1612#define _W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK) \
     1613    "# X0, X1, X2, X3 = W[0..15]\n\t"                  \
     1614    "vmovdqu      (%%rax), %" #X0 "\n\t"               \
     1615    "vmovdqu    16(%%rax), %" #X1 "\n\t"               \
     1616    VPSHUFB(X0, X0, BYTE_FLIP_MASK)                    \
     1617    VPSHUFB(X1, X1, BYTE_FLIP_MASK)                    \
     1618    "vmovdqu    32(%%rax), %" #X2 "\n\t"               \
     1619    "vmovdqu    48(%%rax), %" #X3 "\n\t"               \
     1620    VPSHUFB(X2, X2, BYTE_FLIP_MASK)                    \
     1621    VPSHUFB(X3, X3, BYTE_FLIP_MASK)
     1622
     1623#define W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK) \
     1624       _W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK)
     1625
     1626
     1627#define _SET_W_K_XFER_4(i) \
     1628    "vpaddd     (" #i "*4)+ 0+%[K], %%xmm0, %%xmm4\n\t"  \
     1629    "vpaddd     (" #i "*4)+16+%[K], %%xmm1, %%xmm5\n\t"  \
     1630    "vmovdqu    %%xmm4,   (" WK ")\n\t"                  \
     1631    "vmovdqu    %%xmm5, 16(" WK ")\n\t"                  \
     1632    "vpaddd     (" #i "*4)+32+%[K], %%xmm2, %%xmm6\n\t"  \
     1633    "vpaddd     (" #i "*4)+48+%[K], %%xmm3, %%xmm7\n\t"  \
     1634    "vmovdqu    %%xmm6, 32(" WK ")\n\t"                  \
     1635    "vmovdqu    %%xmm7, 48(" WK ")\n\t"
     1636
     1637#define SET_W_K_XFER_4(i) \
     1638       _SET_W_K_XFER_4(i)
     1639
     1640
     1641static const ALIGN32 word64 mSHUF_00BA[] =
     1642    { 0x0b0a090803020100, 0xFFFFFFFFFFFFFFFF }; /* shuffle xBxA -> 00BA */
     1643static const ALIGN32 word64 mSHUF_DC00[] =
     1644    { 0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100 }; /* shuffle xDxC -> DC00 */
     1645static const ALIGN32 word64 mBYTE_FLIP_MASK[] =
     1646    { 0x0405060700010203, 0x0c0d0e0f08090a0b };
    12461647
    12471648#define _Init_Masks(mask1, mask2, mask3)     \
    1248     "vmovdqu    %[FLIP], %"#mask1"\n\t"      \
    1249     "vmovdqu    %[SHUF00BA], %"#mask2"\n\t"  \
    1250     "vmovdqu    %[SHUFDC00], %"#mask3"\n\t"
     1649    "vmovdqa    %[FLIP], %" #mask1 "\n\t"      \
     1650    "vmovdqa    %[SHUF00BA], %" #mask2 "\n\t"  \
     1651    "vmovdqa    %[SHUFDC00], %" #mask3 "\n\t"
    12511652
    12521653#define Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)\
    12531654    _Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
    12541655
    1255 #define X0 %xmm4
    1256 #define X1 %xmm5
    1257 #define X2 %xmm6
    1258 #define X3 %xmm7
    1259 #define X_ X0
    1260 
    1261 #define XTMP0 %xmm0
    1262 #define XTMP1 %xmm1
    1263 #define XTMP2 %xmm2
    1264 #define XTMP3 %xmm3
     1656#define X0 %xmm0
     1657#define X1 %xmm1
     1658#define X2 %xmm2
     1659#define X3 %xmm3
     1660
     1661#define XTMP0 %xmm4
     1662#define XTMP1 %xmm5
     1663#define XTMP2 %xmm6
     1664#define XTMP3 %xmm7
    12651665#define XTMP4 %xmm8
    12661666#define XTMP5 %xmm9
     
    12721672
    12731673
    1274 static int Transform_AVX1(wc_Sha256* sha256)
     1674SHA256_NOINLINE static int Transform_Sha256_AVX1(wc_Sha256* sha256)
    12751675{
    1276     ALIGN32 word32 W_K[64];  /* temp for W+K */
    1277 
    12781676    __asm__ __volatile__ (
    12791677
     1678        "subq   $64, %%rsp\n\t"
     1679
     1680        "leaq   32(%[sha256]), %%rax\n\t"
    12801681    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
    1281     "# X0, X1, X2, X3 = W[0..15]; \n\t"
    1282     W_K_from_buff()
    1283 
    1284     DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
    1285 
    1286     SET_W_K_XFER(X0, 0)
    1287     MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1288             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0)
    1289     SET_W_K_XFER(X1, 4)
    1290     MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1291             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,4)
    1292     SET_W_K_XFER(X2, 8)
    1293     MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1294             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8)
    1295     SET_W_K_XFER(X3, 12)
    1296     MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1297             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,12)
    1298     SET_W_K_XFER(X0, 16)
    1299     MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1300             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16)
    1301     SET_W_K_XFER(X1, 20)
    1302     MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1303             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,20)
    1304     SET_W_K_XFER(X2, 24)
    1305     MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1306             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24)
    1307     SET_W_K_XFER(X3, 28)
    1308     MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1309             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,28)
    1310     SET_W_K_XFER(X0, 32)
    1311     MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1312             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32)
    1313     SET_W_K_XFER(X1, 36)
    1314     MessageSched(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1315             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,36)
    1316     SET_W_K_XFER(X2, 40)
    1317     MessageSched(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1318             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40)
    1319     SET_W_K_XFER(X3, 44)
    1320     MessageSched(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1321             SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,44)
    1322 
    1323     SET_W_K_XFER(X0, 48)
    1324     SET_W_K_XFER(X1, 52)
    1325     SET_W_K_XFER(X2, 56)
    1326     SET_W_K_XFER(X3, 60)
    1327 
    1328     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48)
    1329     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49)
    1330     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50)
    1331     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51)
    1332 
    1333     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52)
    1334     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53)
    1335     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54)
    1336     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55)
    1337 
    1338     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56)
    1339     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57)
    1340     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58)
    1341     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59)
    1342 
    1343     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60)
    1344     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61)
    1345     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62)
    1346     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63)
    1347 
    1348     RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
     1682    LOAD_DIGEST()
     1683
     1684    W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK)
     1685
     1686        "movl   %%r9d, " L4 "\n\t"
     1687        "movl   %%r12d, " L1 "\n\t"
     1688        "xorl   %%r10d, " L4 "\n\t"
     1689
     1690    SET_W_K_XFER_4(0)
     1691    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1692    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1693    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1694    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1695
     1696    SET_W_K_XFER_4(16)
     1697    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1698    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1699    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1700    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1701
     1702    SET_W_K_XFER_4(32)
     1703    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1704    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1705    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1706    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1707
     1708    SET_W_K_XFER_4(48)
     1709    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1710    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1711    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1712    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1713
     1714    STORE_ADD_DIGEST()
     1715
     1716        "addq   $64, %%rsp\n\t"
    13491717
    13501718        :
     
    13521720          [SHUF00BA] "m" (mSHUF_00BA[0]),
    13531721          [SHUFDC00] "m" (mSHUF_DC00[0]),
    1354           [digest]   "m" (sha256->digest),
    1355           [buf]      "m" (sha256->buffer),
    1356           [K]        "m" (K),
    1357           [W_K]      "m" (W_K)
    1358         : SSE_REGs, "memory"
     1722          [sha256]   "r" (sha256),
     1723          [K]        "m" (K)
     1724        : WORK_REGS, STATE_REGS, XMM_REGS, "memory"
    13591725    );
    13601726
     
    13621728}
    13631729
    1364 #if defined(HAVE_INTEL_RORX)
    1365 static int Transform_AVX1_RORX(wc_Sha256* sha256)
     1730SHA256_NOINLINE static int Transform_Sha256_AVX1_Len(wc_Sha256* sha256,
     1731                                                     word32 len)
    13661732{
    1367     ALIGN32 word32 W_K[64];  /* temp for W+K */
    1368 
    13691733    __asm__ __volatile__ (
    13701734
     1735        "subq   $64, %%rsp\n\t"
     1736        "movq   120(%[sha256]), %%rax\n\t"
     1737
    13711738    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
    1372     "# X0, X1, X2, X3 = W[0..15]; \n\t"
    1373     W_K_from_buff()
    1374 
    1375     DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
    1376 
    1377     SET_W_K_XFER(X0, 0)
    1378     MessageSched(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5, XFER,
    1379             SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0)
    1380     SET_W_K_XFER(X1, 4)
    1381     MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1382             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,4)
    1383     SET_W_K_XFER(X2, 8)
    1384     MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1385             XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8)
    1386     SET_W_K_XFER(X3, 12)
    1387     MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1388             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,12)
    1389     SET_W_K_XFER(X0, 16)
    1390     MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1391             XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16)
    1392     SET_W_K_XFER(X1, 20)
    1393     MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1394             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,20)
    1395     SET_W_K_XFER(X2, 24)
    1396     MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1397             XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24)
    1398     SET_W_K_XFER(X3, 28)
    1399     MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1400             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,28)
    1401     SET_W_K_XFER(X0, 32)
    1402     MessageSched_RORX(X0, X1, X2, X3, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1403             XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32)
    1404     SET_W_K_XFER(X1, 36)
    1405     MessageSched_RORX(X1, X2, X3, X0, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1406             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,36)
    1407     SET_W_K_XFER(X2, 40)
    1408     MessageSched_RORX(X2, X3, X0, X1, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1409             XFER, SHUF_00BA, SHUF_DC00, S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40)
    1410     SET_W_K_XFER(X3, 44)
    1411     MessageSched_RORX(X3, X0, X1, X2, XTMP0, XTMP1, XTMP2, XTMP3, XTMP4, XTMP5,
    1412             XFER, SHUF_00BA, SHUF_DC00, S_4,S_5,S_6,S_7,S_0,S_1,S_2,S_3,44)
    1413 
    1414     SET_W_K_XFER(X0, 48)
    1415     SET_W_K_XFER(X1, 52)
    1416     SET_W_K_XFER(X2, 56)
    1417     SET_W_K_XFER(X3, 60)
    1418 
    1419     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48)
    1420     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49)
    1421     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50)
    1422     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51)
    1423 
    1424     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52)
    1425     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53)
    1426     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54)
    1427     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55)
    1428 
    1429     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56)
    1430     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57)
    1431     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58)
    1432     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59)
    1433 
    1434     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60)
    1435     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61)
    1436     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62)
    1437     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63)
    1438 
    1439     RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
     1739    LOAD_DIGEST()
     1740
     1741        "# Start of loop processing a block\n"
     1742        "1:\n\t"
     1743
     1744    W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK)
     1745
     1746        "movl   %%r9d, " L4 "\n\t"
     1747        "movl   %%r12d, " L1 "\n\t"
     1748        "xorl   %%r10d, " L4 "\n\t"
     1749
     1750    SET_W_K_XFER_4(0)
     1751    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1752    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1753    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1754    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1755
     1756    SET_W_K_XFER_4(16)
     1757    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1758    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1759    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1760    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1761
     1762    SET_W_K_XFER_4(32)
     1763    MsgSched(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1764    MsgSched(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1765    MsgSched(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1766    MsgSched(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1767
     1768    SET_W_K_XFER_4(48)
     1769    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1770    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1771    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1772    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1773        "movq   120(%[sha256]), %%rax\n\t"
     1774
     1775    ADD_DIGEST()
     1776
     1777        "addq   $64, %%rax\n\t"
     1778        "subl   $64, %[len]\n\t"
     1779
     1780    STORE_DIGEST()
     1781
     1782        "movq   %%rax, 120(%[sha256])\n\t"
     1783        "jnz    1b\n\t"
     1784
     1785        "addq   $64, %%rsp\n\t"
    14401786
    14411787        :
     
    14431789          [SHUF00BA] "m" (mSHUF_00BA[0]),
    14441790          [SHUFDC00] "m" (mSHUF_DC00[0]),
    1445           [digest]   "m" (sha256->digest),
    1446           [buf]      "m" (sha256->buffer),
    1447           [K]        "m" (K),
    1448           [W_K]      "m" (W_K)
    1449         : SSE_REGs, "memory"
     1791          [sha256]   "r" (sha256),
     1792          [len]      "r" (len),
     1793          [K]        "m" (K)
     1794        : WORK_REGS, STATE_REGS, XMM_REGS, "memory"
    14501795    );
    14511796
    14521797    return 0;
    14531798}
    1454 #endif  /* HAVE_INTEL_RORX */
    14551799#endif  /* HAVE_INTEL_AVX1 */
    14561800
    1457 
    1458 #if defined(HAVE_INTEL_AVX2)
    1459 
    1460 #define _MOVE_to_REG(ymm, mem, i) \
    1461     "leaq       %["#mem"], %%r8\n\t" \
    1462     "vmovdqu ("#i")*4(%%r8), %%"#ymm"\n\t"
    1463 #define _MOVE_to_MEM(mem, i, ymm) \
    1464     "leaq       %["#mem"], %%r8\n\t" \
    1465     "vmovdqu %%"#ymm",  "#i"*4(%%r8)\n\t"
    1466 #define _BYTE_SWAP(ymm, map)   \
    1467     "vpshufb %["#map"], %%"#ymm", %%"#ymm"\n\t"
    1468 #define _MOVE_128(ymm0, ymm1, ymm2, map) \
    1469     "vperm2i128  $"#map", %%"#ymm2", %%"#ymm1", %%"#ymm0"\n\t"
    1470 #define _MOVE_BYTE(ymm0, ymm1, map) \
    1471     "vpshufb %["#map"], %%"#ymm1", %%"#ymm0"\n\t"
    1472 #define _S_TEMP(dest, src, bits, temp) \
    1473     "vpsrld  $"#bits", %%"#src", %%"#dest"\n\t" \
    1474     "vpslld  $32-"#bits", %%"#src", %%"#temp"\n\t" \
    1475     "vpor %%"#temp",%%"#dest", %%"#dest"\n\t"
    1476 #define _AVX2_R(dest, src, bits) \
    1477     "vpsrld  $"#bits", %%"#src", %%"#dest"\n\t"
    1478 #define _XOR(dest, src1, src2) \
    1479     "vpxor   %%"#src1", %%"#src2", %%"#dest"\n\t"
    1480 #define _OR(dest, src1, src2) \
    1481     "vpor    %%"#src1", %%"#src2", %%"#dest"\n\t"
    1482 #define _ADD(dest, src1, src2) \
    1483     "vpaddd   %%"#src1", %%"#src2", %%"#dest"\n\t"
    1484 #define _ADD_MEM(dest, src1, mem, i) \
    1485     "leaq       %["#mem"], %%r8\n\t" \
    1486     "vpaddd   "#i"*4(%%r8), %%"#src1", %%"#dest"\n\t"
    1487 #define _BLEND(map, dest, src1, src2) \
    1488     "vpblendd    $"#map", %%"#src1",   %%"#src2", %%"#dest"\n\t"
    1489 
    1490 #define    _EXTRACT_XMM_0(xmm, mem) \
    1491     "vpextrd $0, %%"#xmm", %["#mem"]\n\t"
    1492 #define    _EXTRACT_XMM_1(xmm, mem) \
    1493     "vpextrd $1, %%"#xmm", %["#mem"]\n\t"
    1494 #define    _EXTRACT_XMM_2(xmm, mem) \
    1495     "vpextrd $2, %%"#xmm", %["#mem"]\n\t"
    1496 #define    _EXTRACT_XMM_3(xmm, mem) \
    1497     "vpextrd $3, %%"#xmm", %["#mem"]\n\t"
    1498 #define    _EXTRACT_XMM_4(ymm, xmm, mem) \
    1499     "vperm2i128 $0x1, %%"#ymm", %%"#ymm", %%"#ymm"\n\t" \
    1500     "vpextrd $0, %%"#xmm", %["#mem"]\n\t"
    1501 #define    _EXTRACT_XMM_5(xmm, mem) \
    1502     "vpextrd $1, %%"#xmm", %["#mem"]\n\t"
    1503 #define    _EXTRACT_XMM_6(xmm, mem) \
    1504     "vpextrd $2, %%"#xmm", %["#mem"]\n\t"
    1505 #define    _EXTRACT_XMM_7(xmm, mem) \
    1506     "vpextrd $3, %%"#xmm", %["#mem"]\n\t"
    1507 
    1508 #define    _SWAP_YMM_HL(ymm)  \
    1509     "vperm2i128 $0x1, %%"#ymm", %%"#ymm", %%"#ymm"\n\t"
    1510 #define     SWAP_YMM_HL(ymm)   _SWAP_YMM_HL(ymm)
    1511 
    1512 #define MOVE_to_REG(ymm, mem, i)   _MOVE_to_REG(ymm, mem, i)
    1513 #define MOVE_to_MEM(mem, i, ymm)   _MOVE_to_MEM(mem, i, ymm)
    1514 #define BYTE_SWAP(ymm, map)        _BYTE_SWAP(ymm, map)
    1515 #define MOVE_128(ymm0, ymm1, ymm2, map) _MOVE_128(ymm0, ymm1, ymm2, map)
    1516 #define MOVE_BYTE(ymm0, ymm1, map) _MOVE_BYTE(ymm0, ymm1, map)
    1517 #define XOR(dest, src1, src2)      _XOR(dest, src1, src2)
    1518 #define OR(dest, src1, src2)       _OR(dest, src1, src2)
    1519 #define ADD(dest, src1, src2)      _ADD(dest, src1, src2)
    1520 #define ADD_MEM(dest, src1, mem, i)  _ADD_MEM(dest, src1, mem, i)
    1521 #define BLEND(map, dest, src1, src2) _BLEND(map, dest, src1, src2)
    1522 
    1523 #define S_TMP(dest, src, bits, temp) _S_TEMP(dest, src, bits, temp)
    1524 #define AVX2_S(dest, src, bits)      S_TMP(dest, src, bits, S_TEMP)
    1525 #define AVX2_R(dest, src, bits)      _AVX2_R(dest, src, bits)
    1526 
    1527 #define GAMMA0(dest, src)      AVX2_S(dest, src, 7)  AVX2_S(G_TEMP, src, 18) \
    1528     XOR(dest, G_TEMP, dest) AVX2_R(G_TEMP, src, 3)  XOR(dest, G_TEMP, dest)
    1529 #define GAMMA0_1(dest, src)    AVX2_S(dest, src, 7)  AVX2_S(G_TEMP, src, 18)
    1530 #define GAMMA0_2(dest, src)    XOR(dest, G_TEMP, dest) AVX2_R(G_TEMP, src, 3)  \
    1531     XOR(dest, G_TEMP, dest)
    1532 
    1533 #define GAMMA1(dest, src)      AVX2_S(dest, src, 17) AVX2_S(G_TEMP, src, 19) \
    1534     XOR(dest, G_TEMP, dest) AVX2_R(G_TEMP, src, 10) XOR(dest, G_TEMP, dest)
    1535 #define GAMMA1_1(dest, src)    AVX2_S(dest, src, 17) AVX2_S(G_TEMP, src, 19)
    1536 #define GAMMA1_2(dest, src)    XOR(dest, G_TEMP, dest) AVX2_R(G_TEMP, src, 10) \
    1537     XOR(dest, G_TEMP, dest)
    1538 
    1539 #define    FEEDBACK1_to_W_I_2    MOVE_BYTE(YMM_TEMP0, W_I, MAP1W_2) \
    1540     BLEND(0x0c, W_I_2, YMM_TEMP0, W_I_2)
    1541 #define    FEEDBACK2_to_W_I_2    MOVE_128(YMM_TEMP0, W_I, W_I, 0x08)  \
    1542     MOVE_BYTE(YMM_TEMP0, YMM_TEMP0, MAP2W_2) BLEND(0x30, W_I_2, YMM_TEMP0, W_I_2)
    1543 #define    FEEDBACK3_to_W_I_2    MOVE_BYTE(YMM_TEMP0, W_I, MAP3W_2) \
    1544     BLEND(0xc0, W_I_2, YMM_TEMP0, W_I_2)
    1545 
    1546 #define    FEEDBACK_to_W_I_7     MOVE_128(YMM_TEMP0, W_I, W_I, 0x08)\
    1547     MOVE_BYTE(YMM_TEMP0, YMM_TEMP0, MAPW_7) BLEND(0x80, W_I_7, YMM_TEMP0, W_I_7)
    1548 
    1549 #undef voitle
    1550 
    1551 #define W_I_16  ymm8
    1552 #define W_I_15  ymm9
    1553 #define W_I_7  ymm10
    1554 #define W_I_2  ymm11
    1555 #define W_I    ymm12
    1556 #define G_TEMP     ymm13
    1557 #define S_TEMP     ymm14
    1558 #define YMM_TEMP0  ymm15
    1559 #define YMM_TEMP0x xmm15
    1560 #define W_I_TEMP   ymm7
    1561 #define W_K_TEMP   ymm15
    1562 #define W_K_TEMPx  xmm15
    1563 
    1564 #define MOVE_15_to_16(w_i_16, w_i_15, w_i_7)\
    1565     "vperm2i128 $0x01, %%"#w_i_15", %%"#w_i_15", %%"#w_i_15"\n\t" \
    1566     "vpblendd   $0x08, %%"#w_i_15", %%"#w_i_7",  %%"#w_i_16"\n\t" \
    1567     "vperm2i128 $0x01, %%"#w_i_7",  %%"#w_i_7",  %%"#w_i_15"\n\t" \
    1568     "vpblendd   $0x80, %%"#w_i_15", %%"#w_i_16", %%"#w_i_16"\n\t" \
    1569     "vpshufd    $0x93, %%"#w_i_16", %%"#w_i_16"\n\t"
    1570 
    1571 #define MOVE_7_to_15(w_i_15, w_i_7)\
    1572     "vmovdqu    %%"#w_i_7",  %%"#w_i_15"\n\t"
    1573 
    1574 #define MOVE_I_to_7(w_i_7, w_i)\
    1575     "vperm2i128 $0x01, %%"#w_i",   %%"#w_i", %%"#w_i_7"\n\t" \
    1576     "vpblendd   $0x01, %%"#w_i_7", %%"#w_i", %%"#w_i_7"\n\t" \
    1577     "vpshufd    $0x39, %%"#w_i_7", %%"#w_i_7"\n\t"
    1578 
    1579 #define MOVE_I_to_2(w_i_2, w_i)\
    1580     "vperm2i128 $0x01, %%"#w_i", %%"#w_i", %%"#w_i_2"\n\t" \
    1581     "vpshufd    $0x0e, %%"#w_i_2", %%"#w_i_2"\n\t"
    1582 
    1583 #define ROTATE_W(w_i_16, w_i_15, w_i_7, w_i_2, w_i)\
    1584     MOVE_15_to_16(w_i_16, w_i_15, w_i_7) \
    1585     MOVE_7_to_15(w_i_15, w_i_7) \
    1586     MOVE_I_to_7(w_i_7, w_i) \
    1587     MOVE_I_to_2(w_i_2, w_i)
    1588 
    1589 #define _DumpS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    1590   { word32 d[8];\
    1591     __asm__ volatile("movl %"#S_0", %0":"=r"(d[0])::SSE_REGs);\
    1592     __asm__ volatile("movl %"#S_1", %0":"=r"(d[1])::SSE_REGs);\
    1593     __asm__ volatile("movl %"#S_2", %0":"=r"(d[2])::SSE_REGs);\
    1594     __asm__ volatile("movl %"#S_3", %0":"=r"(d[3])::SSE_REGs);\
    1595     __asm__ volatile("movl %"#S_4", %0":"=r"(d[4])::SSE_REGs);\
    1596     __asm__ volatile("movl %"#S_5", %0":"=r"(d[5])::SSE_REGs);\
    1597     __asm__ volatile("movl %"#S_6", %0":"=r"(d[6])::SSE_REGs);\
    1598     __asm__ volatile("movl %"#S_7", %0":"=r"(d[7])::SSE_REGs);\
    1599         printf("S[0..7]=%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);\
    1600     __asm__ volatile("movl %0, %"#S_0::"r"(d[0]):SSE_REGs);\
    1601     __asm__ volatile("movl %0, %"#S_1::"r"(d[1]):SSE_REGs);\
    1602     __asm__ volatile("movl %0, %"#S_2::"r"(d[2]):SSE_REGs);\
    1603     __asm__ volatile("movl %0, %"#S_3::"r"(d[3]):SSE_REGs);\
    1604     __asm__ volatile("movl %0, %"#S_4::"r"(d[4]):SSE_REGs);\
    1605     __asm__ volatile("movl %0, %"#S_5::"r"(d[5]):SSE_REGs);\
    1606     __asm__ volatile("movl %0, %"#S_6::"r"(d[6]):SSE_REGs);\
    1607     __asm__ volatile("movl %0, %"#S_7::"r"(d[7]):SSE_REGs);\
    1608 }
    1609 
    1610 
    1611 #define DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    1612     _DigestToReg(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
    1613 
    1614 #define RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    1615     _RegToDigest(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
    1616 
    1617 #define DumS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )\
    1618     _DumpS(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7 )
    1619 
    1620 
    1621     /* Byte swap Masks to ensure that rest of the words are filled with zero's. */
    1622     static const unsigned long mBYTE_FLIP_MASK_16[] =
    1623         { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x0c0d0e0f08090a0b };
    1624     static const unsigned long mBYTE_FLIP_MASK_15[] =
    1625         { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x0c0d0e0f08090a0b };
    1626     static const unsigned long mBYTE_FLIP_MASK_7 [] =
    1627         { 0x0405060700010203, 0x0c0d0e0f08090a0b, 0x0405060700010203, 0x8080808008090a0b };
    1628     static const unsigned long mBYTE_FLIP_MASK_2 [] =
    1629         { 0x0405060700010203, 0x8080808080808080, 0x8080808080808080, 0x8080808080808080 };
    1630 
    1631     static const unsigned long mMAPtoW_I_7[] =
    1632         { 0x8080808080808080, 0x8080808080808080, 0x8080808080808080, 0x0302010080808080 };
    1633     static const unsigned long mMAP1toW_I_2[] =
    1634         { 0x8080808080808080, 0x0706050403020100, 0x8080808080808080, 0x8080808080808080 };
    1635     static const unsigned long mMAP2toW_I_2[] =
    1636         { 0x8080808080808080, 0x8080808080808080, 0x0f0e0d0c0b0a0908, 0x8080808080808080 };
    1637     static const unsigned long mMAP3toW_I_2[] =
    1638         { 0x8080808080808080, 0x8080808080808080, 0x8080808080808080, 0x0706050403020100 };
    1639 
    1640 static int Transform_AVX2(wc_Sha256* sha256)
     1801#if defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_RORX)
     1802SHA256_NOINLINE static int Transform_Sha256_AVX1_RORX(wc_Sha256* sha256)
    16411803{
    1642 #ifdef WOLFSSL_SMALL_STACK
    1643     word32* W_K;
    1644     W_K = (word32*) XMALLOC(sizeof(word32) * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    1645     if (W_K == NULL)
    1646         return MEMORY_E;
    1647 #else
    1648     word32 W_K[64];
    1649 #endif
    1650 
    16511804    __asm__ __volatile__ (
    16521805
    1653     MOVE_to_REG(W_I_16, buf, 0)     BYTE_SWAP(W_I_16, FLIP_16)
    1654     MOVE_to_REG(W_I_15, buf, 1)     BYTE_SWAP(W_I_15, FLIP_15)
    1655     MOVE_to_REG(W_I,    buf, 8)     BYTE_SWAP(W_I,    FLIP_16)
    1656     MOVE_to_REG(W_I_7,  buf, 16-7)  BYTE_SWAP(W_I_7,  FLIP_7)
    1657     MOVE_to_REG(W_I_2,  buf, 16-2)  BYTE_SWAP(W_I_2,  FLIP_2)
    1658 
    1659     DigestToReg(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
    1660 
    1661     ADD_MEM(W_K_TEMP, W_I_16, K, 0)
    1662     MOVE_to_MEM(W_K, 0, W_K_TEMP)
    1663 
    1664     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,0)
    1665     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,1)
    1666     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,2)
    1667     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,3)
    1668     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,4)
    1669     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,5)
    1670     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,6)
    1671     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,7)
    1672 
    1673     ADD_MEM(YMM_TEMP0, W_I, K, 8)
    1674     MOVE_to_MEM(W_K, 8, YMM_TEMP0)
    1675 
    1676     /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1677             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8)
    1678     GAMMA0_1(W_I_TEMP, W_I_15)
    1679             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8)
    1680     GAMMA0_2(W_I_TEMP, W_I_15)
    1681             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,8)
    1682     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1683             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9)
    1684     ADD(W_I, W_I_7, W_I_TEMP)
    1685             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9)
    1686     GAMMA1_1(YMM_TEMP0, W_I_2)
    1687             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,9)
    1688     GAMMA1_2(YMM_TEMP0, W_I_2)
    1689             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10)
    1690     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1691             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10)
    1692     FEEDBACK1_to_W_I_2
    1693             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,10)
    1694     FEEDBACK_to_W_I_7
    1695             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11)
    1696     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1697             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11)
    1698     GAMMA1_1(YMM_TEMP0, W_I_2)
    1699             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,11)
    1700     GAMMA1_2(YMM_TEMP0, W_I_2)
    1701             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12)
    1702     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1703             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12)
    1704     FEEDBACK2_to_W_I_2
    1705             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,12)
    1706     GAMMA1_1(YMM_TEMP0, W_I_2)
    1707             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13)
    1708     GAMMA1_2(YMM_TEMP0, W_I_2)
    1709             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13)
    1710     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1711             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,13)
    1712     FEEDBACK3_to_W_I_2
    1713             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14)
    1714     GAMMA1(YMM_TEMP0, W_I_2)
    1715             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14)
    1716             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,14)
    1717     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1718             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15)
    1719 
    1720     MOVE_to_REG(YMM_TEMP0, K, 16)
    1721             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15)
    1722     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1723             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,15)
    1724     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1725     MOVE_to_MEM(W_K, 16, YMM_TEMP0)
    1726 
    1727     /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1728             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16)
    1729     GAMMA0_1(W_I_TEMP, W_I_15)
    1730             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16)
    1731     GAMMA0_2(W_I_TEMP, W_I_15)
    1732             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,16)
    1733     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1734             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17)
    1735     ADD(W_I, W_I_7, W_I_TEMP)
    1736             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17)
    1737     GAMMA1_1(YMM_TEMP0, W_I_2)
    1738             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,17)
    1739     GAMMA1_2(YMM_TEMP0, W_I_2)
    1740             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18)
    1741     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1742             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18)
    1743     FEEDBACK1_to_W_I_2
    1744             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,18)
    1745     FEEDBACK_to_W_I_7
    1746             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19)
    1747     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1748             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19)
    1749     GAMMA1(YMM_TEMP0, W_I_2)
    1750             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,19)
    1751     GAMMA1_2(YMM_TEMP0, W_I_2)
    1752             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20)
    1753     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1754             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20)
    1755     FEEDBACK2_to_W_I_2
    1756             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,20)
    1757     GAMMA1_1(YMM_TEMP0, W_I_2)
    1758             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21)
    1759     GAMMA1_2(YMM_TEMP0, W_I_2)
    1760             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21)
    1761     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1762             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,21)
    1763     FEEDBACK3_to_W_I_2
    1764             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22)
    1765     GAMMA1_1(YMM_TEMP0, W_I_2)
    1766             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22)
    1767     GAMMA1_2(YMM_TEMP0, W_I_2)
    1768             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,22)
    1769     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1770             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23)
    1771 
    1772     MOVE_to_REG(YMM_TEMP0, K, 24)
    1773             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23)
    1774     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1775             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,23)
    1776     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1777     MOVE_to_MEM(W_K, 24, YMM_TEMP0)
    1778 
    1779             /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1780             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24)
    1781     GAMMA0_1(W_I_TEMP, W_I_15)
    1782             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24)
    1783     GAMMA0_2(W_I_TEMP, W_I_15)
    1784             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,24)
    1785     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1786             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25)
    1787     ADD(W_I, W_I_7, W_I_TEMP)
    1788             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25)
    1789     GAMMA1_1(YMM_TEMP0, W_I_2)
    1790             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,25)
    1791     GAMMA1_2(YMM_TEMP0, W_I_2)
    1792             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26)
    1793     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1794             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26)
    1795     FEEDBACK1_to_W_I_2
    1796             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,26)
    1797     FEEDBACK_to_W_I_7
    1798             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27)
    1799     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1800             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27)
    1801     GAMMA1_1(YMM_TEMP0, W_I_2)
    1802             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,27)
    1803     GAMMA1_2(YMM_TEMP0, W_I_2)
    1804             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28)
    1805     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1806             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28)
    1807     FEEDBACK2_to_W_I_2
    1808             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,28)
    1809     GAMMA1_1(YMM_TEMP0, W_I_2)
    1810             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29)
    1811     GAMMA1_2(YMM_TEMP0, W_I_2)
    1812             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29)
    1813     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1814             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,29)
    1815     FEEDBACK3_to_W_I_2
    1816             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30)
    1817     GAMMA1(YMM_TEMP0, W_I_2)
    1818             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30)
    1819             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,30)
    1820     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1821             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31)
    1822 
    1823     MOVE_to_REG(YMM_TEMP0, K, 32)
    1824             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31)
    1825     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1826             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,31)
    1827     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1828     MOVE_to_MEM(W_K, 32, YMM_TEMP0)
    1829 
    1830 
    1831             /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1832             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32)
    1833     GAMMA0_1(W_I_TEMP, W_I_15)
    1834             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32)
    1835     GAMMA0_2(W_I_TEMP, W_I_15)
    1836             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,32)
    1837     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1838             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33)
    1839     ADD(W_I, W_I_7, W_I_TEMP)
    1840             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33)
    1841     GAMMA1_1(YMM_TEMP0, W_I_2)
    1842             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,33)
    1843     GAMMA1_2(YMM_TEMP0, W_I_2)
    1844             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34)
    1845     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1846             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34)
    1847     FEEDBACK1_to_W_I_2
    1848             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,34)
    1849     FEEDBACK_to_W_I_7
    1850             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35)
    1851     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1852             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35)
    1853     GAMMA1_1(YMM_TEMP0, W_I_2)
    1854             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,35)
    1855     GAMMA1_2(YMM_TEMP0, W_I_2)
    1856             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36)
    1857     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1858             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36)
    1859     FEEDBACK2_to_W_I_2
    1860             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,36)
    1861     GAMMA1_1(YMM_TEMP0, W_I_2)
    1862             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37)
    1863     GAMMA1_2(YMM_TEMP0, W_I_2)
    1864             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37)
    1865     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1866             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,37)
    1867     FEEDBACK3_to_W_I_2
    1868             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38)
    1869     GAMMA1_1(YMM_TEMP0, W_I_2)
    1870             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38)
    1871     GAMMA1_2(YMM_TEMP0, W_I_2)
    1872             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,38)
    1873     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1874             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39)
    1875 
    1876     MOVE_to_REG(YMM_TEMP0, K, 40)
    1877             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39)
    1878     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1879             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,39)
    1880     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1881     MOVE_to_MEM(W_K, 40, YMM_TEMP0)
    1882 
    1883             /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1884             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40)
    1885     GAMMA0_1(W_I_TEMP, W_I_15)
    1886             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40)
    1887     GAMMA0_2(W_I_TEMP, W_I_15)
    1888             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,40)
    1889     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1890             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41)
    1891     ADD(W_I, W_I_7, W_I_TEMP)
    1892             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41)
    1893     GAMMA1_1(YMM_TEMP0, W_I_2)
    1894             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,41)
    1895     GAMMA1_2(YMM_TEMP0, W_I_2)
    1896             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42)
    1897     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1898             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42)
    1899     FEEDBACK1_to_W_I_2
    1900             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,42)
    1901     FEEDBACK_to_W_I_7
    1902             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43)
    1903     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1904             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43)
    1905     GAMMA1_1(YMM_TEMP0, W_I_2)
    1906             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,43)
    1907     GAMMA1_2(YMM_TEMP0, W_I_2)
    1908             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44)
    1909     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1910             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44)
    1911     FEEDBACK2_to_W_I_2
    1912             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,44)
    1913     GAMMA1_1(YMM_TEMP0, W_I_2)
    1914             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45)
    1915     GAMMA1_2(YMM_TEMP0, W_I_2)
    1916             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45)
    1917     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1918             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,45)
    1919     FEEDBACK3_to_W_I_2
    1920             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46)
    1921     GAMMA1_1(YMM_TEMP0, W_I_2)
    1922             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46)
    1923     GAMMA1_2(YMM_TEMP0, W_I_2)
    1924             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,46)
    1925     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1926             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47)
    1927 
    1928     MOVE_to_REG(YMM_TEMP0, K, 48)
    1929             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47)
    1930     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1931             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,47)
    1932     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1933     MOVE_to_MEM(W_K, 48, YMM_TEMP0)
    1934 
    1935             /* W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15] + W[i-16]) */
    1936             RND_0_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48)
    1937     GAMMA0_1(W_I_TEMP, W_I_15)
    1938             RND_0_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48)
    1939     GAMMA0_2(W_I_TEMP, W_I_15)
    1940             RND_0_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,48)
    1941     ADD(W_I_TEMP, W_I_16, W_I_TEMP)/* for saving W_I before adding incomplete W_I_7 */
    1942             RND_7_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49)
    1943     ADD(W_I, W_I_7, W_I_TEMP)
    1944             RND_7_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49)
    1945     GAMMA1_1(YMM_TEMP0, W_I_2)
    1946             RND_7_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,49)
    1947     GAMMA1_2(YMM_TEMP0, W_I_2)
    1948             RND_6_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50)
    1949     ADD(W_I, W_I, YMM_TEMP0)/* now W[16..17] are completed */
    1950             RND_6_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50)
    1951     FEEDBACK1_to_W_I_2
    1952             RND_6_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,50)
    1953     FEEDBACK_to_W_I_7
    1954             RND_5_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51)
    1955     ADD(W_I_TEMP, W_I_7, W_I_TEMP)
    1956             RND_5_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51)
    1957     GAMMA1_1(YMM_TEMP0, W_I_2)
    1958             RND_5_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,51)
    1959     GAMMA1_2(YMM_TEMP0, W_I_2)
    1960             RND_4_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52)
    1961     ADD(W_I, W_I_TEMP, YMM_TEMP0)/* now W[16..19] are completed */
    1962             RND_4_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52)
    1963     FEEDBACK2_to_W_I_2
    1964             RND_4_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,52)
    1965     GAMMA1_1(YMM_TEMP0, W_I_2)
    1966             RND_3_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53)
    1967     GAMMA1_2(YMM_TEMP0, W_I_2)
    1968             RND_3_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53)
    1969     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..21] are completed */
    1970             RND_3_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,53)
    1971     FEEDBACK3_to_W_I_2
    1972             RND_2_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54)
    1973     GAMMA1_1(YMM_TEMP0, W_I_2)
    1974             RND_2_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54)
    1975     GAMMA1_2(YMM_TEMP0, W_I_2)
    1976             RND_2_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,54)
    1977     ADD(W_I, W_I_TEMP, YMM_TEMP0) /* now W[16..23] are completed */
    1978             RND_1_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55)
    1979 
    1980     MOVE_to_REG(YMM_TEMP0, K, 56)
    1981             RND_1_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55)
    1982     ROTATE_W(W_I_16, W_I_15, W_I_7, W_I_2, W_I)
    1983             RND_1_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,55)
    1984     ADD(YMM_TEMP0, YMM_TEMP0, W_I)
    1985     MOVE_to_MEM(W_K, 56, YMM_TEMP0)
    1986 
    1987     RND_0(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,56)
    1988     RND_7(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,57)
    1989     RND_6(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,58)
    1990     RND_5(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,59)
    1991 
    1992     RND_4(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,60)
    1993     RND_3(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,61)
    1994     RND_2(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,62)
    1995     RND_1(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7,63)
    1996 
    1997     RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7)
     1806        "subq   $64, %%rsp\n\t"
     1807
     1808    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
     1809        "leaq   32(%[sha256]), %%rax\n\t"
     1810    W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK)
     1811
     1812    LOAD_DIGEST()
     1813
     1814    SET_W_K_XFER_4(0)
     1815        "movl   %%r9d, " L4 "\n\t"
     1816        "rorx   $6, %%r12d, " L1 "\n\t"
     1817        "xorl   %%r10d, " L4 "\n\t"
     1818    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1819    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1820    MsgSched_RORX(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1821    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1822
     1823    SET_W_K_XFER_4(16)
     1824    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1825    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1826    MsgSched_RORX(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1827    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1828
     1829    SET_W_K_XFER_4(32)
     1830    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1831    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1832    MsgSched_RORX(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1833    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1834
     1835    SET_W_K_XFER_4(48)
     1836        "xorl   " L3 ", " L3 "\n\t"
     1837    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1838    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1839    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1840    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1841        /* Prev RND: h += Maj(a,b,c) */
     1842        "addl   " L3 ", %%r8d\n\t"
     1843
     1844    STORE_ADD_DIGEST()
     1845
     1846        "addq   $64, %%rsp\n\t"
    19981847
    19991848        :
    2000         : [FLIP_16] "m" (mBYTE_FLIP_MASK_16[0]),
    2001           [FLIP_15] "m" (mBYTE_FLIP_MASK_15[0]),
    2002           [FLIP_7]  "m" (mBYTE_FLIP_MASK_7[0]),
    2003           [FLIP_2]  "m" (mBYTE_FLIP_MASK_2),
    2004           [MAPW_7]  "m" (mMAPtoW_I_7[0]),
    2005           [MAP1W_2] "m" (mMAP1toW_I_2[0]),
    2006           [MAP2W_2] "m" (mMAP2toW_I_2[0]),
    2007           [MAP3W_2] "m" (mMAP3toW_I_2[0]),
    2008           [digest]  "m" (sha256->digest),
    2009           [buf]     "m" (sha256->buffer),
    2010           [K]       "m" (K),
    2011           [W_K]     "m" (W_K)
    2012         : SSE_REGs, "memory"
     1849        : [FLIP]     "m" (mBYTE_FLIP_MASK[0]),
     1850          [SHUF00BA] "m" (mSHUF_00BA[0]),
     1851          [SHUFDC00] "m" (mSHUF_DC00[0]),
     1852          [sha256]   "r" (sha256),
     1853          [K]        "m" (K)
     1854        : WORK_REGS, STATE_REGS, XMM_REGS, "memory"
    20131855    );
    2014 
    2015 #ifdef WOLFSSL_SMALL_STACK
    2016     XFREE(W_K, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    2017 #endif
    20181856
    20191857    return 0;
    20201858}
    20211859
    2022 #endif   /* HAVE_INTEL_AVX2 */
     1860SHA256_NOINLINE static int Transform_Sha256_AVX1_RORX_Len(wc_Sha256* sha256,
     1861                                                          word32 len)
     1862{
     1863    __asm__ __volatile__ (
     1864
     1865        "subq   $64, %%rsp\n\t"
     1866        "movq   120(%[sha256]), %%rax\n\t"
     1867
     1868    Init_Masks(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
     1869    LOAD_DIGEST()
     1870
     1871        "# Start of loop processing a block\n"
     1872        "1:\n\t"
     1873
     1874    W_K_from_buff(X0, X1, X2, X3, BYTE_FLIP_MASK)
     1875
     1876    SET_W_K_XFER_4(0)
     1877        "movl   %%r9d, " L4 "\n\t"
     1878        "rorx   $6, %%r12d, " L1 "\n\t"
     1879        "xorl   %%r10d, " L4 "\n\t"
     1880    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1881    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1882    MsgSched_RORX(X2, X3, X0, X1, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  8)
     1883    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1884
     1885    SET_W_K_XFER_4(16)
     1886    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1887    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1888    MsgSched_RORX(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1889    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1890
     1891    SET_W_K_XFER_4(32)
     1892    MsgSched_RORX(X0, X1, X2, X3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1893    MsgSched_RORX(X1, X2, X3, X0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1894    MsgSched_RORX(X2, X3, X0, X1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1895    MsgSched_RORX(X3, X0, X1, X2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1896
     1897    SET_W_K_XFER_4(48)
     1898        "xorl   " L3 ", " L3 "\n\t"
     1899        "xorl   " L2 ", " L2 "\n\t"
     1900    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     1901    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  4)
     1902    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  8)
     1903    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 12)
     1904        /* Prev RND: h += Maj(a,b,c) */
     1905        "addl   " L3 ", %%r8d\n\t"
     1906        "movq   120(%[sha256]), %%rax\n\t"
     1907
     1908    ADD_DIGEST()
     1909
     1910        "addq   $64, %%rax\n\t"
     1911        "subl   $64, %[len]\n\t"
     1912
     1913    STORE_DIGEST()
     1914
     1915        "movq   %%rax, 120(%[sha256])\n\t"
     1916        "jnz    1b\n\t"
     1917
     1918        "addq   $64, %%rsp\n\t"
     1919
     1920        :
     1921        : [FLIP]     "m" (mBYTE_FLIP_MASK[0]),
     1922          [SHUF00BA] "m" (mSHUF_00BA[0]),
     1923          [SHUFDC00] "m" (mSHUF_DC00[0]),
     1924          [sha256]   "r" (sha256),
     1925          [len]      "r" (len),
     1926          [K]        "m" (K)
     1927        : WORK_REGS, STATE_REGS, XMM_REGS, "memory"
     1928    );
     1929
     1930    return 0;
     1931}
     1932#endif /* HAVE_INTEL_AVX2 && HAVE_INTEL_RORX */
     1933
     1934
     1935#if defined(HAVE_INTEL_AVX2)
     1936#define Y0 %ymm0
     1937#define Y1 %ymm1
     1938#define Y2 %ymm2
     1939#define Y3 %ymm3
     1940
     1941#define YTMP0 %ymm4
     1942#define YTMP1 %ymm5
     1943#define YTMP2 %ymm6
     1944#define YTMP3 %ymm7
     1945#define YTMP4 %ymm8
     1946#define YTMP5 %ymm9
     1947#define YXFER %ymm10
     1948
     1949#define SHUF_Y_00BA       %ymm11 /* shuffle xBxA -> 00BA */
     1950#define SHUF_Y_DC00       %ymm12 /* shuffle xDxC -> DC00 */
     1951#define BYTE_FLIP_Y_MASK  %ymm13
     1952
     1953#define YMM_REGS "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", \
     1954                 "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13"
     1955
     1956#define MsgSched_Y(Y0,Y1,Y2,Y3,a,b,c,d,e,f,g,h,_i)                            \
     1957            RND_STEP_0_1(a,b,c,d,e,f,g,h,_i)                                  \
     1958    VPALIGNR (YTMP1, Y1, Y0, 4)    /* YTMP1 = W[-15] */                       \
     1959    VPALIGNR (YTMP0, Y3, Y2, 4)    /* YTMP0 = W[-7] */                        \
     1960            RND_STEP_0_2(a,b,c,d,e,f,g,h,_i)                                  \
     1961            RND_STEP_0_3(a,b,c,d,e,f,g,h,_i)                                  \
     1962    VPSRLD   (YTMP2, YTMP1, 7)     /* YTMP2 = W[-15] >> 7 */                  \
     1963    VPSLLD   (YTMP3, YTMP1, 25)    /* YTEMP3 = W[-15] << (32-7) */            \
     1964            RND_STEP_0_4(a,b,c,d,e,f,g,h,_i)                                  \
     1965            RND_STEP_0_5(a,b,c,d,e,f,g,h,_i)                                  \
     1966    VPSRLD   (YTMP4, YTMP1, 18)    /* YTEMP4 = W[-15] >> 18 */                \
     1967    VPSLLD   (YTMP5, YTMP1, 14)    /* YTEMP5 = W[-15] << (32-18) */           \
     1968            RND_STEP_0_6(a,b,c,d,e,f,g,h,_i)                                  \
     1969            RND_STEP_0_7(a,b,c,d,e,f,g,h,_i)                                  \
     1970    VPOR     (YTMP2, YTMP3, YTMP2) /* YTMP2 = W[-15] >>> 7 */                 \
     1971    VPOR     (YTMP4, YTMP5, YTMP4) /* YTMP4 = W[-15] >>> 18 */                \
     1972            RND_STEP_0_8(a,b,c,d,e,f,g,h,_i)                                  \
     1973            RND_STEP_1_1(h,a,b,c,d,e,f,g,_i+1)                                \
     1974            RND_STEP_1_2(h,a,b,c,d,e,f,g,_i+1)                                \
     1975    VPSRLD   (YTMP5, YTMP1, 3)     /* YTMP4 = W[-15] >> 3 */                  \
     1976    VPXOR    (YTMP2, YTMP4, YTMP2) /* YTMP2 = W[-15] >>> 7 ^ W[-15] >>> 18 */ \
     1977            RND_STEP_1_3(h,a,b,c,d,e,f,g,_i+1)                                \
     1978            RND_STEP_1_4(h,a,b,c,d,e,f,g,_i+1)                                \
     1979    VPXOR    (YTMP1, YTMP5, YTMP2)  /* YTMP1 = s0 */                          \
     1980    VPSHUFD  (YTMP2, Y3, 0b11111010)  /* YTMP2 = W[-2] {BBAA}*/               \
     1981            RND_STEP_1_5(h,a,b,c,d,e,f,g,_i+1)                                \
     1982            RND_STEP_1_6(h,a,b,c,d,e,f,g,_i+1)                                \
     1983    VPSRLD   (YTMP4, YTMP2, 10)      /* YTMP4 = W[-2] >> 10 {BBAA} */         \
     1984    VPSRLQ   (YTMP3, YTMP2, 19)      /* YTMP3 = W[-2] MY_ROR 19 {xBxA} */     \
     1985            RND_STEP_1_7(h,a,b,c,d,e,f,g,_i+1)                                \
     1986            RND_STEP_1_8(h,a,b,c,d,e,f,g,_i+1)                                \
     1987            RND_STEP_0_1(g,h,a,b,c,d,e,f,_i+2)                                \
     1988    VPSRLQ   (YTMP2, YTMP2, 17)      /* YTMP2 = W[-2] MY_ROR 17 {xBxA} */     \
     1989    VPADDD   (YTMP0, YTMP0, Y0)                                               \
     1990            RND_STEP_0_2(g,h,a,b,c,d,e,f,_i+2)                                \
     1991            RND_STEP_0_3(g,h,a,b,c,d,e,f,_i+2)                                \
     1992            RND_STEP_0_4(g,h,a,b,c,d,e,f,_i+2)                                \
     1993    VPXOR    (YTMP2, YTMP3, YTMP2)                                            \
     1994    VPADDD   (YTMP0, YTMP0, YTMP1)  /* YTMP0 = W[-16] + W[-7] + s0 */         \
     1995            RND_STEP_0_5(g,h,a,b,c,d,e,f,_i+2)                                \
     1996    VPXOR    (YTMP4, YTMP4, YTMP2)   /* YTMP4 = s1 {xBxA} */                  \
     1997            RND_STEP_0_6(g,h,a,b,c,d,e,f,_i+2)                                \
     1998    VPSHUFB  (YTMP4, YTMP4, SHUF_Y_00BA)  /* YTMP4 = s1 {00BA} */             \
     1999            RND_STEP_0_7(g,h,a,b,c,d,e,f,_i+2)                                \
     2000    VPADDD   (YTMP0, YTMP0, YTMP4)  /* YTMP0 = {..., ..., W[1], W[0]} */      \
     2001            RND_STEP_0_8(g,h,a,b,c,d,e,f,_i+2)                                \
     2002            RND_STEP_1_1(f,g,h,a,b,c,d,e,_i+3)                                \
     2003    VPSHUFD  (YTMP2, YTMP0, 0b01010000) /* YTMP2 = W[-2] {DDCC} */            \
     2004            RND_STEP_1_2(f,g,h,a,b,c,d,e,_i+3)                                \
     2005    VPSRLQ   (YTMP4, YTMP2, 17)      /* YTMP4 = W[-2] MY_ROR 17 {xDxC} */     \
     2006    VPSRLQ   (YTMP3, YTMP2, 19)       /* YTMP3 = W[-2] MY_ROR 19 {xDxC} */    \
     2007            RND_STEP_1_3(f,g,h,a,b,c,d,e,_i+3)                                \
     2008            RND_STEP_1_4(f,g,h,a,b,c,d,e,_i+3)                                \
     2009    VPSRLD   (YTMP5, YTMP2, 10)       /* YTMP5 = W[-2] >> 10 {DDCC} */        \
     2010    VPXOR    (YTMP4, YTMP3, YTMP4)                                            \
     2011            RND_STEP_1_5(f,g,h,a,b,c,d,e,_i+3)                                \
     2012            RND_STEP_1_6(f,g,h,a,b,c,d,e,_i+3)                                \
     2013    VPXOR    (YTMP5, YTMP4, YTMP5)   /* YTMP5 = s1 {xDxC} */                  \
     2014            RND_STEP_1_7(f,g,h,a,b,c,d,e,_i+3)                                \
     2015    VPSHUFB  (YTMP5, YTMP5, SHUF_Y_DC00) /* YTMP5 = s1 {DC00} */              \
     2016            RND_STEP_1_8(f,g,h,a,b,c,d,e,_i+3)                                \
     2017    VPADDD   (Y0, YTMP5, YTMP0)      /* Y0 = {W[3], W[2], W[1], W[0]} */
     2018
     2019#if defined(HAVE_INTEL_RORX)
     2020
     2021#define MsgSched_Y_RORX(Y0,Y1,Y2,Y3,a,b,c,d,e,f,g,h,_i)                       \
     2022            RND_STEP_RORX_0_1(a,b,c,d,e,f,g,h,_i)                             \
     2023    VPALIGNR (YTMP1, Y1, Y0, 4)    /* YTMP1 = W[-15] */                       \
     2024            RND_STEP_RORX_0_2(a,b,c,d,e,f,g,h,_i)                             \
     2025    VPALIGNR (YTMP0, Y3, Y2, 4)    /* YTMP0 = W[-7] */                        \
     2026            RND_STEP_RORX_0_3(a,b,c,d,e,f,g,h,_i)                             \
     2027    VPSRLD   (YTMP2, YTMP1, 7)     /* YTMP2 = W[-15] >> 7 */                  \
     2028            RND_STEP_RORX_0_4(a,b,c,d,e,f,g,h,_i)                             \
     2029    VPSLLD   (YTMP3, YTMP1, 25)    /* YTEMP3 = W[-15] << (32-7) */            \
     2030            RND_STEP_RORX_0_5(a,b,c,d,e,f,g,h,_i)                             \
     2031    VPSRLD   (YTMP4, YTMP1, 18)    /* YTEMP4 = W[-15] >> 18 */                \
     2032            RND_STEP_RORX_0_6(a,b,c,d,e,f,g,h,_i)                             \
     2033    VPSLLD   (YTMP5, YTMP1, 14)    /* YTEMP5 = W[-15] << (32-18) */           \
     2034            RND_STEP_RORX_0_7(a,b,c,d,e,f,g,h,_i)                             \
     2035    VPOR     (YTMP2, YTMP2, YTMP3) /* YTMP2 = W[-15] >>> 7 */                 \
     2036            RND_STEP_RORX_0_8(a,b,c,d,e,f,g,h,_i)                             \
     2037    VPOR     (YTMP4, YTMP4, YTMP5) /* YTMP4 = W[-15] >>> 18 */                \
     2038            RND_STEP_RORX_1_1(h,a,b,c,d,e,f,g,_i+1)                           \
     2039    VPSRLD   (YTMP5, YTMP1, 3)     /* YTMP4 = W[-15] >> 3 */                  \
     2040            RND_STEP_RORX_1_2(h,a,b,c,d,e,f,g,_i+1)                           \
     2041    VPXOR    (YTMP2, YTMP2, YTMP4) /* YTMP2 = W[-15] >>> 7 ^ W[-15] >>> 18 */ \
     2042            RND_STEP_RORX_1_3(h,a,b,c,d,e,f,g,_i+1)                           \
     2043    VPSHUFD  (YTMP3, Y3, 0b11111010)  /* YTMP2 = W[-2] {BBAA}*/               \
     2044            RND_STEP_RORX_1_4(h,a,b,c,d,e,f,g,_i+1)                           \
     2045    VPXOR    (YTMP1, YTMP5, YTMP2)  /* YTMP1 = s0 */                          \
     2046            RND_STEP_RORX_1_5(h,a,b,c,d,e,f,g,_i+1)                           \
     2047    VPSRLD   (YTMP4, YTMP3, 10)      /* YTMP4 = W[-2] >> 10 {BBAA} */         \
     2048            RND_STEP_RORX_1_6(h,a,b,c,d,e,f,g,_i+1)                           \
     2049    VPSRLQ   (YTMP2, YTMP3, 19)      /* YTMP3 = W[-2] MY_ROR 19 {xBxA} */     \
     2050            RND_STEP_RORX_1_7(h,a,b,c,d,e,f,g,_i+1)                           \
     2051    VPSRLQ   (YTMP3, YTMP3, 17)      /* YTMP2 = W[-2] MY_ROR 17 {xBxA} */     \
     2052            RND_STEP_RORX_1_8(h,a,b,c,d,e,f,g,_i+1)                           \
     2053    VPADDD   (YTMP0, YTMP0, Y0)                                               \
     2054            RND_STEP_RORX_0_1(g,h,a,b,c,d,e,f,_i+2)                           \
     2055    VPXOR    (YTMP2, YTMP2, YTMP3)                                            \
     2056            RND_STEP_RORX_0_2(g,h,a,b,c,d,e,f,_i+2)                           \
     2057    VPXOR    (YTMP4, YTMP4, YTMP2)   /* YTMP4 = s1 {xBxA} */                  \
     2058            RND_STEP_RORX_0_3(g,h,a,b,c,d,e,f,_i+2)                           \
     2059    VPADDD   (YTMP0, YTMP0, YTMP1)  /* YTMP0 = W[-16] + W[-7] + s0 */         \
     2060            RND_STEP_RORX_0_4(g,h,a,b,c,d,e,f,_i+2)                           \
     2061    VPSHUFB  (YTMP4, YTMP4, SHUF_Y_00BA)  /* YTMP4 = s1 {00BA} */             \
     2062            RND_STEP_RORX_0_5(g,h,a,b,c,d,e,f,_i+2)                           \
     2063    VPADDD   (YTMP0, YTMP0, YTMP4)  /* YTMP0 = {..., ..., W[1], W[0]} */      \
     2064            RND_STEP_RORX_0_6(g,h,a,b,c,d,e,f,_i+2)                           \
     2065    VPSHUFD  (YTMP2, YTMP0, 0b01010000) /* YTMP2 = W[-2] {DDCC} */            \
     2066            RND_STEP_RORX_0_7(g,h,a,b,c,d,e,f,_i+2)                           \
     2067            RND_STEP_RORX_0_8(g,h,a,b,c,d,e,f,_i+2)                           \
     2068    VPSRLQ   (YTMP4, YTMP2, 17)      /* YTMP4 = W[-2] MY_ROR 17 {xDxC} */     \
     2069            RND_STEP_RORX_1_1(f,g,h,a,b,c,d,e,_i+3)                           \
     2070    VPSRLQ   (YTMP3, YTMP2, 19)       /* YTMP3 = W[-2] MY_ROR 19 {xDxC} */    \
     2071            RND_STEP_RORX_1_2(f,g,h,a,b,c,d,e,_i+3)                           \
     2072    VPSRLD   (YTMP5, YTMP2, 10)       /* YTMP5 = W[-2] >> 10 {DDCC} */        \
     2073            RND_STEP_RORX_1_3(f,g,h,a,b,c,d,e,_i+3)                           \
     2074    VPXOR    (YTMP4, YTMP4, YTMP3)                                            \
     2075            RND_STEP_RORX_1_4(f,g,h,a,b,c,d,e,_i+3)                           \
     2076    VPXOR    (YTMP5, YTMP5, YTMP4)   /* YTMP5 = s1 {xDxC} */                  \
     2077            RND_STEP_RORX_1_5(f,g,h,a,b,c,d,e,_i+3)                           \
     2078            RND_STEP_RORX_1_6(f,g,h,a,b,c,d,e,_i+3)                           \
     2079    VPSHUFB  (YTMP5, YTMP5, SHUF_Y_DC00) /* YTMP5 = s1 {DC00} */              \
     2080            RND_STEP_RORX_1_7(f,g,h,a,b,c,d,e,_i+3)                           \
     2081            RND_STEP_RORX_1_8(f,g,h,a,b,c,d,e,_i+3)                           \
     2082    VPADDD   (Y0, YTMP5, YTMP0)      /* Y0 = {W[3], W[2], W[1], W[0]} */      \
     2083
     2084#endif /* HAVE_INTEL_RORX */
     2085
     2086#define _VINSERTI128(op1,op2,op3,op4) \
     2087    "vinserti128        $" #op4 ", %" #op3 ", %" #op2 ", %" #op1 "\n\t"
     2088#define VINSERTI128(op1,op2,op3,op4)  \
     2089       _VINSERTI128(op1,op2,op3,op4)
     2090
     2091
     2092#define _LOAD_W_K_LOW(BYTE_FLIP_MASK, reg)   \
     2093    "# X0, X1, X2, X3 = W[0..15]\n\t"        \
     2094    "vmovdqu      (%%" #reg "), %%xmm0\n\t"  \
     2095    "vmovdqu    16(%%" #reg "), %%xmm1\n\t"  \
     2096    VPSHUFB(X0, X0, BYTE_FLIP_MASK)          \
     2097    VPSHUFB(X1, X1, BYTE_FLIP_MASK)          \
     2098    "vmovdqu    32(%%" #reg "), %%xmm2\n\t"  \
     2099    "vmovdqu    48(%%" #reg "), %%xmm3\n\t"  \
     2100    VPSHUFB(X2, X2, BYTE_FLIP_MASK)          \
     2101    VPSHUFB(X3, X3, BYTE_FLIP_MASK)
     2102
     2103#define LOAD_W_K_LOW(BYTE_FLIP_MASK, reg) \
     2104       _LOAD_W_K_LOW(BYTE_FLIP_MASK, reg)
     2105
     2106
     2107#define _LOAD_W_K(BYTE_FLIP_Y_MASK, reg)      \
     2108    "# X0, X1, X2, X3 = W[0..15]\n\t"         \
     2109    "vmovdqu       (%%" #reg "), %%xmm0\n\t"  \
     2110    "vmovdqu     16(%%" #reg "), %%xmm1\n\t"  \
     2111    "vmovdqu     64(%%" #reg "), %%xmm4\n\t"  \
     2112    "vmovdqu     80(%%" #reg "), %%xmm5\n\t"  \
     2113    VINSERTI128(Y0, Y0, XTMP0, 1)             \
     2114    VINSERTI128(Y1, Y1, XTMP1, 1)             \
     2115    VPSHUFB(Y0, Y0, BYTE_FLIP_Y_MASK)         \
     2116    VPSHUFB(Y1, Y1, BYTE_FLIP_Y_MASK)         \
     2117    "vmovdqu     32(%%" #reg "), %%xmm2\n\t"  \
     2118    "vmovdqu     48(%%" #reg "), %%xmm3\n\t"  \
     2119    "vmovdqu     96(%%" #reg "), %%xmm6\n\t"  \
     2120    "vmovdqu    112(%%" #reg "), %%xmm7\n\t"  \
     2121    VINSERTI128(Y2, Y2, XTMP2, 1)             \
     2122    VINSERTI128(Y3, Y3, XTMP3, 1)             \
     2123    VPSHUFB(Y2, Y2, BYTE_FLIP_Y_MASK)         \
     2124    VPSHUFB(Y3, Y3, BYTE_FLIP_Y_MASK)
     2125
     2126#define LOAD_W_K(BYTE_FLIP_Y_MASK, reg) \
     2127       _LOAD_W_K(BYTE_FLIP_Y_MASK, reg)
     2128
     2129
     2130#define _SET_W_Y_4(i)  \
     2131    "vpaddd     (" #i "*8)+ 0+%[K], %%ymm0, %%ymm4\n\t" \
     2132    "vpaddd     (" #i "*8)+32+%[K], %%ymm1, %%ymm5\n\t" \
     2133    "vmovdqu    %%ymm4, (" #i "*8)+ 0(" WK ")\n\t"      \
     2134    "vmovdqu    %%ymm5, (" #i "*8)+32(" WK ")\n\t"      \
     2135    "vpaddd     (" #i "*8)+64+%[K], %%ymm2, %%ymm4\n\t" \
     2136    "vpaddd     (" #i "*8)+96+%[K], %%ymm3, %%ymm5\n\t" \
     2137    "vmovdqu    %%ymm4, (" #i "*8)+64(" WK ")\n\t"      \
     2138    "vmovdqu    %%ymm5, (" #i "*8)+96(" WK ")\n\t"
     2139
     2140#define SET_W_Y_4(i) \
     2141       _SET_W_Y_4(i)
     2142
     2143
     2144static const ALIGN32 word64 mSHUF_Y_00BA[] =
     2145    { 0x0b0a090803020100, 0xFFFFFFFFFFFFFFFF,
     2146      0x0b0a090803020100, 0xFFFFFFFFFFFFFFFF }; /* shuffle xBxA -> 00BA */
     2147static const ALIGN32 word64 mSHUF_Y_DC00[] =
     2148    { 0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100,
     2149      0xFFFFFFFFFFFFFFFF, 0x0b0a090803020100 }; /* shuffle xDxC -> DC00 */
     2150static const ALIGN32 word64 mBYTE_FLIP_Y_MASK[] =
     2151    { 0x0405060700010203, 0x0c0d0e0f08090a0b,
     2152      0x0405060700010203, 0x0c0d0e0f08090a0b };
     2153
     2154#define _INIT_MASKS_Y(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00) \
     2155    "vmovdqa    %[FLIP], %" #BYTE_FLIP_MASK "\n\t"          \
     2156    "vmovdqa    %[SHUF00BA], %" #SHUF_00BA "\n\t"           \
     2157    "vmovdqa    %[SHUFDC00], %" #SHUF_DC00 "\n\t"
     2158
     2159#define INIT_MASKS_Y(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00) \
     2160       _INIT_MASKS_Y(BYTE_FLIP_MASK, SHUF_00BA, SHUF_DC00)
     2161
     2162static const ALIGN32 word32 K256[128] = {
     2163    0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L,
     2164    0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L,
     2165    0x3956C25BL, 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L,
     2166    0x3956C25BL, 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L,
     2167    0xD807AA98L, 0x12835B01L, 0x243185BEL, 0x550C7DC3L,
     2168    0xD807AA98L, 0x12835B01L, 0x243185BEL, 0x550C7DC3L,
     2169    0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, 0xC19BF174L,
     2170    0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L, 0xC19BF174L,
     2171    0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
     2172    0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
     2173    0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL,
     2174    0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL,
     2175    0x983E5152L, 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L,
     2176    0x983E5152L, 0xA831C66DL, 0xB00327C8L, 0xBF597FC7L,
     2177    0xC6E00BF3L, 0xD5A79147L, 0x06CA6351L, 0x14292967L,
     2178    0xC6E00BF3L, 0xD5A79147L, 0x06CA6351L, 0x14292967L,
     2179    0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, 0x53380D13L,
     2180    0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL, 0x53380D13L,
     2181    0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
     2182    0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
     2183    0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L,
     2184    0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L,
     2185    0xD192E819L, 0xD6990624L, 0xF40E3585L, 0x106AA070L,
     2186    0xD192E819L, 0xD6990624L, 0xF40E3585L, 0x106AA070L,
     2187    0x19A4C116L, 0x1E376C08L, 0x2748774CL, 0x34B0BCB5L,
     2188    0x19A4C116L, 0x1E376C08L, 0x2748774CL, 0x34B0BCB5L,
     2189    0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, 0x682E6FF3L,
     2190    0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL, 0x682E6FF3L,
     2191    0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
     2192    0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
     2193    0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L,
     2194    0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
     2195};
     2196
     2197SHA256_NOINLINE static int Transform_Sha256_AVX2(wc_Sha256* sha256)
     2198{
     2199    __asm__ __volatile__ (
     2200
     2201        "subq   $512, %%rsp\n\t"
     2202        "leaq   32(%[sha256]), %%rax\n\t"
     2203
     2204    INIT_MASKS_Y(BYTE_FLIP_MASK, SHUF_Y_00BA, SHUF_Y_DC00)
     2205    LOAD_DIGEST()
     2206
     2207    LOAD_W_K_LOW(BYTE_FLIP_MASK, rax)
     2208
     2209        "movl   %%r9d, " L4 "\n\t"
     2210        "movl   %%r12d, " L1 "\n\t"
     2211        "xorl   %%r10d, " L4 "\n\t"
     2212
     2213    SET_W_Y_4(0)
     2214    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     2215    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  8)
     2216    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 16)
     2217    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 24)
     2218
     2219    SET_W_Y_4(16)
     2220    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 32)
     2221    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 40)
     2222    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 48)
     2223    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 56)
     2224
     2225    SET_W_Y_4(32)
     2226    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 64)
     2227    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 72)
     2228    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 80)
     2229    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 88)
     2230
     2231    SET_W_Y_4(48)
     2232    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  96)
     2233    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 104)
     2234    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 112)
     2235    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 120)
     2236
     2237    STORE_ADD_DIGEST()
     2238
     2239        "addq   $512, %%rsp\n\t"
     2240
     2241        :
     2242        : [FLIP]     "m" (mBYTE_FLIP_MASK[0]),
     2243          [SHUF00BA] "m" (mSHUF_Y_00BA[0]),
     2244          [SHUFDC00] "m" (mSHUF_Y_DC00[0]),
     2245          [sha256]   "r" (sha256),
     2246          [K]        "m" (K256)
     2247        : WORK_REGS, STATE_REGS, YMM_REGS, "memory"
     2248    );
     2249
     2250    return 0;
     2251}
     2252
     2253SHA256_NOINLINE static int Transform_Sha256_AVX2_Len(wc_Sha256* sha256,
     2254                                                     word32 len)
     2255{
     2256    if ((len & WC_SHA256_BLOCK_SIZE) != 0) {
     2257        XMEMCPY(sha256->buffer, sha256->data, WC_SHA256_BLOCK_SIZE);
     2258        Transform_Sha256_AVX2(sha256);
     2259        sha256->data += WC_SHA256_BLOCK_SIZE;
     2260        len -= WC_SHA256_BLOCK_SIZE;
     2261        if (len == 0)
     2262    return 0;
     2263}
     2264
     2265    __asm__ __volatile__ (
     2266
     2267        "subq   $512, %%rsp\n\t"
     2268        "movq   120(%[sha256]), %%rax\n\t"
     2269
     2270    INIT_MASKS_Y(BYTE_FLIP_Y_MASK, SHUF_Y_00BA, SHUF_Y_DC00)
     2271    LOAD_DIGEST()
     2272
     2273        "# Start of loop processing two blocks\n"
     2274        "1:\n\t"
     2275
     2276    LOAD_W_K(BYTE_FLIP_Y_MASK, rax)
     2277
     2278        "movl   %%r9d, " L4 "\n\t"
     2279        "movl   %%r12d, " L1 "\n\t"
     2280        "xorl   %%r10d, " L4 "\n\t"
     2281
     2282    SET_W_Y_4(0)
     2283    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     2284    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  8)
     2285    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 16)
     2286    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 24)
     2287
     2288    SET_W_Y_4(16)
     2289    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 32)
     2290    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 40)
     2291    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 48)
     2292    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 56)
     2293
     2294    SET_W_Y_4(32)
     2295    MsgSched_Y(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 64)
     2296    MsgSched_Y(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 72)
     2297    MsgSched_Y(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 80)
     2298    MsgSched_Y(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 88)
     2299
     2300    SET_W_Y_4(48)
     2301    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  96)
     2302    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 104)
     2303    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 112)
     2304    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 120)
     2305
     2306    ADD_DIGEST()
     2307    STORE_DIGEST()
     2308
     2309        "movl   %%r9d, " L4 "\n\t"
     2310        "movl   %%r12d, " L1 "\n\t"
     2311        "xorl   %%r10d, " L4 "\n\t"
     2312
     2313    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,   4)
     2314    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  12)
     2315    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  20)
     2316    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  28)
     2317    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  36)
     2318    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  44)
     2319    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  52)
     2320    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  60)
     2321    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  68)
     2322    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  76)
     2323    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  84)
     2324    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  92)
     2325    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 100)
     2326    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 108)
     2327    RND_ALL_4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 116)
     2328    RND_ALL_4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 124)
     2329
     2330    ADD_DIGEST()
     2331
     2332        "movq   120(%[sha256]), %%rax\n\t"
     2333        "addq   $128, %%rax\n\t"
     2334        "subl   $128, %[len]\n\t"
     2335
     2336    STORE_DIGEST()
     2337
     2338        "movq   %%rax, 120(%[sha256])\n\t"
     2339        "jnz    1b\n\t"
     2340
     2341        "addq   $512, %%rsp\n\t"
     2342
     2343        :
     2344        : [FLIP]     "m" (mBYTE_FLIP_Y_MASK[0]),
     2345          [SHUF00BA] "m" (mSHUF_Y_00BA[0]),
     2346          [SHUFDC00] "m" (mSHUF_Y_DC00[0]),
     2347          [sha256]   "r" (sha256),
     2348          [len]      "r" (len),
     2349          [K]        "m" (K256)
     2350        : WORK_REGS, STATE_REGS, YMM_REGS, "memory"
     2351    );
     2352
     2353    return 0;
     2354        }
     2355
     2356#if defined(HAVE_INTEL_RORX)
     2357SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX(wc_Sha256* sha256)
     2358{
     2359    __asm__ __volatile__ (
     2360
     2361        "subq   $512, %%rsp\n\t"
     2362        "leaq   32(%[sha256]), %%rax\n\t"
     2363
     2364    INIT_MASKS_Y(BYTE_FLIP_MASK, SHUF_Y_00BA, SHUF_Y_DC00)
     2365    LOAD_W_K_LOW(BYTE_FLIP_MASK, rax)
     2366
     2367    LOAD_DIGEST()
     2368
     2369        "movl   %%r9d, " L4 "\n\t"
     2370        "rorx   $6, %%r12d, " L1 "\n\t"
     2371        "xorl   %%r10d, " L4 "\n\t"
     2372
     2373    SET_W_Y_4(0)
     2374    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     2375    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  8)
     2376    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 16)
     2377    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 24)
     2378
     2379    SET_W_Y_4(16)
     2380    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 32)
     2381    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 40)
     2382    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 48)
     2383    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 56)
     2384
     2385    SET_W_Y_4(32)
     2386    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 64)
     2387    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 72)
     2388    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 80)
     2389    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 88)
     2390
     2391    SET_W_Y_4(48)
     2392        "xorl   " L3 ", " L3 "\n\t"
     2393        "xorl   " L2 ", " L2 "\n\t"
     2394    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  96)
     2395    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 104)
     2396    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 112)
     2397    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 120)
     2398        /* Prev RND: h += Maj(a,b,c) */
     2399        "addl   " L3 ", %%r8d\n\t"
     2400
     2401    STORE_ADD_DIGEST()
     2402
     2403        "addq   $512, %%rsp\n\t"
     2404
     2405        :
     2406        : [FLIP]     "m" (mBYTE_FLIP_MASK[0]),
     2407          [SHUF00BA] "m" (mSHUF_Y_00BA[0]),
     2408          [SHUFDC00] "m" (mSHUF_Y_DC00[0]),
     2409          [sha256]   "r" (sha256),
     2410          [K]        "m" (K256)
     2411        : WORK_REGS, STATE_REGS, YMM_REGS, "memory"
     2412    );
     2413
     2414        return 0;
     2415    }
     2416
     2417SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256,
     2418                                                          word32 len)
     2419    {
     2420    if ((len & WC_SHA256_BLOCK_SIZE) != 0) {
     2421        XMEMCPY(sha256->buffer, sha256->data, WC_SHA256_BLOCK_SIZE);
     2422        Transform_Sha256_AVX2_RORX(sha256);
     2423        sha256->data += WC_SHA256_BLOCK_SIZE;
     2424        len -= WC_SHA256_BLOCK_SIZE;
     2425        if (len == 0)
     2426            return 0;
     2427    }
     2428
     2429    __asm__ __volatile__ (
     2430
     2431        "subq   $512, %%rsp\n\t"
     2432        "movq   120(%[sha256]), %%rax\n\t"
     2433
     2434    INIT_MASKS_Y(BYTE_FLIP_Y_MASK, SHUF_Y_00BA, SHUF_Y_DC00)
     2435    LOAD_DIGEST()
     2436
     2437        "# Start of loop processing two blocks\n"
     2438        "1:\n\t"
     2439
     2440    LOAD_W_K(BYTE_FLIP_Y_MASK, rax)
     2441
     2442        "movl   %%r9d, " L4 "\n\t"
     2443        "rorx   $6, %%r12d, " L1 "\n\t"
     2444        "xorl   %%r10d, " L4 "\n\t"
     2445
     2446    SET_W_Y_4(0)
     2447    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  0)
     2448    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  8)
     2449    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 16)
     2450    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 24)
     2451
     2452    SET_W_Y_4(16)
     2453    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 32)
     2454    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 40)
     2455    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 48)
     2456    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 56)
     2457
     2458    SET_W_Y_4(32)
     2459    MsgSched_Y_RORX(Y0, Y1, Y2, Y3, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 64)
     2460    MsgSched_Y_RORX(Y1, Y2, Y3, Y0, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 72)
     2461    MsgSched_Y_RORX(Y2, Y3, Y0, Y1, S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 80)
     2462    MsgSched_Y_RORX(Y3, Y0, Y1, Y2, S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 88)
     2463
     2464    SET_W_Y_4(48)
     2465        "xorl   " L3 ", " L3 "\n\t"
     2466        "xorl   " L2 ", " L2 "\n\t"
     2467    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  96)
     2468    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 104)
     2469    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 112)
     2470    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 120)
     2471        /* Prev RND: h += Maj(a,b,c) */
     2472        "addl   " L3 ", %%r8d\n\t"
     2473        "xorl   " L2 ", " L2 "\n\t"
     2474
     2475    ADD_DIGEST()
     2476    STORE_DIGEST()
     2477
     2478        "movl   %%r9d, " L4 "\n\t"
     2479        "xorl   " L3 ", " L3 "\n\t"
     2480        "xorl   %%r10d, " L4 "\n\t"
     2481
     2482    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,   4)
     2483    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  12)
     2484    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  20)
     2485    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  28)
     2486    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  36)
     2487    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  44)
     2488    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  52)
     2489    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  60)
     2490    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  68)
     2491    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  76)
     2492    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7,  84)
     2493    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3,  92)
     2494    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 100)
     2495    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 108)
     2496    RND_RORX_X4(S_0, S_1, S_2, S_3, S_4, S_5, S_6, S_7, 116)
     2497    RND_RORX_X4(S_4, S_5, S_6, S_7, S_0, S_1, S_2, S_3, 124)
     2498        /* Prev RND: h += Maj(a,b,c) */
     2499        "addl   " L3 ", %%r8d\n\t"
     2500        "movq   120(%[sha256]), %%rax\n\t"
     2501
     2502    ADD_DIGEST()
     2503
     2504        "addq   $128, %%rax\n\t"
     2505        "subl   $128, %[len]\n\t"
     2506
     2507    STORE_DIGEST()
     2508
     2509        "movq   %%rax, 120(%[sha256])\n\t"
     2510        "jnz    1b\n\t"
     2511
     2512        "addq   $512, %%rsp\n\t"
     2513
     2514        :
     2515        : [FLIP]     "m" (mBYTE_FLIP_Y_MASK[0]),
     2516          [SHUF00BA] "m" (mSHUF_Y_00BA[0]),
     2517          [SHUFDC00] "m" (mSHUF_Y_DC00[0]),
     2518          [sha256]   "r" (sha256),
     2519          [len]      "r" (len),
     2520          [K]        "m" (K256)
     2521        : WORK_REGS, STATE_REGS, YMM_REGS, "memory"
     2522    );
     2523
     2524    return 0;
     2525                }
     2526#endif  /* HAVE_INTEL_RORX */
     2527#endif  /* HAVE_INTEL_AVX2 */
    20232528
    20242529
    20252530#ifdef WOLFSSL_SHA224
    20262531
    2027 #ifdef STM32_HASH
    2028 
    2029     #define Sha256Update Sha224Update
    2030     #define Sha256Final  Sha224Final
    2031 
    2032     /*
    2033      * STM32F2/F4/F7 hardware SHA224 support through the HASH_* API's from the
    2034      * Standard Peripheral Library or CubeMX (See note in README).
    2035      */
    2036 
    2037     /* STM32 register size, bytes */
    2038     #ifdef WOLFSSL_STM32_CUBEMX
    2039         #define SHA224_REG_SIZE  WC_SHA224_BLOCK_SIZE
    2040     #else
    2041         #define SHA224_REG_SIZE  4
    2042         /* STM32 struct notes:
    2043          * sha224->buffer  = first 4 bytes used to hold partial block if needed
    2044          * sha224->buffLen = num bytes currently stored in sha256->buffer
    2045          * sha224->loLen   = num bytes that have been written to STM32 FIFO
    2046          */
    2047     #endif
    2048     #define SHA224_HW_TIMEOUT 0xFF
    2049 
    2050     static int InitSha224(wc_Sha224* sha224)
     2532#ifdef STM32_HASH_SHA2
     2533
     2534    /* Supports CubeMX HAL or Standard Peripheral Library */
     2535
     2536    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
    20512537    {
    20522538        if (sha224 == NULL)
    20532539            return BAD_FUNC_ARG;
    20542540
    2055         XMEMSET(sha224->buffer, 0, sizeof(sha224->buffer));
    2056         sha224->buffLen = 0;
    2057         sha224->loLen = 0;
    2058         sha224->hiLen = 0;
    2059 
    2060         /* initialize HASH peripheral */
    2061     #ifdef WOLFSSL_STM32_CUBEMX
    2062         HAL_HASH_DeInit(&sha224->hashHandle);
    2063         sha224->hashHandle.Init.DataType = HASH_DATATYPE_8B;
    2064         if (HAL_HASH_Init(&sha224->hashHandle) != HAL_OK) {
    2065             return ASYNC_INIT_E;
    2066         }
    2067         /* required because Cube MX is not clearing algo bits */
    2068         HASH->CR &= ~HASH_CR_ALGO;
    2069     #else
    2070         HASH_DeInit();
    2071 
    2072         /* reset the hash control register */
    2073         /* required because Cube MX is not clearing algo bits */
    2074         HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
    2075 
    2076         /* configure algo used, algo mode, datatype */
    2077         HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HASH
    2078                    | HASH_DataType_8b);
    2079 
    2080         /* reset HASH processor */
    2081         HASH->CR |= HASH_CR_INIT;
    2082     #endif
    2083 
     2541        (void)devId;
     2542        (void)heap;
     2543
     2544        wc_Stm32_Hash_Init(&sha224->stmCtx);
    20842545        return 0;
    20852546    }
    20862547
    2087     static int Sha224Update(wc_Sha256* sha224, const byte* data, word32 len)
     2548    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
    20882549    {
    20892550        int ret = 0;
    2090         byte* local;
    2091 
    2092         /* do block size increments */
    2093         local = (byte*)sha224->buffer;
    2094 
    2095         /* check that internal buffLen is valid */
    2096         if (sha224->buffLen >= SHA224_REG_SIZE)
    2097             return BUFFER_E;
    2098 
    2099         while (len) {
    2100             word32 add = min(len, SHA224_REG_SIZE - sha224->buffLen);
    2101             XMEMCPY(&local[sha224->buffLen], data, add);
    2102 
    2103             sha224->buffLen += add;
    2104             data         += add;
    2105             len          -= add;
    2106 
    2107             if (sha224->buffLen == SHA224_REG_SIZE) {
    2108             #ifdef WOLFSSL_STM32_CUBEMX
    2109                 if (HAL_HASHEx_SHA224_Accumulate(
    2110                         &sha224->hashHandle, local, SHA224_REG_SIZE) != HAL_OK) {
    2111                     ret = ASYNC_OP_E;
    2112                 }
    2113             #else
    2114                 HASH_DataIn(*(uint32_t*)local);
    2115             #endif
    2116 
    2117                 AddLength(sha224, SHA224_REG_SIZE);
    2118                 sha224->buffLen = 0;
     2551
     2552        if (sha224 == NULL || (data == NULL && len > 0)) {
     2553            return BAD_FUNC_ARG;
    21192554            }
     2555
     2556        ret = wolfSSL_CryptHwMutexLock();
     2557        if (ret == 0) {
     2558            ret = wc_Stm32_Hash_Update(&sha224->stmCtx,
     2559                HASH_AlgoSelection_SHA224, data, len);
     2560            wolfSSL_CryptHwMutexUnLock();
    21202561        }
    21212562        return ret;
    21222563    }
    21232564
    2124     static int Sha224Final(wc_Sha256* sha224)
     2565    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
    21252566    {
    21262567        int ret = 0;
    21272568
    2128     #ifdef WOLFSSL_STM32_CUBEMX
    2129         if (HAL_HASHEx_SHA224_Start(&sha224->hashHandle,
    2130                 (byte*)sha224->buffer, sha224->buffLen,
    2131                 (byte*)sha224->digest, SHA224_HW_TIMEOUT) != HAL_OK) {
    2132             ret = ASYNC_OP_E;
    2133         }
    2134     #else
    2135         __IO uint16_t nbvalidbitsdata = 0;
    2136 
    2137         /* finish reading any trailing bytes into FIFO */
    2138         if (sha224->buffLen > 0) {
    2139             HASH_DataIn(*(uint32_t*)sha224->buffer);
    2140             AddLength(sha224, sha224->buffLen);
    2141         }
    2142 
    2143         /* calculate number of valid bits in last word of input data */
    2144         nbvalidbitsdata = 8 * (sha224->loLen % SHA224_REG_SIZE);
    2145 
    2146         /* configure number of valid bits in last word of the data */
    2147         HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
    2148 
    2149         /* start HASH processor */
    2150         HASH_StartDigest();
    2151 
    2152         /* wait until Busy flag == RESET */
    2153         while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}
    2154 
    2155         /* read message digest */
    2156         sha224->digest[0] = HASH->HR[0];
    2157         sha224->digest[1] = HASH->HR[1];
    2158         sha224->digest[2] = HASH->HR[2];
    2159         sha224->digest[3] = HASH->HR[3];
    2160         sha224->digest[4] = HASH->HR[4];
    2161         sha224->digest[5] = HASH_DIGEST->HR[5];
    2162         sha224->digest[6] = HASH_DIGEST->HR[6];
    2163 
    2164         ByteReverseWords(sha224->digest, sha224->digest, SHA224_DIGEST_SIZE);
    2165     #endif /* WOLFSSL_STM32_CUBEMX */
     2569        if (sha224 == NULL || hash == NULL) {
     2570            return BAD_FUNC_ARG;
     2571        }
     2572
     2573        ret = wolfSSL_CryptHwMutexLock();
     2574        if (ret == 0) {
     2575            ret = wc_Stm32_Hash_Final(&sha224->stmCtx,
     2576                HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE);
     2577            wolfSSL_CryptHwMutexUnLock();
     2578        }
     2579
     2580        (void)wc_InitSha224(sha224); /* reset state */
    21662581
    21672582        return ret;
    21682583    }
    21692584
     2585#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     2586    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
     2587
     2588#elif defined(WOLFSSL_AFALG_HASH)
     2589    #error SHA224 currently not supported with AF_ALG enabled
     2590
     2591#elif defined(WOLFSSL_DEVCRYPTO_HASH)
     2592    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
     2593
    21702594#else
     2595
     2596    #define NEED_SOFT_SHA224
     2597
    21712598
    21722599    static int InitSha224(wc_Sha224* sha224)
     
    21992626    }
    22002627
    2201 #endif /* STM32_HASH */
    2202 
     2628#endif
     2629
     2630#ifdef NEED_SOFT_SHA224
    22032631    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
    22042632    {
     
    22132641        if (ret != 0)
    22142642            return ret;
     2643
     2644    #ifdef WOLFSSL_SMALL_STACK_CACHE
     2645        sha224->W = NULL;
     2646    #endif
    22152647
    22162648    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
     
    22242656    }
    22252657
    2226     int wc_InitSha224(wc_Sha224* sha224)
    2227     {
    2228         return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);
    2229     }
    2230 
    22312658    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
    22322659    {
     
    22712698            return ret;
    22722699
    2273     #if defined(LITTLE_ENDIAN_ORDER) && !defined(STM32_HASH)
     2700    #if defined(LITTLE_ENDIAN_ORDER)
    22742701        ByteReverseWords(sha224->digest, sha224->digest, WC_SHA224_DIGEST_SIZE);
    22752702    #endif
     
    22772704
    22782705        return InitSha224(sha224);  /* reset state */
     2706    }
     2707#endif /* end of SHA224 software implementation */
     2708
     2709    int wc_InitSha224(wc_Sha224* sha224)
     2710    {
     2711        return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);
    22792712    }
    22802713
     
    22832716        if (sha224 == NULL)
    22842717            return;
     2718
     2719#ifdef WOLFSSL_SMALL_STACK_CACHE
     2720    if (sha224->W != NULL) {
     2721        XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST);
     2722        sha224->W = NULL;
     2723    }
     2724#endif
    22852725
    22862726    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
    22872727        wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224);
    22882728    #endif /* WOLFSSL_ASYNC_CRYPT */
    2289     }
    2290 
     2729
     2730    #ifdef WOLFSSL_PIC32MZ_HASH
     2731        wc_Sha256Pic32Free(sha224);
     2732    #endif
     2733    }
    22912734#endif /* WOLFSSL_SHA224 */
    22922735
     
    23022745        return;
    23032746
     2747#ifdef WOLFSSL_SMALL_STACK_CACHE
     2748    if (sha256->W != NULL) {
     2749        XFREE(sha256->W, NULL, DYNAMIC_TYPE_DIGEST);
     2750        sha256->W = NULL;
     2751    }
     2752#endif
     2753
    23042754#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
    23052755    wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);
    23062756#endif /* WOLFSSL_ASYNC_CRYPT */
     2757#ifdef WOLFSSL_PIC32MZ_HASH
     2758    wc_Sha256Pic32Free(sha256);
     2759#endif
     2760#if defined(WOLFSSL_AFALG_HASH)
     2761    if (sha256->alFd > 0) {
     2762        close(sha256->alFd);
     2763        sha256->alFd = -1; /* avoid possible double close on socket */
     2764    }
     2765    if (sha256->rdFd > 0) {
     2766        close(sha256->rdFd);
     2767        sha256->rdFd = -1; /* avoid possible double close on socket */
     2768    }
     2769#endif /* WOLFSSL_AFALG_HASH */
     2770#ifdef WOLFSSL_DEVCRYPTO_HASH
     2771    wc_DevCryptoFree(&sha256->ctx);
     2772#endif /* WOLFSSL_DEVCRYPTO */
     2773#if defined(WOLFSSL_AFALG_HASH_KEEP) || \
     2774    (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP))
     2775    if (sha256->msg != NULL) {
     2776        XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
     2777        sha256->msg = NULL;
     2778    }
     2779#endif
    23072780}
    23082781
     
    23242797        if (ret == 0) {
    23252798            ret = wc_Sha224Final(&tmpSha224, hash);
     2799            wc_Sha224Free(&tmpSha224);
    23262800        }
    23272801        return ret;
     
    23352809
    23362810        XMEMCPY(dst, src, sizeof(wc_Sha224));
     2811    #ifdef WOLFSSL_SMALL_STACK_CACHE
     2812        dst->W = NULL;
     2813    #endif
    23372814
    23382815    #ifdef WOLFSSL_ASYNC_CRYPT
     
    23432820    }
    23442821#endif /* WOLFSSL_SHA224 */
     2822
     2823#ifdef WOLFSSL_AFALG_HASH
     2824    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
     2825
     2826#elif defined(WOLFSSL_DEVCRYPTO_HASH)
     2827    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
     2828
     2829#else
    23452830
    23462831int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
     
    23552840    if (ret == 0) {
    23562841        ret = wc_Sha256Final(&tmpSha256, hash);
     2842        wc_Sha256Free(&tmpSha256);
    23572843    }
    23582844    return ret;
     
    23662852
    23672853    XMEMCPY(dst, src, sizeof(wc_Sha256));
     2854#ifdef WOLFSSL_SMALL_STACK_CACHE
     2855    dst->W = NULL;
     2856#endif
    23682857
    23692858#ifdef WOLFSSL_ASYNC_CRYPT
     
    23762865    return ret;
    23772866}
     2867#endif
    23782868#endif /* !WOLFSSL_TI_HASH */
    23792869
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/sha512.c

    r352 r372  
    2727#include <wolfssl/wolfcrypt/settings.h>
    2828
    29 #ifdef WOLFSSL_SHA512
     29#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
     30
     31#if defined(HAVE_FIPS) && \
     32        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
     33
     34    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
     35    #define FIPS_NO_WRAPPERS
     36
     37    #ifdef USE_WINDOWS_API
     38        #pragma code_seg(".fipsA$k")
     39        #pragma const_seg(".fipsB$k")
     40    #endif
     41#endif
     42
    3043#include <wolfssl/wolfcrypt/sha512.h>
    3144#include <wolfssl/wolfcrypt/error-crypt.h>
    3245#include <wolfssl/wolfcrypt/cpuid.h>
    3346
     47/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
     48#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
     49    #define USE_SLOW_SHA512
     50#endif
     51
    3452/* fips wrapper calls, user can call direct */
    35 #ifdef HAVE_FIPS
     53#if defined(HAVE_FIPS) && \
     54    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
     55
     56    #ifdef WOLFSSL_SHA512
     57
    3658    int wc_InitSha512(wc_Sha512* sha)
    3759    {
     
    7294        /* Not supported in FIPS */
    7395    }
     96    #endif
    7497
    7598    #if defined(WOLFSSL_SHA384) || defined(HAVE_AESGCM)
     
    111134    #endif /* WOLFSSL_SHA384 || HAVE_AESGCM */
    112135
    113 #else /* else build without using fips */
     136#else /* else build without fips, or for FIPS v2 */
    114137
    115138#include <wolfssl/wolfcrypt/logging.h>
     
    124147
    125148#if defined(USE_INTEL_SPEEDUP)
     149    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
     150                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
     151        #undef  NO_AVX2_SUPPORT
     152        #define NO_AVX2_SUPPORT
     153    #endif
     154    #if defined(__clang__) && ((__clang_major__ < 3) || \
     155                               (__clang_major__ == 3 && __clang_minor__ <= 5))
     156        #define NO_AVX2_SUPPORT
     157    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
     158        #undef NO_AVX2_SUPPORT
     159    #endif
     160
    126161    #define HAVE_INTEL_AVX1
     162    #ifndef NO_AVX2_SUPPORT
    127163    #define HAVE_INTEL_AVX2
     164#endif
    128165#endif
    129166
     
    136173    /* #define DEBUG_YMM  */
    137174#endif
    138 
    139 
    140 #if defined(HAVE_INTEL_RORX)
    141     #define ROTR(func, bits, x) \
    142     word64 func(word64 x) {  word64 ret ;\
    143         __asm__ ("rorx $"#bits", %1, %0\n\t":"=r"(ret):"r"(x)) ;\
    144         return ret ;\
    145     }
    146 
    147     static INLINE ROTR(rotrFixed64_28, 28, x);
    148     static INLINE ROTR(rotrFixed64_34, 34, x);
    149     static INLINE ROTR(rotrFixed64_39, 39, x);
    150     static INLINE ROTR(rotrFixed64_14, 14, x);
    151     static INLINE ROTR(rotrFixed64_18, 18, x);
    152     static INLINE ROTR(rotrFixed64_41, 41, x);
    153 
    154     #define S0_RORX(x) (rotrFixed64_28(x)^rotrFixed64_34(x)^rotrFixed64_39(x))
    155     #define S1_RORX(x) (rotrFixed64_14(x)^rotrFixed64_18(x)^rotrFixed64_41(x))
    156 #endif /* HAVE_INTEL_RORX */
    157175
    158176#if defined(HAVE_BYTEREVERSE64) && \
     
    167185#endif
    168186
     187#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     188    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
     189#else
     190
     191#ifdef WOLFSSL_SHA512
     192
    169193static int InitSha512(wc_Sha512* sha512)
    170194{
     
    188212}
    189213
     214#endif /* WOLFSSL_SHA512 */
    190215
    191216/* Hardware Acceleration */
    192217#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     218
     219#ifdef WOLFSSL_SHA512
    193220
    194221    /*****
     
    208235
    209236    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
    210       Transform_AVX1(); # Function prototype
    211       Transform_AVX2(); #
     237      Transform_Sha512_AVX1(); # Function prototype
     238      Transform_Sha512_AVX2(); #
    212239    #endif
    213240
    214       _Transform() {     # Native Transform Function body
     241      _Transform_Sha512() {     # Native Transform Function body
    215242
    216243      }
     
    241268    #if defnied(HAVE_INTEL_AVX1)
    242269
    243       int Transform_AVX1() {
     270      int Transform_Sha512_AVX1() {
    244271          Stitched Message Sched/Round
    245272      }
     
    249276    #if defnied(HAVE_INTEL_AVX2)
    250277
    251       int Transform_AVX2() {
     278      int Transform_Sha512_AVX2() {
    252279          Stitched Message Sched/Round
    253280      }
     
    262289
    263290    #if defined(HAVE_INTEL_AVX1)
    264         static int Transform_AVX1(wc_Sha512 *sha512);
     291        static int Transform_Sha512_AVX1(wc_Sha512 *sha512);
     292        static int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);
    265293    #endif
    266294    #if defined(HAVE_INTEL_AVX2)
    267         static int Transform_AVX2(wc_Sha512 *sha512);
    268         #if defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_RORX)
    269             static int Transform_AVX1_RORX(wc_Sha512 *sha512);
     295        static int Transform_Sha512_AVX2(wc_Sha512 *sha512);
     296        static int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);
     297        #if defined(HAVE_INTEL_RORX)
     298            static int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);
     299            static int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,
     300                                                      word32 len);
     301            static int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);
     302            static int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,
     303                                                      word32 len);
    270304        #endif
    271305    #endif
    272     static int _Transform(wc_Sha512 *sha512);
    273     static int (*Transform_p)(wc_Sha512* sha512) = _Transform;
     306    static int _Transform_Sha512(wc_Sha512 *sha512);
     307    static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;
     308    static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;
    274309    static int transform_check = 0;
    275310    static int intel_flags;
    276     #define Transform(sha512) (*Transform_p)(sha512)
    277 
    278     /* Dummy for saving MM_REGs on behalf of Transform */
    279     /* #if defined(HAVE_INTEL_AVX2)
    280      #define SAVE_XMM_YMM   __asm__ volatile("orq %%r8, %%r8":::\
    281        "%ymm0","%ymm1","%ymm2","%ymm3","%ymm4","%ymm5","%ymm6","%ymm7","%ymm8","%ymm9","%ymm10","%ymm11",\
    282        "%ymm12","%ymm13","%ymm14","%ymm15")
    283     */
    284     #if defined(HAVE_INTEL_AVX1)
    285         #define SAVE_XMM_YMM   __asm__ volatile("orq %%r8, %%r8":::\
    286             "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8","xmm9","xmm10","xmm11","xmm12","xmm13","xmm14","xmm15")
    287     #endif
     311    #define Transform_Sha512(sha512)     (*Transform_Sha512_p)(sha512)
     312    #define Transform_Sha512_Len(sha512, len) \
     313        (*Transform_Sha512_Len_p)(sha512, len)
    288314
    289315    static void Sha512_SetTransform()
     
    295321
    296322    #if defined(HAVE_INTEL_AVX2)
    297         if (IS_INTEL_AVX2(intel_flags) && IS_INTEL_BMI2(intel_flags)) {
    298             if (1)
    299                 Transform_p = Transform_AVX1_RORX;
     323        if (IS_INTEL_AVX2(intel_flags)) {
     324        #ifdef HAVE_INTEL_RORX
     325            if (IS_INTEL_BMI2(intel_flags)) {
     326                Transform_Sha512_p = Transform_Sha512_AVX2_RORX;
     327                Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;
     328            }
    300329            else
    301                 Transform_p = Transform_AVX2;
     330        #endif
     331            if (1) {
     332                Transform_Sha512_p = Transform_Sha512_AVX2;
     333                Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;
     334            }
     335        #ifdef HAVE_INTEL_RORX
     336            else {
     337                Transform_Sha512_p = Transform_Sha512_AVX1_RORX;
     338                Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;
     339            }
     340        #endif
    302341        }
    303342        else
    304343    #endif
    305344    #if defined(HAVE_INTEL_AVX1)
    306         if (1) {
    307             Transform_p = ((IS_INTEL_AVX1(intel_flags)) ? Transform_AVX1 :
    308                                                                     _Transform);
     345        if (IS_INTEL_AVX1(intel_flags)) {
     346            Transform_Sha512_p = Transform_Sha512_AVX1;
     347            Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;
    309348        }
    310349        else
    311350    #endif
    312             Transform_p = _Transform;
     351            Transform_Sha512_p = _Transform_Sha512;
    313352
    314353        transform_check = 1;
    315354    }
    316 
    317     int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
    318     {
    319         int ret = InitSha512(sha512);
    320 
    321         (void)heap;
    322         (void)devId;
    323 
    324         Sha512_SetTransform();
    325 
    326         return ret;
    327     }
     355#endif /* WOLFSSL_SHA512 */
    328356
    329357#else
    330     #define Transform(sha512) _Transform(sha512)
     358    #define Transform_Sha512(sha512) _Transform_Sha512(sha512)
     359
     360#endif
     361
     362#ifdef WOLFSSL_SHA512
    331363
    332364    int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
     
    342374        if (ret != 0)
    343375            return ret;
     376
     377#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     378    Sha512_SetTransform();
     379#endif
     380
     381#ifdef WOLFSSL_SMALL_STACK_CACHE
     382    sha512->W = NULL;
     383#endif
    344384
    345385    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
     
    353393    }
    354394
    355 #endif /* Hardware Acceleration */
    356 
    357 #ifndef SAVE_XMM_YMM
    358     #define SAVE_XMM_YMM
    359 #endif
     395#endif /* WOLFSSL_SHA512 */
     396
    360397
    361398static const word64 K512[80] = {
     
    402439};
    403440
    404 
    405 
    406441#define blk0(i) (W[i] = sha512->buffer[i])
    407442
    408 #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
     443#define blk2(i) (\
     444               W[ i     & 15] += \
     445            s1(W[(i-2)  & 15])+ \
     446               W[(i-7)  & 15] + \
     447            s0(W[(i-15) & 15])  \
     448        )
    409449
    410450#define Ch(x,y,z) (z^(x&(y^z)))
     
    425465#define s1(x) (rotrFixed64(x,19)^rotrFixed64(x,61)^(x>>6))
    426466
    427 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\
    428     d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
    429 
    430 static int _Transform(wc_Sha512* sha512)
     467#define R(i) \
     468    h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j ? blk2(i) : blk0(i)); \
     469    d(i) += h(i); \
     470    h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))
     471
     472static int _Transform_Sha512(wc_Sha512* sha512)
    431473{
    432474    const word64* K = K512;
    433 
    434475    word32 j;
    435476    word64 T[8];
    436477
    437 
    438 #ifdef WOLFSSL_SMALL_STACK
     478#ifdef WOLFSSL_SMALL_STACK_CACHE
     479    word64* W = sha512->W;
     480    if (W == NULL) {
     481        W = (word64*) XMALLOC(sizeof(word64) * 16, NULL,
     482                                                       DYNAMIC_TYPE_TMP_BUFFER);
     483        if (W == NULL)
     484            return MEMORY_E;
     485        sha512->W = W;
     486    }
     487#elif defined(WOLFSSL_SMALL_STACK)
    439488    word64* W;
    440489    W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     
    448497    XMEMCPY(T, sha512->digest, sizeof(T));
    449498
    450 #ifdef USE_SLOW_SHA2
     499#ifdef USE_SLOW_SHA512
    451500    /* over twice as small, but 50% slower */
    452501    /* 80 operations, not unrolled */
     
    465514        R(12); R(13); R(14); R(15);
    466515    }
    467 #endif /* USE_SLOW_SHA2 */
     516#endif /* USE_SLOW_SHA512 */
    468517
    469518    /* Add the working vars back into digest */
    470 
    471519    sha512->digest[0] += a(0);
    472520    sha512->digest[1] += b(0);
     
    482530    ForceZero(T, sizeof(T));
    483531
    484 #ifdef WOLFSSL_SMALL_STACK
     532#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
    485533    XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    486534#endif
     
    490538
    491539
    492 static INLINE void AddLength(wc_Sha512* sha512, word32 len)
     540static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
    493541{
    494542    word64 tmp = sha512->loLen;
     
    497545}
    498546
    499 static INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
     547static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
    500548{
    501549    int ret = 0;
     
    507555        return BUFFER_E;
    508556
    509     SAVE_XMM_YMM; /* for Intel AVX */
    510 
    511     while (len) {
     557    if (sha512->buffLen > 0) {
    512558        word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
     559        if (add > 0) {
    513560        XMEMCPY(&local[sha512->buffLen], data, add);
    514561
     
    516563        data            += add;
    517564        len             -= add;
     565        }
    518566
    519567        if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
     
    527575            }
    528576    #endif
    529             ret = Transform(sha512);
     577            ret = Transform_Sha512(sha512);
     578            if (ret == 0) {
     579                AddLength(sha512, WC_SHA512_BLOCK_SIZE);
     580                sha512->buffLen = 0;
     581            }
     582            else
     583                len = 0;
     584        }
     585    }
     586
     587#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     588    if (Transform_Sha512_Len_p != NULL) {
     589        word32 blocksLen = len & ~(WC_SHA512_BLOCK_SIZE-1);
     590
     591        if (blocksLen > 0) {
     592            AddLength(sha512, blocksLen);
     593            sha512->data = data;
     594            /* Byte reversal performed in function if required. */
     595            Transform_Sha512_Len(sha512, blocksLen);
     596            data += blocksLen;
     597            len  -= blocksLen;
     598        }
     599    }
     600    else
     601#endif
     602#if !defined(LITTLE_ENDIAN_ORDER) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     603    {
     604        word32 blocksLen = len & ~(WC_SHA512_BLOCK_SIZE-1);
     605
     606        AddLength(sha512, blocksLen);
     607        while (len >= WC_SHA512_BLOCK_SIZE) {
     608            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
     609
     610            data += WC_SHA512_BLOCK_SIZE;
     611            len  -= WC_SHA512_BLOCK_SIZE;
     612
     613            /* Byte reversal performed in function if required. */
     614            ret = Transform_Sha512(sha512);
    530615            if (ret != 0)
    531616                break;
    532 
    533             AddLength(sha512, WC_SHA512_BLOCK_SIZE);
    534             sha512->buffLen = 0;
    535617        }
     618    }
     619#else
     620    {
     621        word32 blocksLen = len & ~(WC_SHA512_BLOCK_SIZE-1);
     622
     623        AddLength(sha512, blocksLen);
     624        while (len >= WC_SHA512_BLOCK_SIZE) {
     625            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
     626
     627            data += WC_SHA512_BLOCK_SIZE;
     628            len  -= WC_SHA512_BLOCK_SIZE;
     629
     630            ByteReverseWords64(sha512->buffer, sha512->buffer,
     631                                                          WC_SHA512_BLOCK_SIZE);
     632            ret = Transform_Sha512(sha512);
     633            if (ret != 0)
     634                break;
     635        }
     636    }
     637#endif
     638
     639    if (len > 0) {
     640        XMEMCPY(local, data, len);
     641        sha512->buffLen = len;
    536642    }
    537643
    538644    return ret;
    539645}
     646
     647#ifdef WOLFSSL_SHA512
    540648
    541649int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
     
    556664}
    557665
    558 
    559 static INLINE int Sha512Final(wc_Sha512* sha512)
     666#endif /* WOLFSSL_SHA512 */
     667
     668#endif /* WOLFSSL_IMX6_CAAM */
     669
     670static WC_INLINE int Sha512Final(wc_Sha512* sha512)
    560671{
    561672    byte* local = (byte*)sha512->buffer;
     
    566677    }
    567678
    568     SAVE_XMM_YMM ; /* for Intel AVX */
    569679    AddLength(sha512, sha512->buffLen);               /* before adding pads */
    570680
     
    584694        }
    585695#endif /* LITTLE_ENDIAN_ORDER */
    586         ret = Transform(sha512);
     696        ret = Transform_Sha512(sha512);
    587697        if (ret != 0)
    588698            return ret;
     
    614724                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
    615725#endif
    616     ret = Transform(sha512);
     726    ret = Transform_Sha512(sha512);
    617727    if (ret != 0)
    618728        return ret;
     
    621731        ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);
    622732    #endif
     733
     734    return 0;
     735}
     736
     737#ifdef WOLFSSL_SHA512
     738
     739int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
     740{
     741#ifdef LITTLE_ENDIAN_ORDER
     742    word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)];
     743#endif
     744
     745    if (sha512 == NULL || hash == NULL) {
     746        return BAD_FUNC_ARG;
     747    }
     748
     749#ifdef LITTLE_ENDIAN_ORDER
     750    ByteReverseWords64((word64*)digest, (word64*)sha512->digest,
     751                                                         WC_SHA512_DIGEST_SIZE);
     752    XMEMCPY(hash, digest, WC_SHA512_DIGEST_SIZE);
     753#else
     754    XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);
     755#endif
    623756
    624757    return 0;
     
    662795        return;
    663796
     797#ifdef WOLFSSL_SMALL_STACK_CACHE
     798    if (sha512->W != NULL) {
     799        XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     800        sha512->W = NULL;
     801    }
     802#endif
     803
    664804#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
    665805    wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
     
    670810#if defined(HAVE_INTEL_AVX1)
    671811
    672 #define Rx_1(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + W_X[i];
    673 #define Rx_2(i) d(i)+=h(i);
    674 #define Rx_3(i) h(i)+=S0(a(i))+Maj(a(i),b(i),c(i));
     812static word64 mBYTE_FLIP_MASK[] =  { 0x0001020304050607, 0x08090a0b0c0d0e0f };
     813
     814#define W_0     xmm0
     815#define W_2     xmm1
     816#define W_4     xmm2
     817#define W_6     xmm3
     818#define W_8     xmm4
     819#define W_10    xmm5
     820#define W_12    xmm6
     821#define W_14    xmm7
     822
     823#define W_M15   xmm12
     824#define W_M7    xmm13
     825#define MASK    xmm14
     826
     827#define XTMP1   xmm8
     828#define XTMP2   xmm9
     829#define XTMP3   xmm10
     830#define XTMP4   xmm11
     831
     832#define XMM_REGS \
     833    "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",       \
     834    "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
     835
     836#define _VPALIGNR(dest, src1, src2, bits)                               \
     837    "vpalignr   $" #bits ", %%" #src2 ", %%" #src1 ", %%" #dest "\n\t"
     838#define VPALIGNR(dest, src1, src2, bits) \
     839       _VPALIGNR(dest, src1, src2, bits)
     840
     841#define _V_SHIFT_R(dest, src, bits)                             \
     842    "vpsrlq     $" #bits ", %%" #src ", %%" #dest "\n\t"
     843#define V_SHIFT_R(dest, src, bits) \
     844       _V_SHIFT_R(dest, src, bits)
     845
     846#define _V_SHIFT_L(dest, src, bits)                             \
     847    "vpsllq     $" #bits ", %%" #src ", %%" #dest "\n\t"
     848#define V_SHIFT_L(dest, src, bits) \
     849       _V_SHIFT_L(dest, src, bits)
     850
     851#define _V_ADD(dest, src1, src2)                                \
     852    "vpaddq     %%" #src1 ", %%" #src2 ", %%" #dest "\n\t"
     853#define V_ADD(dest, src1, src2) \
     854       _V_ADD(dest, src1, src2)
     855
     856#define _V_XOR(dest, src1, src2)                                \
     857    "vpxor      %%" #src1 ", %%" #src2 ", %%" #dest "\n\t"
     858#define V_XOR(dest, src1, src2) \
     859       _V_XOR(dest, src1, src2)
     860
     861#define _V_OR(dest, src1, src2)                                 \
     862    "vpor       %%" #src1 ", %%" #src2 ", %%" #dest "\n\t"
     863#define V_OR(dest, src1, src2) \
     864       _V_OR(dest, src1, src2)
     865
     866#define RA  %%r8
     867#define RB  %%r9
     868#define RC  %%r10
     869#define RD  %%r11
     870#define RE  %%r12
     871#define RF  %%r13
     872#define RG  %%r14
     873#define RH  %%r15
     874
     875#define STATE_REGS "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
     876
     877#define L1  "%%rax"
     878#define L2  "%%rcx"
     879#define L3  "%%rdx"
     880#define L4  "%%rbx"
     881#define WX  "%%rsp"
     882
     883#define WORK_REGS "rax", "rbx", "rcx", "rdx"
     884
     885#define RND_0_1(a,b,c,d,e,f,g,h,i)                   \
     886    /* L1 = e >>> 23 */                              \
     887    "rorq        $23, " L1 "\n\t"                    \
     888
     889#define RND_0_2(a,b,c,d,e,f,g,h,i)                   \
     890    /* L3 = a */                                     \
     891    "movq       "#a", " L3 "\n\t"                    \
     892    /* L2 = f */                                     \
     893    "movq       "#f", " L2 "\n\t"                    \
     894    /* h += W_X[i] */                                \
     895    "addq       ("#i")*8(" WX "), "#h"\n\t"          \
     896    /* L2 = f ^ g */                                 \
     897    "xorq       "#g", " L2 "\n\t"                    \
     898
     899#define RND_0_2_A(a,b,c,d,e,f,g,h,i)                 \
     900    /* L3 = a */                                     \
     901    "movq       "#a", " L3 "\n\t"                    \
     902    /* L2 = f */                                     \
     903    "movq       "#f", " L2 "\n\t"                    \
     904
     905#define RND_0_2_B(a,b,c,d,e,f,g,h,i)                 \
     906    /* h += W_X[i] */                                \
     907    "addq       ("#i")*8(" WX "), "#h"\n\t"          \
     908    /* L2 = f ^ g */                                 \
     909    "xorq       "#g", " L2 "\n\t"                    \
     910
     911#define RND_0_3(a,b,c,d,e,f,g,h,i)                   \
     912    /* L1 = (e >>> 23) ^ e */                        \
     913    "xorq       "#e", " L1 "\n\t"                    \
     914    /* L2 = (f ^ g) & e */                           \
     915    "andq       "#e", " L2 "\n\t"                    \
     916
     917#define RND_0_4(a,b,c,d,e,f,g,h,i)                   \
     918    /* L1 = ((e >>> 23) ^ e) >>> 4 */                \
     919    "rorq        $4, " L1 "\n\t"                     \
     920    /* L2 = ((f ^ g) & e) ^ g */                     \
     921    "xorq       "#g", " L2 "\n\t"                    \
     922
     923#define RND_0_5(a,b,c,d,e,f,g,h,i)                   \
     924    /* L1 = (((e >>> 23) ^ e) >>> 4) ^ e */          \
     925    "xorq       "#e", " L1 "\n\t"                    \
     926    /* h += Ch(e,f,g) */                             \
     927    "addq       " L2 ", "#h"\n\t"                    \
     928
     929#define RND_0_6(a,b,c,d,e,f,g,h,i)                   \
     930    /* L1 = ((((e >>> 23) ^ e) >>> 4) ^ e) >>> 14 */ \
     931    "rorq       $14, " L1 "\n\t"                     \
     932    /* L3 = a ^ b */                                 \
     933    "xorq       "#b", " L3 "\n\t"                    \
     934
     935#define RND_0_7(a,b,c,d,e,f,g,h,i)                   \
     936    /* h += Sigma1(e) */                             \
     937    "addq       " L1 ", "#h"\n\t"                    \
     938    /* L2 = a */                                     \
     939    "movq       "#a", " L2 "\n\t"                    \
     940
     941#define RND_0_8(a,b,c,d,e,f,g,h,i)                   \
     942    /* L4 = (a ^ b) & (b ^ c) */                     \
     943    "andq       " L3 ", " L4 "\n\t"                  \
     944    /* L2 = a >>> 5 */                               \
     945    "rorq       $5, " L2 "\n\t"                      \
     946
     947#define RND_0_9(a,b,c,d,e,f,g,h,i)                   \
     948    /* L2 = (a >>> 5) ^ a */                         \
     949    "xorq       "#a", " L2 "\n\t"                    \
     950    /* L4 = ((a ^ b) & (b ^ c) ^ b */                \
     951    "xorq       "#b", " L4 "\n\t"                    \
     952
     953#define RND_0_10(a,b,c,d,e,f,g,h,i)                  \
     954    /* L2 = ((a >>> 5) ^ a) >>> 6 */                 \
     955    "rorq        $6, " L2 "\n\t"                     \
     956    /* d += h */                                     \
     957    "addq       "#h", "#d"\n\t"                      \
     958
     959#define RND_0_11(a,b,c,d,e,f,g,h,i)                  \
     960    /* L2 = (((a >>> 5) ^ a) >>> 6) ^ a */           \
     961    "xorq       "#a", " L2 "\n\t"                    \
     962    /* h += Sigma0(a) */                             \
     963    "addq       " L4 ", "#h"\n\t"                    \
     964
     965#define RND_0_12(a,b,c,d,e,f,g,h,i)                  \
     966    /* L2 = ((((a >>> 5) ^ a) >>> 6) ^ a) >>> 28 */  \
     967    "rorq       $28, " L2 "\n\t"                     \
     968    /* d (= e next RND) */                           \
     969    "movq       "#d", " L1 "\n\t"                    \
     970    /* h += Maj(a,b,c) */                            \
     971    "addq       " L2 ", "#h"\n\t"                    \
     972
     973#define RND_1_1(a,b,c,d,e,f,g,h,i)                   \
     974    /* L1 = e >>> 23 */                              \
     975    "rorq        $23, " L1 "\n\t"                    \
     976
     977#define RND_1_2(a,b,c,d,e,f,g,h,i)                   \
     978    /* L4 = a */                                     \
     979    "movq       "#a", " L4 "\n\t"                    \
     980    /* L2 = f */                                     \
     981    "movq       "#f", " L2 "\n\t"                    \
     982    /* h += W_X[i] */                                \
     983    "addq       ("#i")*8(" WX "), "#h"\n\t"          \
     984    /* L2 = f ^ g */                                 \
     985    "xorq       "#g", " L2 "\n\t"                    \
     986
     987#define RND_1_2_A(a,b,c,d,e,f,g,h,i)                 \
     988    /* L4 = a */                                     \
     989    "movq       "#a", " L4 "\n\t"                    \
     990    /* L2 = f */                                     \
     991    "movq       "#f", " L2 "\n\t"                    \
     992
     993#define RND_1_2_B(a,b,c,d,e,f,g,h,i)                 \
     994    /* h += W_X[i] */                                \
     995    "addq       ("#i")*8(" WX "), "#h"\n\t"          \
     996    /* L2 = f ^ g */                                 \
     997    "xorq       "#g", " L2 "\n\t"                    \
     998
     999#define RND_1_3(a,b,c,d,e,f,g,h,i)                   \
     1000    /* L1 = (e >>> 23) ^ e */                        \
     1001    "xorq       "#e", " L1 "\n\t"                    \
     1002    /* L2 = (f ^ g) & e */                           \
     1003    "andq       "#e", " L2 "\n\t"                    \
     1004
     1005#define RND_1_4(a,b,c,d,e,f,g,h,i)                   \
     1006    /* ((e >>> 23) ^ e) >>> 4 */                     \
     1007    "rorq        $4, " L1 "\n\t"                     \
     1008    /* ((f ^ g) & e) ^ g */                          \
     1009    "xorq       "#g", " L2 "\n\t"                    \
     1010
     1011#define RND_1_5(a,b,c,d,e,f,g,h,i)                   \
     1012    /* (((e >>> 23) ^ e) >>> 4) ^ e */               \
     1013    "xorq       "#e", " L1 "\n\t"                    \
     1014    /* h += Ch(e,f,g) */                             \
     1015    "addq       " L2 ", "#h"\n\t"                    \
     1016
     1017#define RND_1_6(a,b,c,d,e,f,g,h,i)                   \
     1018    /* L1 = ((((e >>> 23) ^ e) >>> 4) ^ e) >>> 14 */ \
     1019    "rorq       $14, " L1 "\n\t"                     \
     1020    /* L4 = a ^ b */                                 \
     1021    "xorq       "#b", " L4 "\n\t"                    \
     1022
     1023#define RND_1_7(a,b,c,d,e,f,g,h,i)                   \
     1024    /* h += Sigma1(e) */                             \
     1025    "addq       " L1 ", "#h"\n\t"                    \
     1026    /* L2 = a */                                     \
     1027    "movq       "#a", " L2 "\n\t"                    \
     1028
     1029#define RND_1_8(a,b,c,d,e,f,g,h,i)                   \
     1030    /* L3 = (a ^ b) & (b ^ c) */                     \
     1031    "andq       " L4 ", " L3 "\n\t"                  \
     1032    /* L2 = a >>> 5 */                               \
     1033    "rorq       $5, " L2 "\n\t"                      \
     1034
     1035#define RND_1_9(a,b,c,d,e,f,g,h,i)                   \
     1036    /* L2 = (a >>> 5) ^ a */                         \
     1037    "xorq       "#a", " L2 "\n\t"                    \
     1038    /* L3 = ((a ^ b) & (b ^ c) ^ b */                \
     1039    "xorq       "#b", " L3 "\n\t"                    \
     1040
     1041#define RND_1_10(a,b,c,d,e,f,g,h,i)                  \
     1042    /* L2 = ((a >>> 5) ^ a) >>> 6 */                 \
     1043    "rorq        $6, " L2 "\n\t"                     \
     1044    /* d += h */                                     \
     1045    "addq       "#h", "#d"\n\t"                      \
     1046
     1047#define RND_1_11(a,b,c,d,e,f,g,h,i)                  \
     1048    /* L2 = (((a >>> 5) ^ a) >>> 6) ^ a */           \
     1049    "xorq       "#a", " L2 "\n\t"                    \
     1050    /* h += Sigma0(a) */                             \
     1051    "addq       " L3 ", "#h"\n\t"                    \
     1052
     1053#define RND_1_12(a,b,c,d,e,f,g,h,i)                  \
     1054    /* L2 = ((((a >>> 5) ^ a) >>> 6) ^ a) >>> 28 */  \
     1055    "rorq       $28, " L2 "\n\t"                     \
     1056    /* d (= e next RND) */                           \
     1057    "movq       "#d", " L1 "\n\t"                    \
     1058    /* h += Maj(a,b,c) */                            \
     1059    "addq       " L2 ", "#h"\n\t"                    \
     1060
     1061
     1062#define MsgSched2(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,a,b,c,d,e,f,g,h,i) \
     1063            RND_0_1(a,b,c,d,e,f,g,h,i)                                  \
     1064    VPALIGNR(W_M15, W_2, W_0, 8)                                        \
     1065    VPALIGNR(W_M7, W_10, W_8, 8)                                        \
     1066            RND_0_2(a,b,c,d,e,f,g,h,i)                                  \
     1067    V_SHIFT_R(XTMP1, W_M15, 1)                                          \
     1068    V_SHIFT_L(XTMP2, W_M15, 63)                                         \
     1069            RND_0_3(a,b,c,d,e,f,g,h,i)                                  \
     1070            RND_0_4(a,b,c,d,e,f,g,h,i)                                  \
     1071    V_SHIFT_R(XTMP3, W_M15, 8)                                          \
     1072    V_SHIFT_L(XTMP4, W_M15, 56)                                         \
     1073            RND_0_5(a,b,c,d,e,f,g,h,i)                                  \
     1074            RND_0_6(a,b,c,d,e,f,g,h,i)                                  \
     1075    V_OR(XTMP1, XTMP2, XTMP1)                                           \
     1076    V_OR(XTMP3, XTMP4, XTMP3)                                           \
     1077            RND_0_7(a,b,c,d,e,f,g,h,i)                                  \
     1078            RND_0_8(a,b,c,d,e,f,g,h,i)                                  \
     1079    V_SHIFT_R(XTMP4, W_M15, 7)                                          \
     1080    V_XOR(XTMP1, XTMP3, XTMP1)                                          \
     1081            RND_0_9(a,b,c,d,e,f,g,h,i)                                  \
     1082            RND_0_10(a,b,c,d,e,f,g,h,i)                                 \
     1083    V_XOR(XTMP1, XTMP4, XTMP1)                                          \
     1084    V_ADD(W_0, W_0, W_M7)                                               \
     1085            RND_0_11(a,b,c,d,e,f,g,h,i)                                 \
     1086            RND_0_12(a,b,c,d,e,f,g,h,i)                                 \
     1087            RND_1_1(h,a,b,c,d,e,f,g,i+1)                                \
     1088    V_ADD(W_0, W_0, XTMP1)                                              \
     1089            RND_1_2(h,a,b,c,d,e,f,g,i+1)                                \
     1090    V_SHIFT_R(XTMP1, W_14, 19)                                          \
     1091    V_SHIFT_L(XTMP2, W_14, 45)                                          \
     1092            RND_1_3(h,a,b,c,d,e,f,g,i+1)                                \
     1093            RND_1_4(h,a,b,c,d,e,f,g,i+1)                                \
     1094    V_SHIFT_R(XTMP3, W_14, 61)                                          \
     1095    V_SHIFT_L(XTMP4, W_14, 3)                                           \
     1096            RND_1_5(h,a,b,c,d,e,f,g,i+1)                                \
     1097            RND_1_6(h,a,b,c,d,e,f,g,i+1)                                \
     1098            RND_1_7(h,a,b,c,d,e,f,g,i+1)                                \
     1099    V_OR(XTMP1, XTMP2, XTMP1)                                           \
     1100    V_OR(XTMP3, XTMP4, XTMP3)                                           \
     1101            RND_1_8(h,a,b,c,d,e,f,g,i+1)                                \
     1102            RND_1_9(h,a,b,c,d,e,f,g,i+1)                                \
     1103    V_XOR(XTMP1, XTMP3, XTMP1)                                          \
     1104    V_SHIFT_R(XTMP4, W_14, 6)                                           \
     1105            RND_1_10(h,a,b,c,d,e,f,g,i+1)                               \
     1106            RND_1_11(h,a,b,c,d,e,f,g,i+1)                               \
     1107    V_XOR(XTMP1, XTMP4, XTMP1)                                          \
     1108            RND_1_12(h,a,b,c,d,e,f,g,i+1)                               \
     1109    V_ADD(W_0, W_0, XTMP1)                                              \
     1110
     1111#define RND_ALL_2(a, b, c, d, e, f, g, h, i) \
     1112    RND_0_1 (a, b, c, d, e, f, g, h, i )     \
     1113    RND_0_2 (a, b, c, d, e, f, g, h, i )     \
     1114    RND_0_3 (a, b, c, d, e, f, g, h, i )     \
     1115    RND_0_4 (a, b, c, d, e, f, g, h, i )     \
     1116    RND_0_5 (a, b, c, d, e, f, g, h, i )     \
     1117    RND_0_6 (a, b, c, d, e, f, g, h, i )     \
     1118    RND_0_7 (a, b, c, d, e, f, g, h, i )     \
     1119    RND_0_8 (a, b, c, d, e, f, g, h, i )     \
     1120    RND_0_9 (a, b, c, d, e, f, g, h, i )     \
     1121    RND_0_10(a, b, c, d, e, f, g, h, i )     \
     1122    RND_0_11(a, b, c, d, e, f, g, h, i )     \
     1123    RND_0_12(a, b, c, d, e, f, g, h, i )     \
     1124    RND_1_1 (h, a, b, c, d, e, f, g, i+1)    \
     1125    RND_1_2 (h, a, b, c, d, e, f, g, i+1)    \
     1126    RND_1_3 (h, a, b, c, d, e, f, g, i+1)    \
     1127    RND_1_4 (h, a, b, c, d, e, f, g, i+1)    \
     1128    RND_1_5 (h, a, b, c, d, e, f, g, i+1)    \
     1129    RND_1_6 (h, a, b, c, d, e, f, g, i+1)    \
     1130    RND_1_7 (h, a, b, c, d, e, f, g, i+1)    \
     1131    RND_1_8 (h, a, b, c, d, e, f, g, i+1)    \
     1132    RND_1_9 (h, a, b, c, d, e, f, g, i+1)    \
     1133    RND_1_10(h, a, b, c, d, e, f, g, i+1)    \
     1134    RND_1_11(h, a, b, c, d, e, f, g, i+1)    \
     1135    RND_1_12(h, a, b, c, d, e, f, g, i+1)
     1136
    6751137
    6761138#if defined(HAVE_INTEL_RORX)
    6771139
    678     #define Rx_RORX_1(i) h(i)+=S1_RORX(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + W_X[i];
    679     #define Rx_RORX_2(i) d(i)+=h(i);
    680     #define Rx_RORX_3(i) h(i)+=S0_RORX(a(i))+Maj(a(i),b(i),c(i));
    681 #endif /* HAVE_INTEL_RORX */
     1140#define RND_RORX_0_1(a, b, c, d, e, f, g, h, i) \
     1141    /* L1 = e>>>14 */                           \
     1142    "rorxq      $14, "#e", " L1 "\n\t"          \
     1143    /* L2 = e>>>18 */                           \
     1144    "rorxq      $18, "#e", " L2 "\n\t"          \
     1145    /* Prev RND: h += Maj(a,b,c) */             \
     1146    "addq       " L3 ", "#a"\n\t"               \
     1147
     1148#define RND_RORX_0_2(a, b, c, d, e, f, g, h, i) \
     1149    /* h += w_k */                              \
     1150    "addq       ("#i")*8(" WX "), "#h"\n\t"     \
     1151    /* L3 = f */                                \
     1152    "movq       "#f", " L3 "\n\t"               \
     1153    /* L2 = (e>>>14) ^ (e>>>18) */              \
     1154    "xorq       " L1 ", " L2 "\n\t"             \
     1155
     1156#define RND_RORX_0_3(a, b, c, d, e, f, g, h, i) \
     1157    /* L3 = f ^ g */                            \
     1158    "xorq       "#g", " L3 "\n\t"               \
     1159    /* L1 = e>>>41 */                           \
     1160    "rorxq      $41, "#e", " L1 "\n\t"          \
     1161    /* L1 = Sigma1(e) */                        \
     1162    "xorq       " L2 ", " L1 "\n\t"             \
     1163
     1164#define RND_RORX_0_4(a, b, c, d, e, f, g, h, i) \
     1165    /* L3 = (f ^ g) & e */                      \
     1166    "andq       "#e", " L3 "\n\t"               \
     1167    /* h += Sigma1(e) */                        \
     1168    "addq       " L1 ", "#h"\n\t"               \
     1169    /* L1 = a>>>28 */                           \
     1170    "rorxq      $28, "#a", " L1 "\n\t"          \
     1171
     1172#define RND_RORX_0_5(a, b, c, d, e, f, g, h, i) \
     1173    /* L2 = a>>>34 */                           \
     1174    "rorxq      $34, "#a", " L2 "\n\t"          \
     1175    /* L3 = Ch(e,f,g) */                        \
     1176    "xorq       "#g", " L3 "\n\t"               \
     1177    /* L2 = (a>>>28) ^ (a>>>34) */              \
     1178    "xorq       " L1 ", " L2 "\n\t"             \
     1179
     1180#define RND_RORX_0_6(a, b, c, d, e, f, g, h, i) \
     1181    /* L1 = a>>>39 */                           \
     1182    "rorxq      $39, "#a", " L1 "\n\t"          \
     1183    /* h += Ch(e,f,g) */                        \
     1184    "addq       " L3 ", "#h"\n\t"               \
     1185    /* L1 = Sigma0(a) */                        \
     1186    "xorq       " L2 ", " L1 "\n\t"             \
     1187
     1188#define RND_RORX_0_7(a, b, c, d, e, f, g, h, i) \
     1189    /* L3 = b */                                \
     1190    "movq       "#b", " L3 "\n\t"               \
     1191    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */  \
     1192    "addq       "#h", "#d"\n\t"                 \
     1193    /* L3 = a ^ b */                            \
     1194    "xorq       "#a", " L3 "\n\t"               \
     1195
     1196#define RND_RORX_0_8(a, b, c, d, e, f, g, h, i) \
     1197    /* L4 = (a ^ b) & (b ^ c) */                \
     1198    "andq       " L3 ", " L4 "\n\t"             \
     1199    /* h += Sigma0(a) */                        \
     1200    "addq       " L1 ", "#h"\n\t"               \
     1201    /* L4 = Maj(a,b,c) */                       \
     1202    "xorq       "#b", " L4 "\n\t"               \
     1203
     1204#define RND_RORX_1_1(a, b, c, d, e, f, g, h, i) \
     1205    /* L1 = e>>>14 */                           \
     1206    "rorxq      $14, "#e", " L1 "\n\t"          \
     1207    /* L2 = e>>>18 */                           \
     1208    "rorxq      $18, "#e", " L2 "\n\t"          \
     1209    /* Prev RND: h += Maj(a,b,c) */             \
     1210    "addq       " L4 ", "#a"\n\t"               \
     1211
     1212#define RND_RORX_1_2(a, b, c, d, e, f, g, h, i) \
     1213    /* h += w_k */                              \
     1214    "addq       ("#i")*8(" WX "), "#h"\n\t"     \
     1215    /* L4 = f */                                \
     1216    "movq       "#f", " L4 "\n\t"               \
     1217    /* L2 = (e>>>14) ^ (e>>>18) */              \
     1218    "xorq       " L1 ", " L2 "\n\t"             \
     1219
     1220#define RND_RORX_1_3(a, b, c, d, e, f, g, h, i) \
     1221    /* L4 = f ^ g */                            \
     1222    "xorq       "#g", " L4 "\n\t"               \
     1223    /* L1 = e>>>41 */                           \
     1224    "rorxq      $41, "#e", " L1 "\n\t"          \
     1225    /* L1 = Sigma1(e) */                        \
     1226    "xorq       " L2 ", " L1 "\n\t"             \
     1227
     1228#define RND_RORX_1_4(a, b, c, d, e, f, g, h, i) \
     1229    /* L4 = (f ^ g) & e */                      \
     1230    "andq       "#e", " L4 "\n\t"               \
     1231    /* h += Sigma1(e) */                        \
     1232    "addq       " L1 ", "#h"\n\t"               \
     1233    /* L1 = a>>>28 */                           \
     1234    "rorxq      $28, "#a", " L1 "\n\t"          \
     1235
     1236#define RND_RORX_1_5(a, b, c, d, e, f, g, h, i) \
     1237    /* L2 = a>>>34 */                           \
     1238    "rorxq      $34, "#a", " L2 "\n\t"          \
     1239    /* L4 = Ch(e,f,g) */                        \
     1240    "xorq       "#g", " L4 "\n\t"               \
     1241    /* L2 = (a>>>28) ^ (a>>>34) */              \
     1242    "xorq       " L1 ", " L2 "\n\t"             \
     1243
     1244#define RND_RORX_1_6(a, b, c, d, e, f, g, h, i) \
     1245    /* L1 = a>>>39 */                           \
     1246    "rorxq      $39, "#a", " L1 "\n\t"          \
     1247    /* h += Ch(e,f,g) */                        \
     1248    "addq       " L4 ", "#h"\n\t"               \
     1249    /* L1 = Sigma0(a) */                        \
     1250    "xorq       " L2 ", " L1 "\n\t"             \
     1251
     1252#define RND_RORX_1_7(a, b, c, d, e, f, g, h, i) \
     1253    /* L4 = b */                                \
     1254    "movq       "#b", " L4 "\n\t"               \
     1255    /* d += h + w_k + Sigma1(e) + Ch(e,f,g) */  \
     1256    "addq       "#h", "#d"\n\t"                 \
     1257    /* L4 = a ^ b */                            \
     1258    "xorq       "#a", " L4 "\n\t"               \
     1259
     1260#define RND_RORX_1_8(a, b, c, d, e, f, g, h, i) \
     1261    /* L2 = (a ^ b) & (b ^ c) */                \
     1262    "andq       " L4 ", " L3 "\n\t"             \
     1263    /* h += Sigma0(a) */                        \
     1264    "addq       " L1 ", "#h"\n\t"               \
     1265    /* L3 = Maj(a,b,c) */                       \
     1266    "xorq       "#b", " L3 "\n\t"               \
     1267
     1268#define RND_RORX_ALL_2(a, b, c, d, e, f, g, h, i) \
     1269    RND_RORX_0_1(a, b, c, d, e, f, g, h, i+0)     \
     1270    RND_RORX_0_2(a, b, c, d, e, f, g, h, i+0)     \
     1271    RND_RORX_0_3(a, b, c, d, e, f, g, h, i+0)     \
     1272    RND_RORX_0_4(a, b, c, d, e, f, g, h, i+0)     \
     1273    RND_RORX_0_5(a, b, c, d, e, f, g, h, i+0)     \
     1274    RND_RORX_0_6(a, b, c, d, e, f, g, h, i+0)     \
     1275    RND_RORX_0_7(a, b, c, d, e, f, g, h, i+0)     \
     1276    RND_RORX_0_8(a, b, c, d, e, f, g, h, i+0)     \
     1277    RND_RORX_1_1(h, a, b, c, d, e, f, g, i+1)     \
     1278    RND_RORX_1_2(h, a, b, c, d, e, f, g, i+1)     \
     1279    RND_RORX_1_3(h, a, b, c, d, e, f, g, i+1)     \
     1280    RND_RORX_1_4(h, a, b, c, d, e, f, g, i+1)     \
     1281    RND_RORX_1_5(h, a, b, c, d, e, f, g, i+1)     \
     1282    RND_RORX_1_6(h, a, b, c, d, e, f, g, i+1)     \
     1283    RND_RORX_1_7(h, a, b, c, d, e, f, g, i+1)     \
     1284    RND_RORX_1_8(h, a, b, c, d, e, f, g, i+1)     \
     1285
     1286#define RND_RORX_ALL_4(a, b, c, d, e, f, g, h, i) \
     1287    RND_RORX_ALL_2(a, b, c, d, e, f, g, h, i+0)   \
     1288    RND_RORX_ALL_2(g, h, a, b, c, d, e, f, i+2)
     1289
     1290#define MsgSched_RORX(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,a,b,c,d,e,f,g,h,i) \
     1291            RND_RORX_0_1(a,b,c,d,e,f,g,h,i)                                 \
     1292    VPALIGNR(W_M15, W_2, W_0, 8)                                            \
     1293    VPALIGNR(W_M7, W_10, W_8, 8)                                            \
     1294            RND_RORX_0_2(a,b,c,d,e,f,g,h,i)                                 \
     1295    V_SHIFT_R(XTMP1, W_M15, 1)                                              \
     1296    V_SHIFT_L(XTMP2, W_M15, 63)                                             \
     1297            RND_RORX_0_3(a,b,c,d,e,f,g,h,i)                                 \
     1298    V_SHIFT_R(XTMP3, W_M15, 8)                                              \
     1299    V_SHIFT_L(XTMP4, W_M15, 56)                                             \
     1300            RND_RORX_0_4(a,b,c,d,e,f,g,h,i)                                 \
     1301    V_OR(XTMP1, XTMP2, XTMP1)                                               \
     1302    V_OR(XTMP3, XTMP4, XTMP3)                                               \
     1303            RND_RORX_0_5(a,b,c,d,e,f,g,h,i)                                 \
     1304    V_SHIFT_R(XTMP4, W_M15, 7)                                              \
     1305    V_XOR(XTMP1, XTMP3, XTMP1)                                              \
     1306            RND_RORX_0_6(a,b,c,d,e,f,g,h,i)                                 \
     1307    V_XOR(XTMP1, XTMP4, XTMP1)                                              \
     1308    V_ADD(W_0, W_0, W_M7)                                                   \
     1309            RND_RORX_0_7(a,b,c,d,e,f,g,h,i)                                 \
     1310            RND_RORX_0_8(a,b,c,d,e,f,g,h,i)                                 \
     1311    V_ADD(W_0, W_0, XTMP1)                                                  \
     1312            RND_RORX_1_1(h,a,b,c,d,e,f,g,i+1)                               \
     1313    V_SHIFT_R(XTMP1, W_14, 19)                                              \
     1314    V_SHIFT_L(XTMP2, W_14, 45)                                              \
     1315            RND_RORX_1_2(h,a,b,c,d,e,f,g,i+1)                               \
     1316    V_SHIFT_R(XTMP3, W_14, 61)                                              \
     1317    V_SHIFT_L(XTMP4, W_14, 3)                                               \
     1318            RND_RORX_1_3(h,a,b,c,d,e,f,g,i+1)                               \
     1319    V_OR(XTMP1, XTMP2, XTMP1)                                               \
     1320    V_OR(XTMP3, XTMP4, XTMP3)                                               \
     1321            RND_RORX_1_4(h,a,b,c,d,e,f,g,i+1)                               \
     1322            RND_RORX_1_5(h,a,b,c,d,e,f,g,i+1)                               \
     1323    V_XOR(XTMP1, XTMP3, XTMP1)                                              \
     1324    V_SHIFT_R(XTMP4, W_14, 6)                                               \
     1325            RND_RORX_1_6(h,a,b,c,d,e,f,g,i+1)                               \
     1326            RND_RORX_1_7(h,a,b,c,d,e,f,g,i+1)                               \
     1327    V_XOR(XTMP1, XTMP4, XTMP1)                                              \
     1328            RND_RORX_1_8(h,a,b,c,d,e,f,g,i+1)                               \
     1329    V_ADD(W_0, W_0, XTMP1)                                                  \
     1330
     1331#endif
     1332
     1333#define _INIT_MASK(mask) \
     1334    "vmovdqu %[mask], %%" #mask "\n\t"
     1335#define INIT_MASK(mask) \
     1336       _INIT_MASK(mask)
     1337
     1338#define _LOAD_W_2(i1, i2, xmm1, xmm2, mask, reg)           \
     1339    "vmovdqu    " #i1 "*16(%%" #reg "), %%" #xmm1 "\n\t"   \
     1340    "vmovdqu    " #i2 "*16(%%" #reg "), %%" #xmm2 "\n\t"   \
     1341    "vpshufb    %%" #mask ", %%" #xmm1 ", %%" #xmm1 "\n\t" \
     1342    "vpshufb    %%" #mask ", %%" #xmm2 ", %%" #xmm2 "\n\t"
     1343#define LOAD_W_2(i1, i2, xmm1, xmm2, mask, reg) \
     1344       _LOAD_W_2(i1, i2, xmm1, xmm2, mask, reg)
     1345
     1346#define LOAD_W(mask, reg)                           \
     1347    /* X0..3(xmm4..7), W[0..15] = buffer[0.15];  */ \
     1348    LOAD_W_2(0, 1, W_0 , W_2 , mask, reg)           \
     1349    LOAD_W_2(2, 3, W_4 , W_6 , mask, reg)           \
     1350    LOAD_W_2(4, 5, W_8 , W_10, mask, reg)           \
     1351    LOAD_W_2(6, 7, W_12, W_14, mask, reg)
     1352
     1353#define _SET_W_X_2(xmm0, xmm1, reg, i)                          \
     1354    "vpaddq     " #i "+ 0(%%" #reg "), %%" #xmm0 ", %%xmm8\n\t" \
     1355    "vpaddq     " #i "+16(%%" #reg "), %%" #xmm1 ", %%xmm9\n\t" \
     1356    "vmovdqu    %%xmm8, " #i "+ 0(" WX ")\n\t"                  \
     1357    "vmovdqu    %%xmm9, " #i "+16(" WX ")\n\t"                  \
     1358
     1359#define SET_W_X_2(xmm0, xmm1, reg, i) \
     1360       _SET_W_X_2(xmm0, xmm1, reg, i)
     1361
     1362#define SET_W_X(reg)                \
     1363    SET_W_X_2(W_0 , W_2 , reg,  0)  \
     1364    SET_W_X_2(W_4 , W_6 , reg, 32)  \
     1365    SET_W_X_2(W_8 , W_10, reg, 64)  \
     1366    SET_W_X_2(W_12, W_14, reg, 96)
     1367
     1368#define LOAD_DIGEST()                     \
     1369    "movq         (%[sha512]), %%r8 \n\t" \
     1370    "movq        8(%[sha512]), %%r9 \n\t" \
     1371    "movq       16(%[sha512]), %%r10\n\t" \
     1372    "movq       24(%[sha512]), %%r11\n\t" \
     1373    "movq       32(%[sha512]), %%r12\n\t" \
     1374    "movq       40(%[sha512]), %%r13\n\t" \
     1375    "movq       48(%[sha512]), %%r14\n\t" \
     1376    "movq       56(%[sha512]), %%r15\n\t"
     1377
     1378#define STORE_ADD_DIGEST()                \
     1379    "addq        %%r8,   (%[sha512])\n\t" \
     1380    "addq        %%r9,  8(%[sha512])\n\t" \
     1381    "addq       %%r10, 16(%[sha512])\n\t" \
     1382    "addq       %%r11, 24(%[sha512])\n\t" \
     1383    "addq       %%r12, 32(%[sha512])\n\t" \
     1384    "addq       %%r13, 40(%[sha512])\n\t" \
     1385    "addq       %%r14, 48(%[sha512])\n\t" \
     1386    "addq       %%r15, 56(%[sha512])\n\t"
     1387
     1388#define ADD_DIGEST()                      \
     1389    "addq         (%[sha512]), %%r8 \n\t" \
     1390    "addq        8(%[sha512]), %%r9 \n\t" \
     1391    "addq       16(%[sha512]), %%r10\n\t" \
     1392    "addq       24(%[sha512]), %%r11\n\t" \
     1393    "addq       32(%[sha512]), %%r12\n\t" \
     1394    "addq       40(%[sha512]), %%r13\n\t" \
     1395    "addq       48(%[sha512]), %%r14\n\t" \
     1396    "addq       56(%[sha512]), %%r15\n\t"
     1397
     1398#define STORE_DIGEST()                    \
     1399    "movq        %%r8,   (%[sha512])\n\t" \
     1400    "movq        %%r9,  8(%[sha512])\n\t" \
     1401    "movq       %%r10, 16(%[sha512])\n\t" \
     1402    "movq       %%r11, 24(%[sha512])\n\t" \
     1403    "movq       %%r12, 32(%[sha512])\n\t" \
     1404    "movq       %%r13, 40(%[sha512])\n\t" \
     1405    "movq       %%r14, 48(%[sha512])\n\t" \
     1406    "movq       %%r15, 56(%[sha512])\n\t"
    6821407
    6831408#endif /* HAVE_INTEL_AVX1 */
    684 
    685 #if defined(HAVE_INTEL_AVX2)
    686 #define Ry_1(i, w) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j] + w;
    687 #define Ry_2(i, w) d(i)+=h(i);
    688 #define Ry_3(i, w) h(i)+=S0(a(i))+Maj(a(i),b(i),c(i));
    689 #endif /* HAVE_INTEL_AVX2 */
    690 
    691 /* INLINE Assember for Intel AVX1 instructions */
    692 #if defined(HAVE_INTEL_AVX1)
    693 #if defined(DEBUG_XMM)
    694     #define SAVE_REG(i)     __asm__ volatile("vmovdqu %%xmm"#i", %0 \n\t":"=m"(reg[i][0]):);
    695     #define RECV_REG(i)     __asm__ volatile("vmovdqu %0, %%xmm"#i" \n\t"::"m"(reg[i][0]));
    696 
    697     #define _DUMP_REG(REG, name)\
    698         { word64 buf[16];word64 reg[16][2];int k;\
    699           SAVE_REG(0); SAVE_REG(1); SAVE_REG(2);  SAVE_REG(3);  SAVE_REG(4);  \
    700           SAVE_REG(5);   SAVE_REG(6); SAVE_REG(7);SAVE_REG(8); SAVE_REG(9); SAVE_REG(10);\
    701            SAVE_REG(11); SAVE_REG(12); SAVE_REG(13); SAVE_REG(14); SAVE_REG(15); \
    702           __asm__ volatile("vmovdqu %%"#REG", %0 \n\t":"=m"(buf[0]):);\
    703           printf(" "#name":\t"); for(k=0; k<2; k++) printf("%016lx.", (word64)(buf[k])); printf("\n"); \
    704           RECV_REG(0); RECV_REG(1); RECV_REG(2);  RECV_REG(3);  RECV_REG(4);\
    705           RECV_REG(5);   RECV_REG(6); RECV_REG(7); RECV_REG(8); RECV_REG(9);\
    706           RECV_REG(10); RECV_REG(11); RECV_REG(12); RECV_REG(13); RECV_REG(14); RECV_REG(15);\
    707         }
    708 
    709     #define DUMP_REG(REG) _DUMP_REG(REG, #REG)
    710     #define PRINTF(fmt, ...)
    711 #else
    712     #define DUMP_REG(REG)
    713     #define PRINTF(fmt, ...)
    714 #endif /* DEBUG_XMM */
    715 
    716 #define _MOVE_to_REG(xymm, mem)       __asm__ volatile("vmovdqu %0, %%"#xymm" "\
    717         :: "m"(mem));
    718 #define _MOVE_to_MEM(mem,i, xymm)     __asm__ volatile("vmovdqu %%"#xymm", %0" :\
    719          "=m"(mem[i]),"=m"(mem[i+1]),"=m"(mem[i+2]),"=m"(mem[i+3]):);
    720 #define _MOVE(dest, src)              __asm__ volatile("vmovdqu %%"#src",  %%"\
    721         #dest" "::);
    722 
    723 #define _S_TEMP(dest, src, bits, temp)  __asm__ volatile("vpsrlq  $"#bits", %%"\
    724         #src", %%"#dest"\n\tvpsllq  $64-"#bits", %%"#src", %%"#temp"\n\tvpor %%"\
    725         #temp",%%"#dest", %%"#dest" "::);
    726 #define _AVX1_R(dest, src, bits)      __asm__ volatile("vpsrlq  $"#bits", %%"\
    727         #src", %%"#dest" "::);
    728 #define _XOR(dest, src1, src2)        __asm__ volatile("vpxor   %%"#src1", %%"\
    729         #src2", %%"#dest" "::);
    730 #define _OR(dest, src1, src2)         __asm__ volatile("vpor    %%"#src1", %%"\
    731         #src2", %%"#dest" "::);
    732 #define _ADD(dest, src1, src2)        __asm__ volatile("vpaddq   %%"#src1", %%"\
    733         #src2", %%"#dest" "::);
    734 #define _ADD_MEM(dest, src1, mem)     __asm__ volatile("vpaddq   %0, %%"#src1", %%"\
    735         #dest" "::"m"(mem));
    736 
    737 #define MOVE_to_REG(xymm, mem)      _MOVE_to_REG(xymm, mem)
    738 #define MOVE_to_MEM(mem, i, xymm)   _MOVE_to_MEM(mem, i, xymm)
    739 #define MOVE(dest, src)             _MOVE(dest, src)
    740 
    741 #define XOR(dest, src1, src2)      _XOR(dest, src1, src2)
    742 #define OR(dest, src1, src2)       _OR(dest, src1, src2)
    743 #define ADD(dest, src1, src2)      _ADD(dest, src1, src2)
    744 
    745 #define S_TMP(dest, src, bits, temp) _S_TEMP(dest, src, bits, temp);
    746 #define AVX1_S(dest, src, bits)      S_TMP(dest, src, bits, S_TEMP)
    747 #define AVX1_R(dest, src, bits)      _AVX1_R(dest, src, bits)
    748 
    749 #define Init_Mask(mask) \
    750      __asm__ volatile("vmovdqu %0, %%xmm1\n\t"::"m"(mask):"%xmm1");
    751 
    752 #define _W_from_buff1(w, buff, xmm) \
    753     /* X0..3(xmm4..7), W[0..15] = sha512->buffer[0.15];  */\
    754      __asm__ volatile("vmovdqu %1, %%"#xmm"\n\t"\
    755                       "vpshufb %%xmm1, %%"#xmm", %%"#xmm"\n\t"\
    756                       "vmovdqu %%"#xmm", %0"\
    757                       :"=m"(w): "m"(buff):"%xmm0");
    758 
    759 #define W_from_buff1(w, buff, xmm) _W_from_buff1(w, buff, xmm)
    760 
    761 #define W_from_buff(w, buff)\
    762      Init_Mask(mBYTE_FLIP_MASK[0]);\
    763      W_from_buff1(w[0], buff[0], W_0);\
    764      W_from_buff1(w[2], buff[2], W_2);\
    765      W_from_buff1(w[4], buff[4], W_4);\
    766      W_from_buff1(w[6], buff[6], W_6);\
    767      W_from_buff1(w[8], buff[8], W_8);\
    768      W_from_buff1(w[10],buff[10],W_10);\
    769      W_from_buff1(w[12],buff[12],W_12);\
    770      W_from_buff1(w[14],buff[14],W_14);
    771 
    772 static word64 mBYTE_FLIP_MASK[] =  { 0x0001020304050607, 0x08090a0b0c0d0e0f };
    773 
    774 #define W_I_15  xmm14
    775 #define W_I_7   xmm11
    776 #define W_I_2   xmm13
    777 #define W_I     xmm12
    778 #define G_TEMP  xmm0
    779 #define S_TEMP  xmm1
    780 #define XMM_TEMP0  xmm2
    781 
    782 #define W_0     xmm12
    783 #define W_2     xmm3
    784 #define W_4     xmm4
    785 #define W_6     xmm5
    786 #define W_8     xmm6
    787 #define W_10    xmm7
    788 #define W_12    xmm8
    789 #define W_14    xmm9
    790 
    791 #define s0_1(dest, src)      AVX1_S(dest, src, 1);
    792 #define s0_2(dest, src)      AVX1_S(G_TEMP, src, 8); XOR(dest, G_TEMP, dest);
    793 #define s0_3(dest, src)      AVX1_R(G_TEMP, src, 7);  XOR(dest, G_TEMP, dest);
    794 
    795 #define s1_1(dest, src)      AVX1_S(dest, src, 19);
    796 #define s1_2(dest, src)      AVX1_S(G_TEMP, src, 61); XOR(dest, G_TEMP, dest);
    797 #define s1_3(dest, src)      AVX1_R(G_TEMP, src, 6); XOR(dest, G_TEMP, dest);
    798 
    799 #define s0_(dest, src)       s0_1(dest, src); s0_2(dest, src); s0_3(dest, src)
    800 #define s1_(dest, src)       s1_1(dest, src); s1_2(dest, src); s1_3(dest, src)
    801 
    802 #define Block_xx_1(i) \
    803     MOVE_to_REG(W_I_15, W_X[(i-15)&15]);\
    804     MOVE_to_REG(W_I_7,  W_X[(i- 7)&15]);\
    805 
    806 #define Block_xx_2(i) \
    807     MOVE_to_REG(W_I_2,  W_X[(i- 2)&15]);\
    808     MOVE_to_REG(W_I,    W_X[(i)]);\
    809 
    810 #define Block_xx_3(i) \
    811     s0_ (XMM_TEMP0, W_I_15);\
    812 
    813 #define Block_xx_4(i) \
    814     ADD(W_I, W_I, XMM_TEMP0);\
    815     ADD(W_I, W_I, W_I_7);\
    816 
    817 #define Block_xx_5(i) \
    818     s1_ (XMM_TEMP0, W_I_2);\
    819 
    820 #define Block_xx_6(i) \
    821     ADD(W_I, W_I, XMM_TEMP0);\
    822     MOVE_to_MEM(W_X,i, W_I);\
    823     if (i==0)\
    824         MOVE_to_MEM(W_X,16, W_I);\
    825 
    826 #define Block_xx_7(i) \
    827     MOVE_to_REG(W_I_15, W_X[(i-15)&15]);\
    828     MOVE_to_REG(W_I_7,  W_X[(i- 7)&15]);\
    829 
    830 #define Block_xx_8(i) \
    831     MOVE_to_REG(W_I_2,  W_X[(i- 2)&15]);\
    832     MOVE_to_REG(W_I,    W_X[(i)]);\
    833 
    834 #define Block_xx_9(i) \
    835     s0_ (XMM_TEMP0, W_I_15);\
    836 
    837 #define Block_xx_10(i) \
    838     ADD(W_I, W_I, XMM_TEMP0);\
    839     ADD(W_I, W_I, W_I_7);\
    840 
    841 #define Block_xx_11(i) \
    842     s1_ (XMM_TEMP0, W_I_2);\
    843 
    844 #define Block_xx_12(i) \
    845     ADD(W_I, W_I, XMM_TEMP0);\
    846     MOVE_to_MEM(W_X,i, W_I);\
    847     if ((i)==0)\
    848         MOVE_to_MEM(W_X,16, W_I);\
    849 
    850 static INLINE void Block_0_1(word64 *W_X) { Block_xx_1(0); }
    851 static INLINE void Block_0_2(word64 *W_X) { Block_xx_2(0); }
    852 static INLINE void Block_0_3(void) { Block_xx_3(0); }
    853 static INLINE void Block_0_4(void) { Block_xx_4(0); }
    854 static INLINE void Block_0_5(void) { Block_xx_5(0); }
    855 static INLINE void Block_0_6(word64 *W_X) { Block_xx_6(0); }
    856 static INLINE void Block_0_7(word64 *W_X) { Block_xx_7(2); }
    857 static INLINE void Block_0_8(word64 *W_X) { Block_xx_8(2); }
    858 static INLINE void Block_0_9(void) { Block_xx_9(2); }
    859 static INLINE void Block_0_10(void){ Block_xx_10(2); }
    860 static INLINE void Block_0_11(void){ Block_xx_11(2); }
    861 static INLINE void Block_0_12(word64 *W_X){ Block_xx_12(2); }
    862 
    863 static INLINE void Block_4_1(word64 *W_X) { Block_xx_1(4); }
    864 static INLINE void Block_4_2(word64 *W_X) { Block_xx_2(4); }
    865 static INLINE void Block_4_3(void) { Block_xx_3(4); }
    866 static INLINE void Block_4_4(void) { Block_xx_4(4); }
    867 static INLINE void Block_4_5(void) { Block_xx_5(4); }
    868 static INLINE void Block_4_6(word64 *W_X) { Block_xx_6(4); }
    869 static INLINE void Block_4_7(word64 *W_X) { Block_xx_7(6); }
    870 static INLINE void Block_4_8(word64 *W_X) { Block_xx_8(6); }
    871 static INLINE void Block_4_9(void) { Block_xx_9(6); }
    872 static INLINE void Block_4_10(void){ Block_xx_10(6); }
    873 static INLINE void Block_4_11(void){ Block_xx_11(6); }
    874 static INLINE void Block_4_12(word64 *W_X){ Block_xx_12(6); }
    875 
    876 static INLINE void Block_8_1(word64 *W_X) { Block_xx_1(8); }
    877 static INLINE void Block_8_2(word64 *W_X) { Block_xx_2(8); }
    878 static INLINE void Block_8_3(void) { Block_xx_3(8); }
    879 static INLINE void Block_8_4(void) { Block_xx_4(8); }
    880 static INLINE void Block_8_5(void) { Block_xx_5(8); }
    881 static INLINE void Block_8_6(word64 *W_X) { Block_xx_6(8); }
    882 static INLINE void Block_8_7(word64 *W_X) { Block_xx_7(10); }
    883 static INLINE void Block_8_8(word64 *W_X) { Block_xx_8(10); }
    884 static INLINE void Block_8_9(void) { Block_xx_9(10); }
    885 static INLINE void Block_8_10(void){ Block_xx_10(10); }
    886 static INLINE void Block_8_11(void){ Block_xx_11(10); }
    887 static INLINE void Block_8_12(word64 *W_X){ Block_xx_12(10); }
    888 
    889 static INLINE void Block_12_1(word64 *W_X) { Block_xx_1(12); }
    890 static INLINE void Block_12_2(word64 *W_X) { Block_xx_2(12); }
    891 static INLINE void Block_12_3(void) { Block_xx_3(12); }
    892 static INLINE void Block_12_4(void) { Block_xx_4(12); }
    893 static INLINE void Block_12_5(void) { Block_xx_5(12); }
    894 static INLINE void Block_12_6(word64 *W_X) { Block_xx_6(12); }
    895 static INLINE void Block_12_7(word64 *W_X) { Block_xx_7(14); }
    896 static INLINE void Block_12_8(word64 *W_X) { Block_xx_8(14); }
    897 static INLINE void Block_12_9(void) { Block_xx_9(14); }
    898 static INLINE void Block_12_10(void){ Block_xx_10(14); }
    899 static INLINE void Block_12_11(void){ Block_xx_11(14); }
    900 static INLINE void Block_12_12(word64 *W_X){ Block_xx_12(14); }
    901 
    902 #endif /* HAVE_INTEL_AVX1 */
    903 
    904 #if defined(HAVE_INTEL_AVX2)
    905 static const unsigned long mBYTE_FLIP_MASK_Y[] =
    906    { 0x0001020304050607, 0x08090a0b0c0d0e0f, 0x0001020304050607, 0x08090a0b0c0d0e0f };
    907 
    908 #define W_from_buff_Y(buff)\
    909     { /* X0..3(ymm9..12), W_X[0..15] = sha512->buffer[0.15];  */\
    910      __asm__ volatile("vmovdqu %0, %%ymm8\n\t"::"m"(mBYTE_FLIP_MASK_Y[0]));\
    911      __asm__ volatile("vmovdqu %0, %%ymm12\n\t"\
    912                       "vmovdqu %1, %%ymm4\n\t"\
    913                       "vpshufb %%ymm8, %%ymm12, %%ymm12\n\t"\
    914                       "vpshufb %%ymm8, %%ymm4, %%ymm4\n\t"\
    915                       :: "m"(buff[0]),  "m"(buff[4]));\
    916      __asm__ volatile("vmovdqu %0, %%ymm5\n\t"\
    917                       "vmovdqu %1, %%ymm6\n\t"\
    918                       "vpshufb %%ymm8, %%ymm5, %%ymm5\n\t"\
    919                       "vpshufb %%ymm8, %%ymm6, %%ymm6\n\t"\
    920                       :: "m"(buff[8]),  "m"(buff[12]));\
    921     }
    922 
    923 #if defined(DEBUG_YMM)
    924     #define SAVE_REG_Y(i) __asm__ volatile("vmovdqu %%ymm"#i", %0 \n\t":"=m"(reg[i-4][0]):);
    925     #define RECV_REG_Y(i) __asm__ volatile("vmovdqu %0, %%ymm"#i" \n\t"::"m"(reg[i-4][0]));
    926 
    927     #define _DUMP_REG_Y(REG, name)\
    928         { word64 buf[16];word64 reg[16][2];int k;\
    929           SAVE_REG_Y(4);  SAVE_REG_Y(5);   SAVE_REG_Y(6); SAVE_REG_Y(7); \
    930           SAVE_REG_Y(8); SAVE_REG_Y(9); SAVE_REG_Y(10); SAVE_REG_Y(11); SAVE_REG_Y(12);\
    931           SAVE_REG_Y(13); SAVE_REG_Y(14); SAVE_REG_Y(15); \
    932           __asm__ volatile("vmovdqu %%"#REG", %0 \n\t":"=m"(buf[0]):);\
    933           printf(" "#name":\t"); for(k=0; k<4; k++) printf("%016lx.", (word64)buf[k]); printf("\n"); \
    934           RECV_REG_Y(4);  RECV_REG_Y(5);   RECV_REG_Y(6); RECV_REG_Y(7); \
    935           RECV_REG_Y(8); RECV_REG_Y(9); RECV_REG_Y(10); RECV_REG_Y(11); RECV_REG_Y(12); \
    936           RECV_REG_Y(13); RECV_REG_Y(14); RECV_REG_Y(15);\
    937         }
    938 
    939     #define DUMP_REG_Y(REG) _DUMP_REG_Y(REG, #REG)
    940     #define DUMP_REG2_Y(REG) _DUMP_REG_Y(REG, #REG)
    941     #define PRINTF_Y(fmt, ...)
    942 #else
    943     #define DUMP_REG_Y(REG)
    944     #define DUMP_REG2_Y(REG)
    945     #define PRINTF_Y(fmt, ...)
    946 #endif /* DEBUG_YMM */
    947 
    948 #define _MOVE_to_REGy(ymm, mem)         __asm__ volatile("vmovdqu %0, %%"#ymm" "\
    949                                         :: "m"(mem));
    950 #define _MOVE_to_MEMy(mem,i, ymm)       __asm__ volatile("vmovdqu %%"#ymm", %0" \
    951         : "=m"(mem[i]),"=m"(mem[i+1]),"=m"(mem[i+2]),"=m"(mem[i+3]):);
    952 #define _MOVE_128y(ymm0, ymm1, ymm2, map)  __asm__ volatile("vperm2i128  $"\
    953         #map", %%"#ymm2", %%"#ymm1", %%"#ymm0" "::);
    954 #define _S_TEMPy(dest, src, bits, temp) \
    955          __asm__ volatile("vpsrlq  $"#bits", %%"#src", %%"#dest"\n\tvpsllq  $64-"#bits\
    956         ", %%"#src", %%"#temp"\n\tvpor %%"#temp",%%"#dest", %%"#dest" "::);
    957 #define _AVX2_R(dest, src, bits)        __asm__ volatile("vpsrlq  $"#bits", %%"\
    958          #src", %%"#dest" "::);
    959 #define _XORy(dest, src1, src2)         __asm__ volatile("vpxor   %%"#src1", %%"\
    960          #src2", %%"#dest" "::);
    961 #define _ADDy(dest, src1, src2)         __asm__ volatile("vpaddq   %%"#src1", %%"\
    962          #src2", %%"#dest" "::);
    963 #define _BLENDy(map, dest, src1, src2)  __asm__ volatile("vpblendd    $"#map", %%"\
    964          #src1",   %%"#src2", %%"#dest" "::);
    965 #define _BLENDQy(map, dest, src1, src2) __asm__ volatile("vblendpd   $"#map", %%"\
    966          #src1",   %%"#src2", %%"#dest" "::);
    967 #define _PERMQy(map, dest, src)         __asm__ volatile("vpermq  $"#map", %%"\
    968          #src", %%"#dest" "::);
    969 
    970 #define MOVE_to_REGy(ymm, mem)      _MOVE_to_REGy(ymm, mem)
    971 #define MOVE_to_MEMy(mem, i, ymm)   _MOVE_to_MEMy(mem, i, ymm)
    972 
    973 #define MOVE_128y(ymm0, ymm1, ymm2, map) _MOVE_128y(ymm0, ymm1, ymm2, map)
    974 #define XORy(dest, src1, src2)      _XORy(dest, src1, src2)
    975 #define ADDy(dest, src1, src2)      _ADDy(dest, src1, src2)
    976 #define BLENDy(map, dest, src1, src2) _BLENDy(map, dest, src1, src2)
    977 #define BLENDQy(map, dest, src1, src2) _BLENDQy(map, dest, src1, src2)
    978 #define PERMQy(map, dest, src)      _PERMQy(map, dest, src)
    979 
    980 
    981 #define S_TMPy(dest, src, bits, temp) _S_TEMPy(dest, src, bits, temp);
    982 #define AVX2_S(dest, src, bits)      S_TMPy(dest, src, bits, S_TEMPy)
    983 #define AVX2_R(dest, src, bits)      _AVX2_R(dest, src, bits)
    984 
    985 
    986 #define    FEEDBACK1_to_W_I_2(w_i_2, w_i)    MOVE_128y(YMM_TEMP0, w_i, w_i, 0x08);\
    987                                        BLENDy(0xf0, w_i_2, YMM_TEMP0, w_i_2);
    988 
    989 #define    MOVE_W_to_W_I_15(w_i_15, w_0, w_4)  BLENDQy(0x1, w_i_15, w_4, w_0);\
    990                                        PERMQy(0x39, w_i_15, w_i_15);
    991 #define    MOVE_W_to_W_I_7(w_i_7,  w_8, w_12)  BLENDQy(0x1, w_i_7, w_12, w_8);\
    992                                        PERMQy(0x39, w_i_7, w_i_7);
    993 #define    MOVE_W_to_W_I_2(w_i_2,  w_12)       BLENDQy(0xc, w_i_2, w_12, w_i_2);\
    994                                        PERMQy(0x0e, w_i_2, w_i_2);
    995 
    996 
    997 #define W_I_16y  ymm8
    998 #define W_I_15y  ymm9
    999 #define W_I_7y  ymm10
    1000 #define W_I_2y  ymm11
    1001 #define W_Iy    ymm12
    1002 #define G_TEMPy     ymm13
    1003 #define S_TEMPy     ymm14
    1004 #define YMM_TEMP0  ymm15
    1005 #define YMM_TEMP0x xmm15
    1006 #define W_I_TEMPy   ymm7
    1007 #define W_K_TEMPy   ymm15
    1008 #define W_K_TEMPx  xmm15
    1009 #define W_0y     ymm12
    1010 #define W_4y     ymm4
    1011 #define W_8y     ymm5
    1012 #define W_12y    ymm6
    1013 
    1014 
    1015 #define MOVE_15_to_16(w_i_16, w_i_15, w_i_7)\
    1016     __asm__ volatile("vperm2i128  $0x01, %%"#w_i_15", %%"#w_i_15", %%"#w_i_15" "::);\
    1017     __asm__ volatile("vpblendd    $0x08, %%"#w_i_15", %%"#w_i_7", %%"#w_i_16" "::);\
    1018     __asm__ volatile("vperm2i128 $0x01,  %%"#w_i_7",  %%"#w_i_7", %%"#w_i_15" "::);\
    1019     __asm__ volatile("vpblendd    $0x80, %%"#w_i_15", %%"#w_i_16", %%"#w_i_16" "::);\
    1020     __asm__ volatile("vpshufd    $0x93,  %%"#w_i_16", %%"#w_i_16" "::);\
    1021 
    1022 #define MOVE_7_to_15(w_i_15, w_i_7)\
    1023     __asm__ volatile("vmovdqu                 %%"#w_i_7",  %%"#w_i_15" "::);\
    1024 
    1025 #define MOVE_I_to_7(w_i_7, w_i)\
    1026     __asm__ volatile("vperm2i128 $0x01,       %%"#w_i",   %%"#w_i",   %%"#w_i_7" "::);\
    1027     __asm__ volatile("vpblendd    $0x01,       %%"#w_i_7",   %%"#w_i", %%"#w_i_7" "::);\
    1028     __asm__ volatile("vpshufd    $0x39, %%"#w_i_7", %%"#w_i_7" "::);\
    1029 
    1030 #define MOVE_I_to_2(w_i_2, w_i)\
    1031     __asm__ volatile("vperm2i128 $0x01,       %%"#w_i", %%"#w_i", %%"#w_i_2" "::);\
    1032     __asm__ volatile("vpshufd    $0x0e, %%"#w_i_2", %%"#w_i_2" "::);\
    1033 
    1034 #endif /* HAVE_INTEL_AVX2 */
    10351409
    10361410
    10371411/***  Transform Body ***/
    10381412#if defined(HAVE_INTEL_AVX1)
    1039 static int Transform_AVX1(wc_Sha512* sha512)
     1413static int Transform_Sha512_AVX1(wc_Sha512* sha512)
    10401414{
    1041     const word64* K = K512;
    1042     word64 W_X[16+4] = {0};
    1043     word32 j;
    1044     word64 T[8];
    1045 
    1046     /* Copy digest to working vars */
    1047     XMEMCPY(T, sha512->digest, sizeof(T));
    1048 
    1049     W_from_buff(W_X, sha512->buffer);
    1050     for (j = 0; j < 80; j += 16) {
    1051         Rx_1( 0); Block_0_1(W_X); Rx_2( 0); Block_0_2(W_X); Rx_3( 0); Block_0_3();
    1052         Rx_1( 1); Block_0_4(); Rx_2( 1); Block_0_5(); Rx_3( 1); Block_0_6(W_X);
    1053         Rx_1( 2); Block_0_7(W_X); Rx_2( 2); Block_0_8(W_X); Rx_3( 2); Block_0_9();
    1054         Rx_1( 3); Block_0_10();Rx_2( 3); Block_0_11();Rx_3( 3); Block_0_12(W_X);
    1055 
    1056         Rx_1( 4); Block_4_1(W_X); Rx_2( 4); Block_4_2(W_X); Rx_3( 4); Block_4_3();
    1057         Rx_1( 5); Block_4_4(); Rx_2( 5); Block_4_5(); Rx_3( 5); Block_4_6(W_X);
    1058         Rx_1( 6); Block_4_7(W_X); Rx_2( 6); Block_4_8(W_X); Rx_3( 6); Block_4_9();
    1059         Rx_1( 7); Block_4_10();Rx_2( 7); Block_4_11();Rx_3( 7); Block_4_12(W_X);
    1060 
    1061         Rx_1( 8); Block_8_1(W_X); Rx_2( 8); Block_8_2(W_X); Rx_3( 8); Block_8_3();
    1062         Rx_1( 9); Block_8_4(); Rx_2( 9); Block_8_5(); Rx_3( 9); Block_8_6(W_X);
    1063         Rx_1(10); Block_8_7(W_X); Rx_2(10); Block_8_8(W_X); Rx_3(10); Block_8_9();
    1064         Rx_1(11); Block_8_10();Rx_2(11); Block_8_11();Rx_3(11); Block_8_12(W_X);
    1065 
    1066         Rx_1(12); Block_12_1(W_X); Rx_2(12); Block_12_2(W_X); Rx_3(12); Block_12_3();
    1067         Rx_1(13); Block_12_4(); Rx_2(13); Block_12_5(); Rx_3(13); Block_12_6(W_X);
    1068         Rx_1(14); Block_12_7(W_X); Rx_2(14); Block_12_8(W_X); Rx_3(14); Block_12_9();
    1069         Rx_1(15); Block_12_10();Rx_2(15); Block_12_11();Rx_3(15); Block_12_12(W_X);
    1070     }
    1071 
    1072     /* Add the working vars back into digest */
    1073     sha512->digest[0] += a(0);
    1074     sha512->digest[1] += b(0);
    1075     sha512->digest[2] += c(0);
    1076     sha512->digest[3] += d(0);
    1077     sha512->digest[4] += e(0);
    1078     sha512->digest[5] += f(0);
    1079     sha512->digest[6] += g(0);
    1080     sha512->digest[7] += h(0);
    1081 
    1082     /* Wipe variables */
    1083 #if !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
    1084     XMEMSET(W_X, 0, sizeof(word64) * 16);
    1085 #endif
    1086     XMEMSET(T, 0, sizeof(T));
     1415    __asm__ __volatile__ (
     1416
     1417        /* 16 Ws plus loop counter. */
     1418        "subq   $136, %%rsp\n\t"
     1419        "leaq   64(%[sha512]), %%rax\n\t"
     1420
     1421    INIT_MASK(MASK)
     1422    LOAD_DIGEST()
     1423
     1424    LOAD_W(MASK, rax)
     1425
     1426        "movl   $4, 16*8(" WX ")\n\t"
     1427        "leaq   %[K512], %%rsi\n\t"
     1428        /* b */
     1429        "movq   %%r9, " L4 "\n\t"
     1430        /* e */
     1431        "movq   %%r12, " L1 "\n\t"
     1432        /* b ^ c */
     1433        "xorq   %%r10, " L4 "\n\t"
     1434
     1435        "# Start of 16 rounds\n"
     1436        "1:\n\t"
     1437
     1438    SET_W_X(rsi)
     1439
     1440        "addq   $128, %%rsi\n\t"
     1441
     1442    MsgSched2(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1443    MsgSched2(W_2,W_4,W_6,W_8,W_10,W_12,W_14,W_0,RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1444    MsgSched2(W_4,W_6,W_8,W_10,W_12,W_14,W_0,W_2,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1445    MsgSched2(W_6,W_8,W_10,W_12,W_14,W_0,W_2,W_4,RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1446    MsgSched2(W_8,W_10,W_12,W_14,W_0,W_2,W_4,W_6,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1447    MsgSched2(W_10,W_12,W_14,W_0,W_2,W_4,W_6,W_8,RG,RH,RA,RB,RC,RD,RE,RF,10)
     1448    MsgSched2(W_12,W_14,W_0,W_2,W_4,W_6,W_8,W_10,RE,RF,RG,RH,RA,RB,RC,RD,12)
     1449    MsgSched2(W_14,W_0,W_2,W_4,W_6,W_8,W_10,W_12,RC,RD,RE,RF,RG,RH,RA,RB,14)
     1450
     1451        "subl   $1, 16*8(" WX ")\n\t"
     1452        "jne    1b\n\t"
     1453
     1454    SET_W_X(rsi)
     1455
     1456    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1457    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1458    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1459    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1460
     1461    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1462    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,10)
     1463    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,12)
     1464    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     1465
     1466    STORE_ADD_DIGEST()
     1467
     1468        "addq   $136, %%rsp\n\t"
     1469
     1470        :
     1471        : [mask]   "m" (mBYTE_FLIP_MASK),
     1472          [sha512] "r" (sha512),
     1473          [K512]   "m" (K512)
     1474        : WORK_REGS, STATE_REGS, XMM_REGS, "memory", "rsi"
     1475    );
     1476
     1477    return 0;
     1478    }
     1479
     1480static int Transform_Sha512_AVX1_Len(wc_Sha512* sha512, word32 len)
     1481{
     1482    __asm__ __volatile__ (
     1483
     1484        "movq   224(%[sha512]), %%rsi\n\t"
     1485        "leaq   %[K512], %%rdx\n\t"
     1486
     1487    INIT_MASK(MASK)
     1488    LOAD_DIGEST()
     1489
     1490        "# Start of processing a block\n"
     1491        "2:\n\t"
     1492
     1493        /* 16 Ws plus loop counter and K512. len goes into -4(%rsp).
     1494         * Debug needs more stack space. */
     1495        "subq   $256, %%rsp\n\t"
     1496
     1497    LOAD_W(MASK, rsi)
     1498
     1499        "movl   $4, 16*8(" WX ")\n\t"
     1500        /* b */
     1501        "movq   %%r9, " L4 "\n\t"
     1502        /* e */
     1503        "movq   %%r12, " L1 "\n\t"
     1504        /* b ^ c */
     1505        "xorq   %%r10, " L4 "\n\t"
     1506
     1507    SET_W_X(rdx)
     1508
     1509        "# Start of 16 rounds\n"
     1510        "1:\n\t"
     1511
     1512        "addq   $128, %%rdx\n\t"
     1513        "movq   %%rdx, 17*8(%%rsp)\n\t"
     1514
     1515    MsgSched2(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1516    MsgSched2(W_2,W_4,W_6,W_8,W_10,W_12,W_14,W_0,RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1517    MsgSched2(W_4,W_6,W_8,W_10,W_12,W_14,W_0,W_2,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1518    MsgSched2(W_6,W_8,W_10,W_12,W_14,W_0,W_2,W_4,RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1519    MsgSched2(W_8,W_10,W_12,W_14,W_0,W_2,W_4,W_6,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1520    MsgSched2(W_10,W_12,W_14,W_0,W_2,W_4,W_6,W_8,RG,RH,RA,RB,RC,RD,RE,RF,10)
     1521    MsgSched2(W_12,W_14,W_0,W_2,W_4,W_6,W_8,W_10,RE,RF,RG,RH,RA,RB,RC,RD,12)
     1522    MsgSched2(W_14,W_0,W_2,W_4,W_6,W_8,W_10,W_12,RC,RD,RE,RF,RG,RH,RA,RB,14)
     1523
     1524        "movq   17*8(%%rsp), %%rdx\n\t"
     1525
     1526    SET_W_X(rdx)
     1527
     1528        "subl   $1, 16*8(" WX ")\n\t"
     1529        "jne    1b\n\t"
     1530
     1531    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1532    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1533    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1534    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1535
     1536    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1537    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,10)
     1538    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,12)
     1539    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     1540
     1541    ADD_DIGEST()
     1542
     1543        "addq   $256, %%rsp\n\t"
     1544        "leaq   %[K512], %%rdx\n\t"
     1545        "addq   $128, %%rsi\n\t"
     1546        "subl   $128, %[len]\n\t"
     1547
     1548    STORE_DIGEST()
     1549
     1550        "jnz    2b\n\t"
     1551
     1552        :
     1553        : [mask]   "m" (mBYTE_FLIP_MASK),
     1554          [len]    "m" (len),
     1555          [sha512] "r" (sha512),
     1556          [K512]   "m" (K512)
     1557        : WORK_REGS, STATE_REGS, XMM_REGS, "memory", "rsi"
     1558    );
    10871559
    10881560    return 0;
     
    10901562#endif /* HAVE_INTEL_AVX1 */
    10911563
    1092 #if defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_AVX1) && defined(HAVE_INTEL_RORX)
    1093 static int Transform_AVX1_RORX(wc_Sha512* sha512)
     1564#if defined(HAVE_INTEL_AVX2) && defined(HAVE_INTEL_RORX)
     1565static int Transform_Sha512_AVX1_RORX(wc_Sha512* sha512)
    10941566{
    1095     const word64* K = K512;
    1096     word64 W_X[16+4] = {0};
    1097     word32 j;
    1098     word64 T[8];
    1099 
    1100     /* Copy digest to working vars */
    1101     XMEMCPY(T, sha512->digest, sizeof(T));
    1102 
    1103     W_from_buff(W_X, sha512->buffer);
    1104     for (j = 0; j < 80; j += 16) {
    1105         Rx_RORX_1( 0); Block_0_1(W_X); Rx_RORX_2( 0); Block_0_2(W_X);
    1106                                     Rx_RORX_3( 0); Block_0_3();
    1107         Rx_RORX_1( 1); Block_0_4(); Rx_RORX_2( 1); Block_0_5();
    1108                                     Rx_RORX_3( 1); Block_0_6(W_X);
    1109         Rx_RORX_1( 2); Block_0_7(W_X); Rx_RORX_2( 2); Block_0_8(W_X);
    1110                                     Rx_RORX_3( 2); Block_0_9();
    1111         Rx_RORX_1( 3); Block_0_10();Rx_RORX_2( 3); Block_0_11();
    1112                                     Rx_RORX_3( 3); Block_0_12(W_X);
    1113 
    1114         Rx_RORX_1( 4); Block_4_1(W_X); Rx_RORX_2( 4); Block_4_2(W_X);
    1115                                     Rx_RORX_3( 4); Block_4_3();
    1116         Rx_RORX_1( 5); Block_4_4(); Rx_RORX_2( 5); Block_4_5();
    1117                                     Rx_RORX_3( 5); Block_4_6(W_X);
    1118         Rx_RORX_1( 6); Block_4_7(W_X); Rx_RORX_2( 6); Block_4_8(W_X);
    1119                                     Rx_RORX_3( 6); Block_4_9();
    1120         Rx_RORX_1( 7); Block_4_10();Rx_RORX_2( 7); Block_4_11();
    1121                                     Rx_RORX_3( 7); Block_4_12(W_X);
    1122 
    1123         Rx_RORX_1( 8); Block_8_1(W_X); Rx_RORX_2( 8); Block_8_2(W_X);
    1124                                     Rx_RORX_3( 8); Block_8_3();
    1125         Rx_RORX_1( 9); Block_8_4(); Rx_RORX_2( 9); Block_8_5();
    1126                                     Rx_RORX_3( 9); Block_8_6(W_X);
    1127         Rx_RORX_1(10); Block_8_7(W_X); Rx_RORX_2(10); Block_8_8(W_X);
    1128                                     Rx_RORX_3(10); Block_8_9();
    1129         Rx_RORX_1(11); Block_8_10();Rx_RORX_2(11); Block_8_11();
    1130                                     Rx_RORX_3(11); Block_8_12(W_X);
    1131 
    1132         Rx_RORX_1(12); Block_12_1(W_X); Rx_RORX_2(12); Block_12_2(W_X);
    1133                                      Rx_RORX_3(12); Block_12_3();
    1134         Rx_RORX_1(13); Block_12_4(); Rx_RORX_2(13); Block_12_5();
    1135                                      Rx_RORX_3(13); Block_12_6(W_X);
    1136         Rx_RORX_1(14); Block_12_7(W_X); Rx_RORX_2(14); Block_12_8(W_X);
    1137                                      Rx_RORX_3(14); Block_12_9();
    1138         Rx_RORX_1(15); Block_12_10();Rx_RORX_2(15); Block_12_11();
    1139                                      Rx_RORX_3(15); Block_12_12(W_X);
    1140     }
    1141 
    1142     /* Add the working vars back into digest */
    1143     sha512->digest[0] += a(0);
    1144     sha512->digest[1] += b(0);
    1145     sha512->digest[2] += c(0);
    1146     sha512->digest[3] += d(0);
    1147     sha512->digest[4] += e(0);
    1148     sha512->digest[5] += f(0);
    1149     sha512->digest[6] += g(0);
    1150     sha512->digest[7] += h(0);
    1151 
    1152     /* Wipe variables */
    1153 #if !defined(HAVE_INTEL_AVX1)&&!defined(HAVE_INTEL_AVX2)
    1154     XMEMSET(W_X, 0, sizeof(word64) * 16);
    1155 #endif
    1156     XMEMSET(T, 0, sizeof(T));
     1567    __asm__ __volatile__ (
     1568
     1569        /* 16 Ws plus loop counter and K512. */
     1570        "subq   $144, %%rsp\n\t"
     1571        "leaq   64(%[sha512]), %%rax\n\t"
     1572
     1573    INIT_MASK(MASK)
     1574    LOAD_DIGEST()
     1575
     1576    LOAD_W(MASK, rax)
     1577
     1578        "movl   $4, 16*8(" WX ")\n\t"
     1579        "leaq   %[K512], %%rsi\n\t"
     1580        /* L4 = b */
     1581        "movq   %%r9, " L4 "\n\t"
     1582        /* L3 = 0 (add to prev h) */
     1583        "xorq   " L3 ", " L3 "\n\t"
     1584        /* L4 = b ^ c */
     1585        "xorq   %%r10, " L4 "\n\t"
     1586
     1587    SET_W_X(rsi)
     1588
     1589        "# Start of 16 rounds\n"
     1590        "1:\n\t"
     1591
     1592        "addq   $128, %%rsi\n\t"
     1593
     1594    MsgSched_RORX(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1595    MsgSched_RORX(W_2,W_4,W_6,W_8,W_10,W_12,W_14,W_0,RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1596    MsgSched_RORX(W_4,W_6,W_8,W_10,W_12,W_14,W_0,W_2,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1597    MsgSched_RORX(W_6,W_8,W_10,W_12,W_14,W_0,W_2,W_4,RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1598    MsgSched_RORX(W_8,W_10,W_12,W_14,W_0,W_2,W_4,W_6,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1599    MsgSched_RORX(W_10,W_12,W_14,W_0,W_2,W_4,W_6,W_8,RG,RH,RA,RB,RC,RD,RE,RF,10)
     1600    MsgSched_RORX(W_12,W_14,W_0,W_2,W_4,W_6,W_8,W_10,RE,RF,RG,RH,RA,RB,RC,RD,12)
     1601    MsgSched_RORX(W_14,W_0,W_2,W_4,W_6,W_8,W_10,W_12,RC,RD,RE,RF,RG,RH,RA,RB,14)
     1602
     1603    SET_W_X(rsi)
     1604
     1605        "subl   $1, 16*8(" WX ")\n\t"
     1606        "jne    1b\n\t"
     1607
     1608    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1609    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1610    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1611    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1612
     1613    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1614    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,10)
     1615    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,12)
     1616    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     1617
     1618        /* Prev RND: h += Maj(a,b,c) */
     1619        "addq   " L3 ", %%r8\n\t"
     1620        "addq   $144, %%rsp\n\t"
     1621
     1622    STORE_ADD_DIGEST()
     1623
     1624        :
     1625        : [mask]   "m" (mBYTE_FLIP_MASK),
     1626          [sha512] "r" (sha512),
     1627          [K512]   "m" (K512)
     1628        : WORK_REGS, STATE_REGS, XMM_REGS, "memory", "rsi"
     1629    );
     1630
     1631    return 0;
     1632    }
     1633
     1634static int Transform_Sha512_AVX1_RORX_Len(wc_Sha512* sha512, word32 len)
     1635{
     1636    __asm__ __volatile__ (
     1637
     1638        "movq   224(%[sha512]), %%rsi\n\t"
     1639        "leaq   %[K512], %%rcx\n\t"
     1640
     1641    INIT_MASK(MASK)
     1642    LOAD_DIGEST()
     1643
     1644        "# Start of processing a block\n"
     1645        "2:\n\t"
     1646
     1647        /* 16 Ws plus loop counter and K512. len goes into -4(%rsp).
     1648         * Debug needs more stack space. */
     1649        "subq   $256, %%rsp\n\t"
     1650
     1651    LOAD_W(MASK, rsi)
     1652
     1653        "movl   $4, 16*8(" WX ")\n\t"
     1654        /* L4 = b */
     1655        "movq   %%r9, " L4 "\n\t"
     1656        /* L3 = 0 (add to prev h) */
     1657        "xorq   " L3 ", " L3 "\n\t"
     1658        /* L4 = b ^ c */
     1659        "xorq   %%r10, " L4 "\n\t"
     1660
     1661    SET_W_X(rcx)
     1662
     1663        "# Start of 16 rounds\n"
     1664        "1:\n\t"
     1665
     1666        "addq   $128, %%rcx\n\t"
     1667        "movq   %%rcx, 17*8(%%rsp)\n\t"
     1668
     1669    MsgSched_RORX(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1670    MsgSched_RORX(W_2,W_4,W_6,W_8,W_10,W_12,W_14,W_0,RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1671    MsgSched_RORX(W_4,W_6,W_8,W_10,W_12,W_14,W_0,W_2,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1672    MsgSched_RORX(W_6,W_8,W_10,W_12,W_14,W_0,W_2,W_4,RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1673    MsgSched_RORX(W_8,W_10,W_12,W_14,W_0,W_2,W_4,W_6,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1674    MsgSched_RORX(W_10,W_12,W_14,W_0,W_2,W_4,W_6,W_8,RG,RH,RA,RB,RC,RD,RE,RF,10)
     1675    MsgSched_RORX(W_12,W_14,W_0,W_2,W_4,W_6,W_8,W_10,RE,RF,RG,RH,RA,RB,RC,RD,12)
     1676    MsgSched_RORX(W_14,W_0,W_2,W_4,W_6,W_8,W_10,W_12,RC,RD,RE,RF,RG,RH,RA,RB,14)
     1677
     1678        "movq   17*8(%%rsp), %%rcx\n\t"
     1679
     1680    SET_W_X(rcx)
     1681
     1682        "subl   $1, 16*8(" WX ")\n\t"
     1683        "jne    1b\n\t"
     1684
     1685    SET_W_X(rcx)
     1686
     1687    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     1688    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 2)
     1689    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     1690    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB, 6)
     1691
     1692    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     1693    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,10)
     1694    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,12)
     1695    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     1696
     1697        /* Prev RND: h += Maj(a,b,c) */
     1698        "addq   " L3 ", %%r8\n\t"
     1699        "addq   $256, %%rsp\n\t"
     1700
     1701    ADD_DIGEST()
     1702
     1703        "leaq   %[K512], %%rcx\n\t"
     1704        "addq   $128, %%rsi\n\t"
     1705        "subl   $128, %[len]\n\t"
     1706
     1707    STORE_DIGEST()
     1708
     1709        "jnz    2b\n\t"
     1710
     1711        :
     1712        : [mask]   "m" (mBYTE_FLIP_MASK),
     1713          [len]    "m" (len),
     1714          [sha512] "r" (sha512),
     1715          [K512]   "m" (K512)
     1716        : WORK_REGS, STATE_REGS, XMM_REGS, "memory", "rsi"
     1717    );
    11571718
    11581719    return 0;
    11591720}
    1160 #endif /* HAVE_INTEL_AVX2 && HAVE_INTEL_AVX1 && HAVE_INTEL_RORX */
     1721#endif /* HAVE_INTEL_AVX2 && HAVE_INTEL_RORX */
    11611722
    11621723#if defined(HAVE_INTEL_AVX2)
    1163 
    1164 #define s0_1y(dest, src)      AVX2_S(dest, src, 1);
    1165 #define s0_2y(dest, src)      AVX2_S(G_TEMPy, src, 8); XORy(dest, G_TEMPy, dest);
    1166 #define s0_3y(dest, src)      AVX2_R(G_TEMPy, src, 7);  XORy(dest, G_TEMPy, dest);
    1167 
    1168 #define s1_1y(dest, src)      AVX2_S(dest, src, 19);
    1169 #define s1_2y(dest, src)      AVX2_S(G_TEMPy, src, 61); XORy(dest, G_TEMPy, dest);
    1170 #define s1_3y(dest, src)      AVX2_R(G_TEMPy, src, 6); XORy(dest, G_TEMPy, dest);
    1171 
    1172 #define s0_y(dest, src)       s0_1y(dest, src); s0_2y(dest, src); s0_3y(dest, src)
    1173 #define s1_y(dest, src)       s1_1y(dest, src); s1_2y(dest, src); s1_3y(dest, src)
    1174 
    1175 
    1176 #define Block_Y_xx_1(i, w_0, w_4, w_8, w_12)\
    1177     MOVE_W_to_W_I_15(W_I_15y, w_0, w_4);\
    1178     MOVE_W_to_W_I_7 (W_I_7y,  w_8, w_12);\
    1179     MOVE_W_to_W_I_2 (W_I_2y,  w_12);\
    1180 
    1181 #define Block_Y_xx_2(i, w_0, w_4, w_8, w_12)\
    1182     s0_1y (YMM_TEMP0, W_I_15y);\
    1183 
    1184 #define Block_Y_xx_3(i, w_0, w_4, w_8, w_12)\
    1185     s0_2y (YMM_TEMP0, W_I_15y);\
    1186 
    1187 #define Block_Y_xx_4(i, w_0, w_4, w_8, w_12)\
    1188     s0_3y (YMM_TEMP0, W_I_15y);\
    1189 
    1190 #define Block_Y_xx_5(i, w_0, w_4, w_8, w_12)\
    1191     ADDy(W_I_TEMPy, w_0, YMM_TEMP0);\
    1192 
    1193 #define Block_Y_xx_6(i, w_0, w_4, w_8, w_12)\
    1194     ADDy(W_I_TEMPy, W_I_TEMPy, W_I_7y);\
    1195     s1_1y (YMM_TEMP0, W_I_2y);\
    1196 
    1197 #define Block_Y_xx_7(i, w_0, w_4, w_8, w_12)\
    1198     s1_2y (YMM_TEMP0, W_I_2y);\
    1199 
    1200 #define Block_Y_xx_8(i, w_0, w_4, w_8, w_12)\
    1201     s1_3y (YMM_TEMP0, W_I_2y);\
    1202     ADDy(w_0, W_I_TEMPy, YMM_TEMP0);\
    1203 
    1204 #define Block_Y_xx_9(i, w_0, w_4, w_8, w_12)\
    1205     FEEDBACK1_to_W_I_2(W_I_2y, w_0);\
    1206 
    1207 #define Block_Y_xx_10(i, w_0, w_4, w_8, w_12) \
    1208     s1_1y (YMM_TEMP0, W_I_2y);\
    1209 
    1210 #define Block_Y_xx_11(i, w_0, w_4, w_8, w_12) \
    1211     s1_2y (YMM_TEMP0, W_I_2y);\
    1212 
    1213 #define Block_Y_xx_12(i, w_0, w_4, w_8, w_12)\
    1214     s1_3y (YMM_TEMP0, W_I_2y);\
    1215     ADDy(w_0, W_I_TEMPy, YMM_TEMP0);\
    1216     MOVE_to_MEMy(w,0, w_4);\
    1217 
    1218 
    1219 static INLINE void Block_Y_0_1(void) { Block_Y_xx_1(0, W_0y, W_4y, W_8y, W_12y); }
    1220 static INLINE void Block_Y_0_2(void) { Block_Y_xx_2(0, W_0y, W_4y, W_8y, W_12y); }
    1221 static INLINE void Block_Y_0_3(void) { Block_Y_xx_3(0, W_0y, W_4y, W_8y, W_12y); }
    1222 static INLINE void Block_Y_0_4(void) { Block_Y_xx_4(0, W_0y, W_4y, W_8y, W_12y); }
    1223 static INLINE void Block_Y_0_5(void) { Block_Y_xx_5(0, W_0y, W_4y, W_8y, W_12y); }
    1224 static INLINE void Block_Y_0_6(void) { Block_Y_xx_6(0, W_0y, W_4y, W_8y, W_12y); }
    1225 static INLINE void Block_Y_0_7(void) { Block_Y_xx_7(0, W_0y, W_4y, W_8y, W_12y); }
    1226 static INLINE void Block_Y_0_8(void) { Block_Y_xx_8(0, W_0y, W_4y, W_8y, W_12y); }
    1227 static INLINE void Block_Y_0_9(void) { Block_Y_xx_9(0, W_0y, W_4y, W_8y, W_12y); }
    1228 static INLINE void Block_Y_0_10(void){ Block_Y_xx_10(0, W_0y, W_4y, W_8y, W_12y); }
    1229 static INLINE void Block_Y_0_11(void){ Block_Y_xx_11(0, W_0y, W_4y, W_8y, W_12y); }
    1230 static INLINE void Block_Y_0_12(word64 *w){ Block_Y_xx_12(0, W_0y, W_4y, W_8y, W_12y); }
    1231 
    1232 static INLINE void Block_Y_4_1(void) { Block_Y_xx_1(4, W_4y, W_8y, W_12y, W_0y); }
    1233 static INLINE void Block_Y_4_2(void) { Block_Y_xx_2(4, W_4y, W_8y, W_12y, W_0y); }
    1234 static INLINE void Block_Y_4_3(void) { Block_Y_xx_3(4, W_4y, W_8y, W_12y, W_0y); }
    1235 static INLINE void Block_Y_4_4(void) { Block_Y_xx_4(4, W_4y, W_8y, W_12y, W_0y); }
    1236 static INLINE void Block_Y_4_5(void) { Block_Y_xx_5(4, W_4y, W_8y, W_12y, W_0y); }
    1237 static INLINE void Block_Y_4_6(void) { Block_Y_xx_6(4, W_4y, W_8y, W_12y, W_0y); }
    1238 static INLINE void Block_Y_4_7(void) { Block_Y_xx_7(4, W_4y, W_8y, W_12y, W_0y); }
    1239 static INLINE void Block_Y_4_8(void) { Block_Y_xx_8(4, W_4y, W_8y, W_12y, W_0y); }
    1240 static INLINE void Block_Y_4_9(void) { Block_Y_xx_9(4, W_4y, W_8y, W_12y, W_0y); }
    1241 static INLINE void Block_Y_4_10(void) { Block_Y_xx_10(4, W_4y, W_8y, W_12y, W_0y); }
    1242 static INLINE void Block_Y_4_11(void) { Block_Y_xx_11(4, W_4y, W_8y, W_12y, W_0y); }
    1243 static INLINE void Block_Y_4_12(word64 *w) { Block_Y_xx_12(4, W_4y, W_8y, W_12y, W_0y); }
    1244 
    1245 static INLINE void Block_Y_8_1(void) { Block_Y_xx_1(8, W_8y, W_12y, W_0y, W_4y); }
    1246 static INLINE void Block_Y_8_2(void) { Block_Y_xx_2(8, W_8y, W_12y, W_0y, W_4y); }
    1247 static INLINE void Block_Y_8_3(void) { Block_Y_xx_3(8, W_8y, W_12y, W_0y, W_4y); }
    1248 static INLINE void Block_Y_8_4(void) { Block_Y_xx_4(8, W_8y, W_12y, W_0y, W_4y); }
    1249 static INLINE void Block_Y_8_5(void) { Block_Y_xx_5(8, W_8y, W_12y, W_0y, W_4y); }
    1250 static INLINE void Block_Y_8_6(void) { Block_Y_xx_6(8, W_8y, W_12y, W_0y, W_4y); }
    1251 static INLINE void Block_Y_8_7(void) { Block_Y_xx_7(8, W_8y, W_12y, W_0y, W_4y); }
    1252 static INLINE void Block_Y_8_8(void) { Block_Y_xx_8(8, W_8y, W_12y, W_0y, W_4y); }
    1253 static INLINE void Block_Y_8_9(void) { Block_Y_xx_9(8, W_8y, W_12y, W_0y, W_4y); }
    1254 static INLINE void Block_Y_8_10(void) { Block_Y_xx_10(8, W_8y, W_12y, W_0y, W_4y); }
    1255 static INLINE void Block_Y_8_11(void) { Block_Y_xx_11(8, W_8y, W_12y, W_0y, W_4y); }
    1256 static INLINE void Block_Y_8_12(word64 *w) { Block_Y_xx_12(8, W_8y, W_12y, W_0y, W_4y); }
    1257 
    1258 static INLINE void Block_Y_12_1(void) { Block_Y_xx_1(12, W_12y, W_0y, W_4y, W_8y); }
    1259 static INLINE void Block_Y_12_2(void) { Block_Y_xx_2(12, W_12y, W_0y, W_4y, W_8y); }
    1260 static INLINE void Block_Y_12_3(void) { Block_Y_xx_3(12, W_12y, W_0y, W_4y, W_8y); }
    1261 static INLINE void Block_Y_12_4(void) { Block_Y_xx_4(12, W_12y, W_0y, W_4y, W_8y); }
    1262 static INLINE void Block_Y_12_5(void) { Block_Y_xx_5(12, W_12y, W_0y, W_4y, W_8y); }
    1263 static INLINE void Block_Y_12_6(void) { Block_Y_xx_6(12, W_12y, W_0y, W_4y, W_8y); }
    1264 static INLINE void Block_Y_12_7(void) { Block_Y_xx_7(12, W_12y, W_0y, W_4y, W_8y); }
    1265 static INLINE void Block_Y_12_8(void) { Block_Y_xx_8(12, W_12y, W_0y, W_4y, W_8y); }
    1266 static INLINE void Block_Y_12_9(void) { Block_Y_xx_9(12, W_12y, W_0y, W_4y, W_8y); }
    1267 static INLINE void Block_Y_12_10(void) { Block_Y_xx_10(12, W_12y, W_0y, W_4y, W_8y); }
    1268 static INLINE void Block_Y_12_11(void) { Block_Y_xx_11(12, W_12y, W_0y, W_4y, W_8y); }
    1269 static INLINE void Block_Y_12_12(word64 *w) { Block_Y_xx_12(12, W_12y, W_0y, W_4y, W_8y); }
    1270 
    1271 
    1272 static int Transform_AVX2(wc_Sha512* sha512)
     1724static const unsigned long mBYTE_FLIP_MASK_Y[] =
     1725   { 0x0001020304050607, 0x08090a0b0c0d0e0f,
     1726     0x0001020304050607, 0x08090a0b0c0d0e0f };
     1727
     1728#define W_Y_0       ymm0
     1729#define W_Y_4       ymm1
     1730#define W_Y_8       ymm2
     1731#define W_Y_12      ymm3
     1732
     1733#define X0       xmm0
     1734#define X1       xmm1
     1735#define X2       xmm2
     1736#define X3       xmm3
     1737#define X4       xmm4
     1738#define X5       xmm5
     1739#define X6       xmm6
     1740#define X7       xmm7
     1741#define X8       xmm8
     1742#define X9       xmm9
     1743#define Y0       ymm0
     1744#define Y1       ymm1
     1745#define Y2       ymm2
     1746#define Y3       ymm3
     1747#define Y4       ymm4
     1748#define Y5       ymm5
     1749#define Y6       ymm6
     1750#define Y7       ymm7
     1751
     1752#define W_Y_M15     ymm12
     1753#define W_Y_M7      ymm13
     1754#define W_Y_M2      ymm14
     1755#define MASK_Y      ymm15
     1756
     1757#define YTMP1       ymm8
     1758#define YTMP2       ymm9
     1759#define YTMP3       ymm10
     1760#define YTMP4       ymm11
     1761
     1762#define YMM_REGS \
     1763    "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",       \
     1764    "xmm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15"
     1765
     1766#define _VPERM2I128(dest, src1, src2, sel)                             \
     1767    "vperm2I128 $" #sel ", %%" #src2 ", %%" #src1 ", %%" #dest "\n\t"
     1768#define VPERM2I128(dest, src1, src2, sel) \
     1769       _VPERM2I128(dest, src1, src2, sel)
     1770
     1771#define _VPERMQ(dest, src, sel)                                        \
     1772    "vpermq     $" #sel ", %%" #src ", %%" #dest "\n\t"
     1773#define VPERMQ(dest, src, sel) \
     1774       _VPERMQ(dest, src, sel)
     1775
     1776#define _VPBLENDD(dest, src1, src2, sel)                               \
     1777    "vpblendd   $" #sel ", %%" #src2 ", %%" #src1 ", %%" #dest "\n\t"
     1778#define VPBLENDD(dest, src1, src2, sel) \
     1779       _VPBLENDD(dest, src1, src2, sel)
     1780
     1781#define _V_ADD_I(dest, src1, addr, i)                                  \
     1782    "vpaddq      "#i"*8(%%" #addr "), %%" #src1 ", %%" #dest "\n\t"
     1783#define V_ADD_I(dest, src1, addr, i) \
     1784       _V_ADD_I(dest, src1, addr, i)
     1785
     1786#define _VMOVDQU_I(addr, i, src)                                       \
     1787    "vmovdqu     %%" #src ", " #i "*8(%%" #addr ")\n\t"
     1788#define VMOVDQU_I(addr, i, src) \
     1789       _VMOVDQU_I(addr, i, src)
     1790
     1791#define MsgSched4_AVX2(W_Y_0,W_Y_4,W_Y_8,W_Y_12,a,b,c,d,e,f,g,h,i) \
     1792            RND_0_1(a,b,c,d,e,f,g,h,i)                             \
     1793    /* W[-13]..W[-15], W[-12] */                                   \
     1794    VPBLENDD(W_Y_M15, W_Y_0, W_Y_4, 0x03)                          \
     1795    /* W[-5]..W[-7], W[-4] */                                      \
     1796    VPBLENDD(W_Y_M7, W_Y_8, W_Y_12, 0x03)                          \
     1797            RND_0_2(a,b,c,d,e,f,g,h,i)                             \
     1798            RND_0_3(a,b,c,d,e,f,g,h,i)                             \
     1799    /* W_Y_M15 = W[-12]..W[-15] */                                 \
     1800    VPERMQ(W_Y_M15, W_Y_M15, 0x39)                                 \
     1801            RND_0_4(a,b,c,d,e,f,g,h,i)                             \
     1802    /* W_Y_M7 = W[-4]..W[-7] */                                    \
     1803    VPERMQ(W_Y_M7, W_Y_M7, 0x39)                                   \
     1804            RND_0_5(a,b,c,d,e,f,g,h,i)                             \
     1805            RND_0_6(a,b,c,d,e,f,g,h,i)                             \
     1806    /* W[-15] >>  1 */                                             \
     1807    V_SHIFT_R(YTMP1, W_Y_M15, 1)                                   \
     1808            RND_0_7(a,b,c,d,e,f,g,h,i)                             \
     1809    /* W[-15] << 63 */                                             \
     1810    V_SHIFT_L(YTMP2, W_Y_M15, 63)                                  \
     1811            RND_0_8(a,b,c,d,e,f,g,h,i)                             \
     1812    /* W[-15] >>  8 */                                             \
     1813    V_SHIFT_R(YTMP3, W_Y_M15, 8)                                   \
     1814            RND_0_9(a,b,c,d,e,f,g,h,i)                             \
     1815    /* W[-15] << 56 */                                             \
     1816    V_SHIFT_L(YTMP4, W_Y_M15, 56)                                  \
     1817            RND_0_10(a,b,c,d,e,f,g,h,i)                            \
     1818    /* W[-15] >>> 1 */                                             \
     1819    V_OR(YTMP1, YTMP2, YTMP1)                                      \
     1820            RND_0_11(a,b,c,d,e,f,g,h,i)                            \
     1821    /* W[-15] >>> 8 */                                             \
     1822    V_OR(YTMP3, YTMP4, YTMP3)                                      \
     1823            RND_0_12(a,b,c,d,e,f,g,h,i)                            \
     1824            RND_1_1(h,a,b,c,d,e,f,g,i+1)                           \
     1825    /* W[-15] >> 7 */                                              \
     1826    V_SHIFT_R(YTMP4, W_Y_M15, 7)                                   \
     1827            RND_1_2_A(h,a,b,c,d,e,f,g,i+1)                         \
     1828    /* (W[-15] >>> 1) ^ (W[-15] >>> 8) */                          \
     1829    V_XOR(YTMP1, YTMP3, YTMP1)                                     \
     1830            RND_1_2_B(h,a,b,c,d,e,f,g,i+1)                         \
     1831    /* (W[-15] >>> 1) ^ (W[-15] >>> 8) ^ (W[-15] >> 7) */          \
     1832    V_XOR(YTMP1, YTMP4, YTMP1)                                     \
     1833            RND_1_3(h,a,b,c,d,e,f,g,i+1)                           \
     1834    /* W[0] = W[-16] + W[-7] */                                    \
     1835    V_ADD(W_Y_0, W_Y_0, W_Y_M7)                                    \
     1836            RND_1_4(h,a,b,c,d,e,f,g,i+1)                           \
     1837    /* W[0] = W[-16] + W[-7] + s0(W[-15]) */                       \
     1838    V_ADD(W_Y_0, W_Y_0, YTMP1)                                     \
     1839            RND_1_5(h,a,b,c,d,e,f,g,i+1)                           \
     1840    /* 0, 0, W[-1], W[-2] */                                       \
     1841    VPERM2I128(W_Y_M2, W_Y_12, W_Y_12, 0x81)                       \
     1842            RND_1_6(h,a,b,c,d,e,f,g,i+1)                           \
     1843            RND_1_7(h,a,b,c,d,e,f,g,i+1)                           \
     1844            RND_1_8(h,a,b,c,d,e,f,g,i+1)                           \
     1845    /* W[-2] >> 19 */                                              \
     1846    V_SHIFT_R(YTMP1, W_Y_M2, 19)                                   \
     1847            RND_1_9(h,a,b,c,d,e,f,g,i+1)                           \
     1848    /* W[-2] << 45 */                                              \
     1849    V_SHIFT_L(YTMP2, W_Y_M2, 45)                                   \
     1850            RND_1_10(h,a,b,c,d,e,f,g,i+1)                          \
     1851    /* W[-2] >> 61 */                                              \
     1852    V_SHIFT_R(YTMP3, W_Y_M2, 61)                                   \
     1853            RND_1_11(h,a,b,c,d,e,f,g,i+1)                          \
     1854    /* W[-2] <<  3 */                                              \
     1855    V_SHIFT_L(YTMP4, W_Y_M2, 3)                                    \
     1856            RND_1_12(h,a,b,c,d,e,f,g,i+1)                          \
     1857            RND_0_1(g,h,a,b,c,d,e,f,i+2)                           \
     1858    /* W[-2] >>> 19 */                                             \
     1859    V_OR(YTMP1, YTMP2, YTMP1)                                      \
     1860            RND_0_2(g,h,a,b,c,d,e,f,i+2)                           \
     1861    /* W[-2] >>> 61 */                                             \
     1862    V_OR(YTMP3, YTMP4, YTMP3)                                      \
     1863            RND_0_3(g,h,a,b,c,d,e,f,i+2)                           \
     1864    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) */                          \
     1865    V_XOR(YTMP1, YTMP3, YTMP1)                                     \
     1866            RND_0_4(g,h,a,b,c,d,e,f,i+2)                           \
     1867    /* W[-2] >>  6 */                                              \
     1868    V_SHIFT_R(YTMP4, W_Y_M2, 6)                                    \
     1869            RND_0_5(g,h,a,b,c,d,e,f,i+2)                           \
     1870    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) ^ (W[-2] >> 6) */           \
     1871    V_XOR(YTMP1, YTMP4, YTMP1)                                     \
     1872            RND_0_6(g,h,a,b,c,d,e,f,i+2)                           \
     1873    /* W[0] = W[-16] + W[-7] + s0(W[-15]) + s1(W[-2]) */           \
     1874    V_ADD(W_Y_0, W_Y_0, YTMP1)                                     \
     1875            RND_0_7(g,h,a,b,c,d,e,f,i+2)                           \
     1876            RND_0_8(g,h,a,b,c,d,e,f,i+2)                           \
     1877    /* W[1], W[0], 0, 0 */                                         \
     1878    VPERM2I128(W_Y_M2, W_Y_0, W_Y_0, 0x08)                         \
     1879            RND_0_9(g,h,a,b,c,d,e,f,i+2)                           \
     1880            RND_0_10(g,h,a,b,c,d,e,f,i+2)                          \
     1881    /* W[-2] >> 19 */                                              \
     1882    V_SHIFT_R(YTMP1, W_Y_M2, 19)                                   \
     1883            RND_0_11(g,h,a,b,c,d,e,f,i+2)                          \
     1884    /* W[-2] << 45 */                                              \
     1885    V_SHIFT_L(YTMP2, W_Y_M2, 45)                                   \
     1886            RND_0_12(g,h,a,b,c,d,e,f,i+2)                          \
     1887            RND_1_1(f,g,h,a,b,c,d,e,i+3)                           \
     1888    /* W[-2] >> 61 */                                              \
     1889    V_SHIFT_R(YTMP3, W_Y_M2, 61)                                   \
     1890            RND_1_2(f,g,h,a,b,c,d,e,i+3)                           \
     1891    /* W[-2] <<  3 */                                              \
     1892    V_SHIFT_L(YTMP4, W_Y_M2, 3)                                    \
     1893            RND_1_3(f,g,h,a,b,c,d,e,i+3)                           \
     1894    /* W[-2] >>> 19 */                                             \
     1895    V_OR(YTMP1, YTMP2, YTMP1)                                      \
     1896            RND_1_4(f,g,h,a,b,c,d,e,i+3)                           \
     1897    /* W[-2] >>> 61 */                                             \
     1898    V_OR(YTMP3, YTMP4, YTMP3)                                      \
     1899            RND_1_5(f,g,h,a,b,c,d,e,i+3)                           \
     1900    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) */                          \
     1901    V_XOR(YTMP1, YTMP3, YTMP1)                                     \
     1902            RND_1_6(f,g,h,a,b,c,d,e,i+3)                           \
     1903    /* W[-2] >>  6 */                                              \
     1904    V_SHIFT_R(YTMP4, W_Y_M2, 6)                                    \
     1905            RND_1_7(f,g,h,a,b,c,d,e,i+3)                           \
     1906    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) ^ (W[-2] >> 6) */           \
     1907    V_XOR(YTMP1, YTMP4, YTMP1)                                     \
     1908            RND_1_8(f,g,h,a,b,c,d,e,i+3)                           \
     1909    /* W[0] = W[-16] + W[-7] + s0(W[-15]) + s1(W[-2]) */           \
     1910    V_ADD(W_Y_0, W_Y_0, YTMP1)                                     \
     1911            RND_1_9(f,g,h,a,b,c,d,e,i+3)                           \
     1912            RND_1_10(f,g,h,a,b,c,d,e,i+3)                          \
     1913            RND_1_11(f,g,h,a,b,c,d,e,i+3)                          \
     1914            RND_1_12(f,g,h,a,b,c,d,e,i+3)                          \
     1915
     1916#define MsgSched2_AVX2(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,a,b,c,d,e,f,g,h,i) \
     1917            RND_0_1(a,b,c,d,e,f,g,h,i)                                       \
     1918    VPALIGNR(W_Y_M15, W_2, W_0, 8)                                           \
     1919    VPALIGNR(W_Y_M7, W_10, W_8, 8)                                           \
     1920            RND_0_2(a,b,c,d,e,f,g,h,i)                                       \
     1921    V_SHIFT_R(YTMP1, W_Y_M15, 1)                                             \
     1922    V_SHIFT_L(YTMP2, W_Y_M15, 63)                                            \
     1923            RND_0_3(a,b,c,d,e,f,g,h,i)                                       \
     1924            RND_0_4(a,b,c,d,e,f,g,h,i)                                       \
     1925    V_SHIFT_R(YTMP3, W_Y_M15, 8)                                             \
     1926    V_SHIFT_L(YTMP4, W_Y_M15, 56)                                            \
     1927            RND_0_5(a,b,c,d,e,f,g,h,i)                                       \
     1928            RND_0_6(a,b,c,d,e,f,g,h,i)                                       \
     1929    V_OR(YTMP1, YTMP2, YTMP1)                                                \
     1930    V_OR(YTMP3, YTMP4, YTMP3)                                                \
     1931            RND_0_7(a,b,c,d,e,f,g,h,i)                                       \
     1932            RND_0_8(a,b,c,d,e,f,g,h,i)                                       \
     1933    V_SHIFT_R(YTMP4, W_Y_M15, 7)                                             \
     1934    V_XOR(YTMP1, YTMP3, YTMP1)                                               \
     1935            RND_0_9(a,b,c,d,e,f,g,h,i)                                       \
     1936            RND_0_10(a,b,c,d,e,f,g,h,i)                                      \
     1937    V_XOR(YTMP1, YTMP4, YTMP1)                                               \
     1938    V_ADD(W_0, W_0, W_Y_M7)                                                  \
     1939            RND_0_11(a,b,c,d,e,f,g,h,i)                                      \
     1940            RND_0_12(a,b,c,d,e,f,g,h,i)                                      \
     1941            RND_1_1(h,a,b,c,d,e,f,g,i+1)                                     \
     1942    V_ADD(W_0, W_0, YTMP1)                                                   \
     1943            RND_1_2(h,a,b,c,d,e,f,g,i+1)                                     \
     1944    V_SHIFT_R(YTMP1, W_14, 19)                                               \
     1945    V_SHIFT_L(YTMP2, W_14, 45)                                               \
     1946            RND_1_3(h,a,b,c,d,e,f,g,i+1)                                     \
     1947            RND_1_4(h,a,b,c,d,e,f,g,i+1)                                     \
     1948    V_SHIFT_R(YTMP3, W_14, 61)                                               \
     1949    V_SHIFT_L(YTMP4, W_14, 3)                                                \
     1950            RND_1_5(h,a,b,c,d,e,f,g,i+1)                                     \
     1951            RND_1_6(h,a,b,c,d,e,f,g,i+1)                                     \
     1952            RND_1_7(h,a,b,c,d,e,f,g,i+1)                                     \
     1953    V_OR(YTMP1, YTMP2, YTMP1)                                                \
     1954    V_OR(YTMP3, YTMP4, YTMP3)                                                \
     1955            RND_1_8(h,a,b,c,d,e,f,g,i+1)                                     \
     1956            RND_1_9(h,a,b,c,d,e,f,g,i+1)                                     \
     1957    V_XOR(YTMP1, YTMP3, YTMP1)                                               \
     1958    V_SHIFT_R(YTMP4, W_14, 6)                                                \
     1959            RND_1_10(h,a,b,c,d,e,f,g,i+1)                                    \
     1960            RND_1_11(h,a,b,c,d,e,f,g,i+1)                                    \
     1961    V_XOR(YTMP1, YTMP4, YTMP1)                                               \
     1962            RND_1_12(h,a,b,c,d,e,f,g,i+1)                                    \
     1963    V_ADD(W_0, W_0, YTMP1)                                                   \
     1964
     1965#define MsgSched4_AVX2_RORX_SET(W_Y_0,W_Y_4,W_Y_8,W_Y_12,a,b,c,d,e,f,g,h,i) \
     1966            RND_RORX_0_1(a,b,c,d,e,f,g,h,i)                                 \
     1967    /* W[-13]..W[-15], W[-12] */                                            \
     1968    VPBLENDD(W_Y_M15, W_Y_0, W_Y_4, 0x03)                                   \
     1969    /* W[-5]..W[-7], W[-4] */                                               \
     1970    VPBLENDD(W_Y_M7, W_Y_8, W_Y_12, 0x03)                                   \
     1971            RND_RORX_0_2(a,b,c,d,e,f,g,h,i)                                 \
     1972    /* W_Y_M15 = W[-12]..W[-15] */                                          \
     1973    VPERMQ(W_Y_M15, W_Y_M15, 0x39)                                          \
     1974            RND_RORX_0_3(a,b,c,d,e,f,g,h,i)                                 \
     1975    /* W_Y_M7 = W[-4]..W[-7] */                                             \
     1976    VPERMQ(W_Y_M7, W_Y_M7, 0x39)                                            \
     1977            RND_RORX_0_4(a,b,c,d,e,f,g,h,i)                                 \
     1978    /* W[-15] >>  1 */                                                      \
     1979    V_SHIFT_R(YTMP1, W_Y_M15, 1)                                            \
     1980    /* W[-15] << 63 */                                                      \
     1981    V_SHIFT_L(YTMP2, W_Y_M15, 63)                                           \
     1982            RND_RORX_0_5(a,b,c,d,e,f,g,h,i)                                 \
     1983    /* W[-15] >>  8 */                                                      \
     1984    V_SHIFT_R(YTMP3, W_Y_M15, 8)                                            \
     1985    /* W[-15] << 56 */                                                      \
     1986    V_SHIFT_L(YTMP4, W_Y_M15, 56)                                           \
     1987    /* W[-15] >>> 1 */                                                      \
     1988    V_OR(YTMP1, YTMP2, YTMP1)                                               \
     1989    /* W[-15] >>> 8 */                                                      \
     1990    V_OR(YTMP3, YTMP4, YTMP3)                                               \
     1991            RND_RORX_0_6(a,b,c,d,e,f,g,h,i)                                 \
     1992    /* W[-15] >> 7 */                                                       \
     1993    V_SHIFT_R(YTMP4, W_Y_M15, 7)                                            \
     1994            RND_RORX_0_7(a,b,c,d,e,f,g,h,i)                                 \
     1995    /* 0, 0, W[-1], W[-2] */                                                \
     1996    VPERM2I128(W_Y_M2, W_Y_12, W_Y_12, 0x81)                                \
     1997            RND_RORX_0_8(a,b,c,d,e,f,g,h,i)                                 \
     1998            RND_RORX_1_1(h,a,b,c,d,e,f,g,i+1)                               \
     1999    /* (W[-15] >>> 1) ^ (W[-15] >>> 8) */                                   \
     2000    V_XOR(YTMP1, YTMP3, YTMP1)                                              \
     2001            RND_RORX_1_2(h,a,b,c,d,e,f,g,i+1)                               \
     2002    /* (W[-15] >>> 1) ^ (W[-15] >>> 8) ^ (W[-15] >> 7) */                   \
     2003    V_XOR(YTMP1, YTMP4, YTMP1)                                              \
     2004            RND_RORX_1_3(h,a,b,c,d,e,f,g,i+1)                               \
     2005    /* W[0] = W[-16] + W[-7] */                                             \
     2006    V_ADD(W_Y_0, W_Y_0, W_Y_M7)                                             \
     2007    /* W[0] = W[-16] + W[-7] + s0(W[-15]) */                                \
     2008    V_ADD(W_Y_0, W_Y_0, YTMP1)                                              \
     2009            RND_RORX_1_4(h,a,b,c,d,e,f,g,i+1)                               \
     2010    /* W[-2] >> 19 */                                                       \
     2011    V_SHIFT_R(YTMP1, W_Y_M2, 19)                                            \
     2012    /* W[-2] << 45 */                                                       \
     2013    V_SHIFT_L(YTMP2, W_Y_M2, 45)                                            \
     2014            RND_RORX_1_5(h,a,b,c,d,e,f,g,i+1)                               \
     2015    /* W[-2] >> 61 */                                                       \
     2016    V_SHIFT_R(YTMP3, W_Y_M2, 61)                                            \
     2017    /* W[-2] <<  3 */                                                       \
     2018    V_SHIFT_L(YTMP4, W_Y_M2, 3)                                             \
     2019    /* W[-2] >>> 19 */                                                      \
     2020    V_OR(YTMP1, YTMP2, YTMP1)                                               \
     2021            RND_RORX_1_6(h,a,b,c,d,e,f,g,i+1)                               \
     2022    /* W[-2] >>> 61 */                                                      \
     2023    V_OR(YTMP3, YTMP4, YTMP3)                                               \
     2024            RND_RORX_1_7(h,a,b,c,d,e,f,g,i+1)                               \
     2025    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) */                                   \
     2026    V_XOR(YTMP1, YTMP3, YTMP1)                                              \
     2027            RND_RORX_1_8(h,a,b,c,d,e,f,g,i+1)                               \
     2028    /* W[-2] >>  6 */                                                       \
     2029    V_SHIFT_R(YTMP4, W_Y_M2, 6)                                             \
     2030            RND_RORX_0_1(g,h,a,b,c,d,e,f,i+2)                               \
     2031    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) ^ (W[-2] >> 6) */                    \
     2032    V_XOR(YTMP1, YTMP4, YTMP1)                                              \
     2033            RND_RORX_0_2(g,h,a,b,c,d,e,f,i+2)                               \
     2034    /* W[0] = W[-16] + W[-7] + s0(W[-15]) + s1(W[-2]) */                    \
     2035    V_ADD(W_Y_0, W_Y_0, YTMP1)                                              \
     2036            RND_RORX_0_3(g,h,a,b,c,d,e,f,i+2)                               \
     2037    /* W[1], W[0], 0, 0 */                                                  \
     2038    VPERM2I128(W_Y_M2, W_Y_0, W_Y_0, 0x08)                                  \
     2039            RND_RORX_0_4(g,h,a,b,c,d,e,f,i+2)                               \
     2040            RND_RORX_0_5(g,h,a,b,c,d,e,f,i+2)                               \
     2041    /* W[-2] >> 19 */                                                       \
     2042    V_SHIFT_R(YTMP1, W_Y_M2, 19)                                            \
     2043    /* W[-2] << 45 */                                                       \
     2044    V_SHIFT_L(YTMP2, W_Y_M2, 45)                                            \
     2045            RND_RORX_0_6(g,h,a,b,c,d,e,f,i+2)                               \
     2046    /* W[-2] >> 61 */                                                       \
     2047    V_SHIFT_R(YTMP3, W_Y_M2, 61)                                            \
     2048    /* W[-2] <<  3 */                                                       \
     2049    V_SHIFT_L(YTMP4, W_Y_M2, 3)                                             \
     2050    /* W[-2] >>> 19 */                                                      \
     2051    V_OR(YTMP1, YTMP2, YTMP1)                                               \
     2052            RND_RORX_0_7(g,h,a,b,c,d,e,f,i+2)                               \
     2053    /* W[-2] >>> 61 */                                                      \
     2054    V_OR(YTMP3, YTMP4, YTMP3)                                               \
     2055            RND_RORX_0_8(g,h,a,b,c,d,e,f,i+2)                               \
     2056    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) */                                   \
     2057    V_XOR(YTMP1, YTMP3, YTMP1)                                              \
     2058            RND_RORX_1_1(f,g,h,a,b,c,d,e,i+3)                               \
     2059    /* W[-2] >>  6 */                                                       \
     2060    V_SHIFT_R(YTMP4, W_Y_M2, 6)                                             \
     2061            RND_RORX_1_2(f,g,h,a,b,c,d,e,i+3)                               \
     2062            RND_RORX_1_3(f,g,h,a,b,c,d,e,i+3)                               \
     2063    /* (W[-2] >>> 19) ^ (W[-2] >>> 61) ^ (W[-2] >> 6) */                    \
     2064    V_XOR(YTMP1, YTMP4, YTMP1)                                              \
     2065            RND_RORX_1_4(f,g,h,a,b,c,d,e,i+3)                               \
     2066            RND_RORX_1_5(f,g,h,a,b,c,d,e,i+3)                               \
     2067    /* W[0] = W[-16] + W[-7] + s0(W[-15]) + s1(W[-2]) */                    \
     2068    V_ADD(W_Y_0, W_Y_0, YTMP1)                                              \
     2069            RND_RORX_1_6(f,g,h,a,b,c,d,e,i+3)                               \
     2070    V_ADD_I(YTMP1, W_Y_0, rsi, i)                                           \
     2071            RND_RORX_1_7(f,g,h,a,b,c,d,e,i+3)                               \
     2072            RND_RORX_1_8(f,g,h,a,b,c,d,e,i+3)                               \
     2073    VMOVDQU_I(rsp, i, YTMP1)                                                \
     2074
     2075#define MsgSched2_AVX2_RORX(W_0,W_2,W_4,W_6,W_8,W_10,W_12,W_14,a,b,c,d,e,  \
     2076                            f,g,h,i)                                       \
     2077            RND_RORX_0_1(a,b,c,d,e,f,g,h,i)                                \
     2078    VPALIGNR(W_Y_M15, W_2, W_0, 8)                                         \
     2079    VPALIGNR(W_Y_M7, W_10, W_8, 8)                                         \
     2080            RND_RORX_0_2(a,b,c,d,e,f,g,h,i)                                \
     2081    V_SHIFT_R(YTMP1, W_Y_M15, 1)                                           \
     2082    V_SHIFT_L(YTMP2, W_Y_M15, 63)                                          \
     2083            RND_RORX_0_3(a,b,c,d,e,f,g,h,i)                                \
     2084    V_SHIFT_R(YTMP3, W_Y_M15, 8)                                           \
     2085    V_SHIFT_L(YTMP4, W_Y_M15, 56)                                          \
     2086            RND_RORX_0_4(a,b,c,d,e,f,g,h,i)                                \
     2087    V_OR(YTMP1, YTMP2, YTMP1)                                              \
     2088    V_OR(YTMP3, YTMP4, YTMP3)                                              \
     2089            RND_RORX_0_5(a,b,c,d,e,f,g,h,i)                                \
     2090    V_SHIFT_R(YTMP4, W_Y_M15, 7)                                           \
     2091    V_XOR(YTMP1, YTMP3, YTMP1)                                             \
     2092            RND_RORX_0_6(a,b,c,d,e,f,g,h,i)                                \
     2093    V_XOR(YTMP1, YTMP4, YTMP1)                                             \
     2094    V_ADD(W_0, W_0, W_Y_M7)                                                \
     2095            RND_RORX_0_7(a,b,c,d,e,f,g,h,i)                                \
     2096            RND_RORX_0_8(a,b,c,d,e,f,g,h,i)                                \
     2097    V_ADD(W_0, W_0, YTMP1)                                                 \
     2098            RND_RORX_1_1(h,a,b,c,d,e,f,g,i+1)                              \
     2099    V_SHIFT_R(YTMP1, W_14, 19)                                             \
     2100    V_SHIFT_L(YTMP2, W_14, 45)                                             \
     2101            RND_RORX_1_2(h,a,b,c,d,e,f,g,i+1)                              \
     2102    V_SHIFT_R(YTMP3, W_14, 61)                                             \
     2103    V_SHIFT_L(YTMP4, W_14, 3)                                              \
     2104            RND_RORX_1_3(h,a,b,c,d,e,f,g,i+1)                              \
     2105    V_OR(YTMP1, YTMP2, YTMP1)                                              \
     2106    V_OR(YTMP3, YTMP4, YTMP3)                                              \
     2107            RND_RORX_1_4(h,a,b,c,d,e,f,g,i+1)                              \
     2108            RND_RORX_1_5(h,a,b,c,d,e,f,g,i+1)                              \
     2109    V_XOR(YTMP1, YTMP3, YTMP1)                                             \
     2110    V_SHIFT_R(YTMP4, W_14, 6)                                              \
     2111            RND_RORX_1_6(h,a,b,c,d,e,f,g,i+1)                              \
     2112            RND_RORX_1_7(h,a,b,c,d,e,f,g,i+1)                              \
     2113    V_XOR(YTMP1, YTMP4, YTMP1)                                             \
     2114            RND_RORX_1_8(h,a,b,c,d,e,f,g,i+1)                              \
     2115    V_ADD(W_0, W_0, YTMP1)                                                 \
     2116
     2117
     2118#define _INIT_MASK_Y(mask)            \
     2119    "vmovdqu %[mask], %%"#mask"\n\t"
     2120#define INIT_MASK_Y(mask) \
     2121       _INIT_MASK_Y(mask)
     2122
     2123/* Load into YMM registers and swap endian. */
     2124#define _LOAD_BLOCK_W_Y_2(mask, ymm0, ymm1, reg, i)           \
     2125    /* buffer[0..15] => ymm0..ymm3;  */                       \
     2126    "vmovdqu    " #i "+ 0(%%" #reg "), %%" #ymm0 "\n\t"       \
     2127    "vmovdqu    " #i "+32(%%" #reg "), %%" #ymm1 "\n\t"       \
     2128    "vpshufb    %%" #mask ", %%" #ymm0 ", %%" #ymm0 "\n\t"    \
     2129    "vpshufb    %%" #mask ", %%" #ymm1 ", %%" #ymm1 "\n\t"
     2130
     2131#define LOAD_BLOCK_W_Y_2(mask, ymm1, ymm2, reg, i) \
     2132       _LOAD_BLOCK_W_Y_2(mask, ymm1, ymm2, reg, i)
     2133
     2134#define LOAD_BLOCK_W_Y(mask, reg)                  \
     2135    LOAD_BLOCK_W_Y_2(mask, W_Y_0, W_Y_4 , reg,  0) \
     2136    LOAD_BLOCK_W_Y_2(mask, W_Y_8, W_Y_12, reg, 64)
     2137
     2138#define _SET_W_Y_2(ymm0, ymm1, ymm2, ymm3, reg, i)                    \
     2139    "vpaddq     " #i "+ 0(%%" #reg "), %%" #ymm0 ", %%" #ymm2 "\n\t"  \
     2140    "vpaddq     " #i "+32(%%" #reg "), %%" #ymm1 ", %%" #ymm3 "\n\t"  \
     2141    "vmovdqu    %%" #ymm2 ", " #i "+ 0(" WX ")\n\t"                   \
     2142    "vmovdqu    %%" #ymm3 ", " #i "+32(" WX ")\n\t"
     2143
     2144#define SET_W_Y_2(ymm0, ymm1, ymm2, ymm3, reg, i) \
     2145       _SET_W_Y_2(ymm0, ymm1, ymm2, ymm3, reg, i)
     2146
     2147#define SET_BLOCK_W_Y(reg)                          \
     2148    SET_W_Y_2(W_Y_0, W_Y_4 , YTMP1, YTMP2, reg,  0) \
     2149    SET_W_Y_2(W_Y_8, W_Y_12, YTMP1, YTMP2, reg, 64)
     2150
     2151/* Load into YMM registers and swap endian. */
     2152#define _LOAD_BLOCK2_W_Y_2(mask, Y0, Y1, X0, X1, X8, X9, reg, i)   \
     2153    "vmovdqu    " #i "+  0(%%" #reg "), %%" #X0 "\n\t"                   \
     2154    "vmovdqu    " #i "+ 16(%%" #reg "), %%" #X1 "\n\t"                   \
     2155    "vmovdqu    " #i "+128(%%" #reg "), %%" #X8 "\n\t"                   \
     2156    "vmovdqu    " #i "+144(%%" #reg "), %%" #X9 "\n\t"                   \
     2157    "vinserti128        $1, %%" #X8 ", %%" #Y0 ", %%" #Y0 "\n\t"         \
     2158    "vinserti128        $1, %%" #X9 ", %%" #Y1 ", %%" #Y1 "\n\t"         \
     2159    "vpshufb    %%" #mask ", %%" #Y0 ", %%" #Y0 "\n\t"                   \
     2160    "vpshufb    %%" #mask ", %%" #Y1 ", %%" #Y1 "\n\t"
     2161
     2162#define LOAD_BLOCK2_W_Y_2(mask, Y0, Y1, X0, X1, X8, X9, reg, i) \
     2163       _LOAD_BLOCK2_W_Y_2(mask, Y0, Y1, X0, X1, X8, X9, reg, i)
     2164
     2165#define LOAD_BLOCK2_W_Y(mask, reg)                           \
     2166    LOAD_BLOCK2_W_Y_2(mask, Y0, Y1, X0, X1, X8, X9, reg,  0) \
     2167    LOAD_BLOCK2_W_Y_2(mask, Y2, Y3, X2, X3, X8, X9, reg, 32) \
     2168    LOAD_BLOCK2_W_Y_2(mask, Y4, Y5, X4, X5, X8, X9, reg, 64) \
     2169    LOAD_BLOCK2_W_Y_2(mask, Y6, Y7, X6, X7, X8, X9, reg, 96) \
     2170
     2171#define SET_BLOCK2_W_Y(reg)                   \
     2172    SET_W_Y_2(Y0, Y1, YTMP1, YTMP2, reg,   0) \
     2173    SET_W_Y_2(Y2, Y3, YTMP1, YTMP2, reg,  64) \
     2174    SET_W_Y_2(Y4, Y5, YTMP1, YTMP2, reg, 128) \
     2175    SET_W_Y_2(Y6, Y7, YTMP1, YTMP2, reg, 192)
     2176
     2177static const word64 K512_AVX2[160] = {
     2178    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
     2179    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
     2180    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
     2181    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
     2182    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
     2183    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
     2184    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
     2185    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
     2186    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
     2187    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
     2188    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
     2189    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
     2190    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
     2191    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
     2192    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
     2193    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
     2194    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
     2195    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
     2196    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
     2197    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
     2198    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
     2199    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
     2200    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
     2201    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
     2202    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
     2203    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
     2204    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
     2205    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
     2206    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
     2207    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
     2208    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
     2209    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
     2210    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
     2211    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
     2212    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
     2213    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
     2214    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
     2215    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
     2216    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
     2217    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
     2218    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
     2219    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
     2220    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
     2221    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
     2222    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
     2223    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
     2224    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
     2225    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
     2226    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
     2227    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
     2228    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
     2229    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
     2230    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
     2231    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
     2232    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
     2233    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
     2234    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
     2235    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
     2236    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
     2237    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
     2238    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
     2239    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
     2240    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
     2241    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
     2242    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
     2243    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
     2244    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
     2245    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
     2246    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
     2247    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
     2248    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
     2249    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
     2250    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
     2251    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
     2252    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
     2253    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
     2254    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
     2255    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
     2256    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817),
     2257    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
     2258};
     2259static const word64* K512_AVX2_END = &K512_AVX2[128];
     2260
     2261static int Transform_Sha512_AVX2(wc_Sha512* sha512)
    12732262{
    1274     const word64* K = K512;
    1275     word64 w[4];
    1276     word32 j;
    1277     word64 T[8];
    1278 
    1279     /* Copy digest to working vars */
    1280     XMEMCPY(T, sha512->digest, sizeof(T));
    1281 
    1282     W_from_buff_Y(sha512->buffer);
    1283     MOVE_to_MEMy(w,0, W_0y);
    1284     for (j = 0; j < 80; j += 16) {
    1285         Ry_1( 0, w[0]); Block_Y_0_1(); Ry_2( 0, w[0]); Block_Y_0_2();
    1286                                        Ry_3( 0, w[0]); Block_Y_0_3();
    1287         Ry_1( 1, w[1]); Block_Y_0_4(); Ry_2( 1, w[1]); Block_Y_0_5();
    1288                                        Ry_3( 1, w[1]); Block_Y_0_6();
    1289         Ry_1( 2, w[2]); Block_Y_0_7(); Ry_2( 2, w[2]); Block_Y_0_8();
    1290                                        Ry_3( 2, w[2]); Block_Y_0_9();
    1291         Ry_1( 3, w[3]); Block_Y_0_10();Ry_2( 3, w[3]); Block_Y_0_11();
    1292                                        Ry_3( 3, w[3]); Block_Y_0_12(w);
    1293 
    1294         Ry_1( 4, w[0]); Block_Y_4_1(); Ry_2( 4, w[0]); Block_Y_4_2();
    1295                                        Ry_3( 4, w[0]); Block_Y_4_3();
    1296         Ry_1( 5, w[1]); Block_Y_4_4(); Ry_2( 5, w[1]); Block_Y_4_5();
    1297                                        Ry_3( 5, w[1]); Block_Y_4_6();
    1298         Ry_1( 6, w[2]); Block_Y_4_7(); Ry_2( 6, w[2]); Block_Y_4_8();
    1299                                        Ry_3( 6, w[2]); Block_Y_4_9();
    1300         Ry_1( 7, w[3]); Block_Y_4_10(); Ry_2( 7, w[3]);Block_Y_4_11();
    1301                                         Ry_3( 7, w[3]);Block_Y_4_12(w);
    1302 
    1303         Ry_1( 8, w[0]); Block_Y_8_1(); Ry_2( 8, w[0]); Block_Y_8_2();
    1304                                        Ry_3( 8, w[0]); Block_Y_8_3();
    1305         Ry_1( 9, w[1]); Block_Y_8_4(); Ry_2( 9, w[1]); Block_Y_8_5();
    1306                                        Ry_3( 9, w[1]); Block_Y_8_6();
    1307         Ry_1(10, w[2]); Block_Y_8_7(); Ry_2(10, w[2]); Block_Y_8_8();
    1308                                        Ry_3(10, w[2]); Block_Y_8_9();
    1309         Ry_1(11, w[3]); Block_Y_8_10();Ry_2(11, w[3]); Block_Y_8_11();
    1310                                        Ry_3(11, w[3]); Block_Y_8_12(w);
    1311 
    1312         Ry_1(12, w[0]); Block_Y_12_1(); Ry_2(12, w[0]); Block_Y_12_2();
    1313                                         Ry_3(12, w[0]); Block_Y_12_3();
    1314         Ry_1(13, w[1]); Block_Y_12_4(); Ry_2(13, w[1]); Block_Y_12_5();
    1315                                         Ry_3(13, w[1]); Block_Y_12_6();
    1316         Ry_1(14, w[2]); Block_Y_12_7(); Ry_2(14, w[2]); Block_Y_12_8();
    1317                                         Ry_3(14, w[2]); Block_Y_12_9();
    1318         Ry_1(15, w[3]); Block_Y_12_10();Ry_2(15, w[3]); Block_Y_12_11();
    1319                                         Ry_3(15, w[3]);Block_Y_12_12(w);
    1320     }
    1321 
    1322     /* Add the working vars back into digest */
    1323     sha512->digest[0] += a(0);
    1324     sha512->digest[1] += b(0);
    1325     sha512->digest[2] += c(0);
    1326     sha512->digest[3] += d(0);
    1327     sha512->digest[4] += e(0);
    1328     sha512->digest[5] += f(0);
    1329     sha512->digest[6] += g(0);
    1330     sha512->digest[7] += h(0);
    1331 
    1332     /* Wipe variables */
    1333 #if !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
    1334     XMEMSET(W, 0, sizeof(word64) * 16);
    1335 #endif
    1336     XMEMSET(T, 0, sizeof(T));
     2263    __asm__ __volatile__ (
     2264
     2265        /* 16 Ws plus loop counter and K512. */
     2266        "subq   $136, %%rsp\n\t"
     2267        "leaq   64(%[sha512]), %%rax\n\t"
     2268
     2269    INIT_MASK(MASK_Y)
     2270    LOAD_DIGEST()
     2271
     2272    LOAD_BLOCK_W_Y(MASK_Y, rax)
     2273
     2274        "movl   $4, 16*8(" WX ")\n\t"
     2275        "leaq   %[K512], %%rsi\n\t"
     2276        /* b */
     2277        "movq   %%r9, " L4 "\n\t"
     2278        /* e */
     2279        "movq   %%r12, " L1 "\n\t"
     2280        /* b ^ c */
     2281        "xorq   %%r10, " L4 "\n\t"
     2282
     2283    SET_BLOCK_W_Y(rsi)
     2284
     2285        "# Start of 16 rounds\n"
     2286        "1:\n\t"
     2287
     2288        "addq   $128, %%rsi\n\t"
     2289
     2290    MsgSched4_AVX2(W_Y_0,W_Y_4,W_Y_8,W_Y_12,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2291    MsgSched4_AVX2(W_Y_4,W_Y_8,W_Y_12,W_Y_0,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     2292    MsgSched4_AVX2(W_Y_8,W_Y_12,W_Y_0,W_Y_4,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     2293    MsgSched4_AVX2(W_Y_12,W_Y_0,W_Y_4,W_Y_8,RE,RF,RG,RH,RA,RB,RC,RD,12)
     2294
     2295    SET_BLOCK_W_Y(rsi)
     2296
     2297        "subl   $1, 16*8(" WX ")\n\t"
     2298        "jne    1b\n\t"
     2299
     2300    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2301    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 2)
     2302    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     2303    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB, 6)
     2304
     2305    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     2306    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,10)
     2307    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,12)
     2308    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     2309
     2310    STORE_ADD_DIGEST()
     2311
     2312        "addq   $136, %%rsp\n\t"
     2313
     2314        :
     2315        : [mask]   "m" (mBYTE_FLIP_MASK_Y),
     2316          [sha512] "r" (sha512),
     2317          [K512]   "m" (K512)
     2318        : WORK_REGS, STATE_REGS, YMM_REGS, "memory", "rsi"
     2319    );
     2320
     2321    return 0;
     2322    }
     2323
     2324static int Transform_Sha512_AVX2_Len(wc_Sha512* sha512, word32 len)
     2325{
     2326    if ((len & WC_SHA512_BLOCK_SIZE) != 0) {
     2327        XMEMCPY(sha512->buffer, sha512->data, WC_SHA512_BLOCK_SIZE);
     2328        Transform_Sha512_AVX2(sha512);
     2329        sha512->data += WC_SHA512_BLOCK_SIZE;
     2330        len -= WC_SHA512_BLOCK_SIZE;
     2331        if (len == 0)
     2332            return 0;
     2333    }
     2334
     2335    __asm__ __volatile__ (
     2336
     2337        "movq   224(%[sha512]), %%rcx\n\t"
     2338
     2339    INIT_MASK(MASK_Y)
     2340    LOAD_DIGEST()
     2341
     2342        "# Start of processing two blocks\n"
     2343        "2:\n\t"
     2344
     2345        "subq   $1344, %%rsp\n\t"
     2346        "leaq   %[K512], %%rsi\n\t"
     2347
     2348        /* L4 = b */
     2349        "movq   %%r9, " L4 "\n\t"
     2350        /* e */
     2351        "movq   %%r12, " L1 "\n\t"
     2352
     2353    LOAD_BLOCK2_W_Y(MASK_Y, rcx)
     2354
     2355        /* L4 = b ^ c */
     2356        "xorq   %%r10, " L4 "\n\t"
     2357        "\n"
     2358        "1:\n\t"
     2359    SET_BLOCK2_W_Y(rsi)
     2360    MsgSched2_AVX2(Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2361    MsgSched2_AVX2(Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y0,RG,RH,RA,RB,RC,RD,RE,RF, 4)
     2362    MsgSched2_AVX2(Y2,Y3,Y4,Y5,Y6,Y7,Y0,Y1,RE,RF,RG,RH,RA,RB,RC,RD, 8)
     2363    MsgSched2_AVX2(Y3,Y4,Y5,Y6,Y7,Y0,Y1,Y2,RC,RD,RE,RF,RG,RH,RA,RB,12)
     2364    MsgSched2_AVX2(Y4,Y5,Y6,Y7,Y0,Y1,Y2,Y3,RA,RB,RC,RD,RE,RF,RG,RH,16)
     2365    MsgSched2_AVX2(Y5,Y6,Y7,Y0,Y1,Y2,Y3,Y4,RG,RH,RA,RB,RC,RD,RE,RF,20)
     2366    MsgSched2_AVX2(Y6,Y7,Y0,Y1,Y2,Y3,Y4,Y5,RE,RF,RG,RH,RA,RB,RC,RD,24)
     2367    MsgSched2_AVX2(Y7,Y0,Y1,Y2,Y3,Y4,Y5,Y6,RC,RD,RE,RF,RG,RH,RA,RB,28)
     2368        "addq   $256, %%rsi\n\t"
     2369        "addq   $256, %%rsp\n\t"
     2370        "cmpq   %[K512_END], %%rsi\n\t"
     2371        "jne    1b\n\t"
     2372
     2373    SET_BLOCK2_W_Y(rsi)
     2374    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2375    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 4)
     2376    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 8)
     2377    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,12)
     2378
     2379    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH,16)
     2380    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,20)
     2381    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,24)
     2382    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,28)
     2383        "subq   $1024, %%rsp\n\t"
     2384
     2385    ADD_DIGEST()
     2386    STORE_DIGEST()
     2387
     2388        /* L4 = b */
     2389        "movq   %%r9, " L4 "\n\t"
     2390        /* e */
     2391        "movq   %%r12, " L1 "\n\t"
     2392        /* L4 = b ^ c */
     2393        "xorq   %%r10, " L4 "\n\t"
     2394
     2395        "movq   $5, %%rsi\n\t"
     2396        "\n"
     2397        "3:\n\t"
     2398    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 2)
     2399    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 6)
     2400    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,10)
     2401    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     2402
     2403    RND_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH,18)
     2404    RND_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,22)
     2405    RND_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,26)
     2406    RND_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,30)
     2407        "addq   $256, %%rsp\n\t"
     2408        "subq   $1, %%rsi\n\t"
     2409        "jnz    3b\n\t"
     2410
     2411    ADD_DIGEST()
     2412
     2413        "movq   224(%[sha512]), %%rcx\n\t"
     2414        "addq   $64, %%rsp\n\t"
     2415        "addq   $256, %%rcx\n\t"
     2416        "subl   $256, %[len]\n\t"
     2417        "movq   %%rcx, 224(%[sha512])\n\t"
     2418
     2419    STORE_DIGEST()
     2420
     2421        "jnz    2b\n\t"
     2422
     2423        :
     2424        : [mask]   "m" (mBYTE_FLIP_MASK_Y),
     2425          [len]    "m" (len),
     2426          [sha512] "r" (sha512),
     2427          [K512]   "m" (K512_AVX2),
     2428          [K512_END]   "m" (K512_AVX2_END)
     2429        : WORK_REGS, STATE_REGS, YMM_REGS, "memory", "rsi"
     2430    );
    13372431
    13382432    return 0;
    13392433}
     2434
     2435#ifdef HAVE_INTEL_RORX
     2436static int Transform_Sha512_AVX2_RORX(wc_Sha512* sha512)
     2437{
     2438    __asm__ __volatile__ (
     2439
     2440        /* 16 Ws plus loop counter. */
     2441        "subq   $136, %%rsp\n\t"
     2442        "leaq   64(%[sha512]), " L2 "\n\t"
     2443
     2444    INIT_MASK(MASK_Y)
     2445    LOAD_DIGEST()
     2446
     2447    LOAD_BLOCK_W_Y(MASK_Y, rcx)
     2448
     2449        "movl   $4, 16*8(" WX ")\n\t"
     2450        "leaq   %[K512], %%rsi\n\t"
     2451        /* b */
     2452        "movq   %%r9, " L4 "\n\t"
     2453        /* L3 = 0 (add to prev h) */
     2454        "xorq   " L3 ", " L3 "\n\t"
     2455        /* b ^ c */
     2456        "xorq   %%r10, " L4 "\n\t"
     2457
     2458    SET_BLOCK_W_Y(rsi)
     2459
     2460        "# Start of 16 rounds\n"
     2461        "1:\n\t"
     2462
     2463        "addq   $128, %%rsi\n\t"
     2464
     2465    MsgSched4_AVX2_RORX_SET(W_Y_0,W_Y_4,W_Y_8,W_Y_12,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2466    MsgSched4_AVX2_RORX_SET(W_Y_4,W_Y_8,W_Y_12,W_Y_0,RE,RF,RG,RH,RA,RB,RC,RD, 4)
     2467    MsgSched4_AVX2_RORX_SET(W_Y_8,W_Y_12,W_Y_0,W_Y_4,RA,RB,RC,RD,RE,RF,RG,RH, 8)
     2468    MsgSched4_AVX2_RORX_SET(W_Y_12,W_Y_0,W_Y_4,W_Y_8,RE,RF,RG,RH,RA,RB,RC,RD,12)
     2469
     2470        "subl   $1, 16*8(%%rsp)\n\t"
     2471        "jnz    1b\n\t"
     2472
     2473    RND_RORX_ALL_4(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2474    RND_RORX_ALL_4(RE,RF,RG,RH,RA,RB,RC,RD, 4)
     2475    RND_RORX_ALL_4(RA,RB,RC,RD,RE,RF,RG,RH, 8)
     2476    RND_RORX_ALL_4(RE,RF,RG,RH,RA,RB,RC,RD,12)
     2477        /* Prev RND: h += Maj(a,b,c) */
     2478        "addq   " L3 ", %%r8\n\t"
     2479        "addq   $136, %%rsp\n\t"
     2480
     2481    STORE_ADD_DIGEST()
     2482
     2483        :
     2484        : [mask]   "m" (mBYTE_FLIP_MASK_Y),
     2485          [sha512] "r" (sha512),
     2486          [K512]   "m" (K512)
     2487        : WORK_REGS, STATE_REGS, YMM_REGS, "memory", "rsi"
     2488    );
     2489
     2490    return 0;
     2491}
     2492
     2493static int Transform_Sha512_AVX2_RORX_Len(wc_Sha512* sha512, word32 len)
     2494{
     2495    if ((len & WC_SHA512_BLOCK_SIZE) != 0) {
     2496        XMEMCPY(sha512->buffer, sha512->data, WC_SHA512_BLOCK_SIZE);
     2497        Transform_Sha512_AVX2_RORX(sha512);
     2498        sha512->data += WC_SHA512_BLOCK_SIZE;
     2499        len -= WC_SHA512_BLOCK_SIZE;
     2500        if (len == 0)
     2501            return 0;
     2502    }
     2503
     2504    __asm__ __volatile__ (
     2505
     2506        "movq   224(%[sha512]), %%rax\n\t"
     2507
     2508    INIT_MASK(MASK_Y)
     2509    LOAD_DIGEST()
     2510
     2511        "# Start of processing two blocks\n"
     2512        "2:\n\t"
     2513
     2514        "subq   $1344, %%rsp\n\t"
     2515        "leaq   %[K512], %%rsi\n\t"
     2516
     2517        /* L4 = b */
     2518        "movq   %%r9, " L4 "\n\t"
     2519        /* L3 = 0 (add to prev h) */
     2520        "xorq   " L3 ", " L3 "\n\t"
     2521
     2522    LOAD_BLOCK2_W_Y(MASK_Y, rax)
     2523
     2524        /* L4 = b ^ c */
     2525        "xorq   %%r10, " L4 "\n\t"
     2526        "\n"
     2527        "1:\n\t"
     2528    SET_BLOCK2_W_Y(rsi)
     2529    MsgSched2_AVX2_RORX(Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2530    MsgSched2_AVX2_RORX(Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y0,RG,RH,RA,RB,RC,RD,RE,RF, 4)
     2531    MsgSched2_AVX2_RORX(Y2,Y3,Y4,Y5,Y6,Y7,Y0,Y1,RE,RF,RG,RH,RA,RB,RC,RD, 8)
     2532    MsgSched2_AVX2_RORX(Y3,Y4,Y5,Y6,Y7,Y0,Y1,Y2,RC,RD,RE,RF,RG,RH,RA,RB,12)
     2533    MsgSched2_AVX2_RORX(Y4,Y5,Y6,Y7,Y0,Y1,Y2,Y3,RA,RB,RC,RD,RE,RF,RG,RH,16)
     2534    MsgSched2_AVX2_RORX(Y5,Y6,Y7,Y0,Y1,Y2,Y3,Y4,RG,RH,RA,RB,RC,RD,RE,RF,20)
     2535    MsgSched2_AVX2_RORX(Y6,Y7,Y0,Y1,Y2,Y3,Y4,Y5,RE,RF,RG,RH,RA,RB,RC,RD,24)
     2536    MsgSched2_AVX2_RORX(Y7,Y0,Y1,Y2,Y3,Y4,Y5,Y6,RC,RD,RE,RF,RG,RH,RA,RB,28)
     2537        "addq   $256, %%rsi\n\t"
     2538        "addq   $256, %%rsp\n\t"
     2539        "cmpq   %[K512_END], %%rsi\n\t"
     2540        "jne    1b\n\t"
     2541
     2542    SET_BLOCK2_W_Y(rsi)
     2543    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 0)
     2544    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 4)
     2545    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD, 8)
     2546    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,12)
     2547
     2548    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH,16)
     2549    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,20)
     2550    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,24)
     2551    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,28)
     2552        "addq   " L3 ", %%r8\n\t"
     2553        "subq   $1024, %%rsp\n\t"
     2554
     2555    ADD_DIGEST()
     2556    STORE_DIGEST()
     2557
     2558        /* L4 = b */
     2559        "movq   %%r9, " L4 "\n\t"
     2560        /* L3 = 0 (add to prev h) */
     2561        "xorq   " L3 ", " L3 "\n\t"
     2562        /* L4 = b ^ c */
     2563        "xorq   %%r10, " L4 "\n\t"
     2564
     2565        "movq   $5, %%rsi\n\t"
     2566        "\n"
     2567        "3:\n\t"
     2568    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH, 2)
     2569    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF, 6)
     2570    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,10)
     2571    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,14)
     2572
     2573    RND_RORX_ALL_2(RA,RB,RC,RD,RE,RF,RG,RH,18)
     2574    RND_RORX_ALL_2(RG,RH,RA,RB,RC,RD,RE,RF,22)
     2575    RND_RORX_ALL_2(RE,RF,RG,RH,RA,RB,RC,RD,26)
     2576    RND_RORX_ALL_2(RC,RD,RE,RF,RG,RH,RA,RB,30)
     2577        "addq   $256, %%rsp\n\t"
     2578        "subq   $1, %%rsi\n\t"
     2579        "jnz    3b\n\t"
     2580
     2581        "addq   " L3 ", %%r8\n\t"
     2582
     2583    ADD_DIGEST()
     2584
     2585        "movq   224(%[sha512]), %%rax\n\t"
     2586        "addq   $64, %%rsp\n\t"
     2587        "addq   $256, %%rax\n\t"
     2588        "subl   $256, %[len]\n\t"
     2589        "movq   %%rax, 224(%[sha512])\n\t"
     2590
     2591    STORE_DIGEST()
     2592
     2593        "jnz    2b\n\t"
     2594
     2595        :
     2596        : [mask]   "m" (mBYTE_FLIP_MASK_Y),
     2597          [len]    "m" (len),
     2598          [sha512] "r" (sha512),
     2599          [K512]   "m" (K512_AVX2),
     2600          [K512_END]   "m" (K512_AVX2_END)
     2601        : WORK_REGS, STATE_REGS, YMM_REGS, "memory", "rsi"
     2602    );
     2603
     2604    return 0;
     2605}
     2606#endif /* HAVE_INTEL_RORX */
    13402607#endif /* HAVE_INTEL_AVX2 */
    13412608
     2609#endif /* WOLFSSL_SHA512 */
    13422610
    13432611
     
    13462614/* -------------------------------------------------------------------------- */
    13472615#ifdef WOLFSSL_SHA384
     2616
     2617#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
     2618    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
     2619#else
     2620
    13482621static int InitSha384(wc_Sha384* sha384)
    13492622{
     
    13862659
    13872660
     2661int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
     2662{
     2663#ifdef LITTLE_ENDIAN_ORDER
     2664    word64 digest[WC_SHA384_DIGEST_SIZE / sizeof(word64)];
     2665#endif
     2666
     2667    if (sha384 == NULL || hash == NULL) {
     2668        return BAD_FUNC_ARG;
     2669    }
     2670
     2671#ifdef LITTLE_ENDIAN_ORDER
     2672    ByteReverseWords64((word64*)digest, (word64*)sha384->digest,
     2673                                                         WC_SHA384_DIGEST_SIZE);
     2674    XMEMCPY(hash, digest, WC_SHA384_DIGEST_SIZE);
     2675#else
     2676    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
     2677#endif
     2678
     2679    return 0;
     2680}
     2681
    13882682int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
    13892683{
     
    14122706}
    14132707
    1414 
    1415 /* Hardware Acceleration */
    1416 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
    1417     int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
    1418     {
    1419         int ret = InitSha384(sha384);
    1420 
    1421         (void)heap;
    1422         (void)devId;
    1423 
    1424         Sha512_SetTransform();
    1425 
    1426         return ret;
    1427     }
    1428 #else
    14292708int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
    14302709{
     
    14392718    if (ret != 0)
    14402719        return ret;
     2720
     2721#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
     2722    Sha512_SetTransform();
     2723#endif
     2724#ifdef WOLFSSL_SMALL_STACK_CACHE
     2725    sha384->W = NULL;
     2726#endif
    14412727
    14422728#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
     
    14492735    return ret;
    14502736}
    1451 #endif
     2737
     2738#endif /* WOLFSSL_IMX6_CAAM */
    14522739
    14532740int wc_InitSha384(wc_Sha384* sha384)
     
    14612748        return;
    14622749
     2750#ifdef WOLFSSL_SMALL_STACK_CACHE
     2751    if (sha384->W != NULL) {
     2752        XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     2753        sha384->W = NULL;
     2754    }
     2755#endif
     2756
    14632757#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
    14642758    wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);
     
    14702764#endif /* HAVE_FIPS */
    14712765
     2766#ifdef WOLFSSL_SHA512
    14722767
    14732768int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
     
    14822777    if (ret == 0) {
    14832778        ret = wc_Sha512Final(&tmpSha512, hash);
     2779        wc_Sha512Free(&tmpSha512);
    14842780    }
    14852781    return ret;
     
    14942790
    14952791    XMEMCPY(dst, src, sizeof(wc_Sha512));
     2792#ifdef WOLFSSL_SMALL_STACK_CACHE
     2793    dst->W = NULL;
     2794#endif
    14962795
    14972796#ifdef WOLFSSL_ASYNC_CRYPT
     
    15022801}
    15032802
     2803#endif /* WOLFSSL_SHA512 */
     2804
    15042805#ifdef WOLFSSL_SHA384
     2806
    15052807int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
    15062808{
     
    15142816    if (ret == 0) {
    15152817        ret = wc_Sha384Final(&tmpSha384, hash);
     2818        wc_Sha384Free(&tmpSha384);
    15162819    }
    15172820    return ret;
     
    15252828
    15262829    XMEMCPY(dst, src, sizeof(wc_Sha384));
     2830#ifdef WOLFSSL_SMALL_STACK_CACHE
     2831    dst->W = NULL;
     2832#endif
    15272833
    15282834#ifdef WOLFSSL_ASYNC_CRYPT
     
    15322838    return ret;
    15332839}
     2840
    15342841#endif /* WOLFSSL_SHA384 */
    15352842
    1536 #endif /* WOLFSSL_SHA512 */
     2843#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/wc_encrypt.c

    r352 r372  
    2828#include <wolfssl/wolfcrypt/aes.h>
    2929#include <wolfssl/wolfcrypt/des3.h>
     30#include <wolfssl/wolfcrypt/hash.h>
     31#include <wolfssl/wolfcrypt/arc4.h>
    3032#include <wolfssl/wolfcrypt/wc_encrypt.h>
    3133#include <wolfssl/wolfcrypt/error-crypt.h>
    32 
     34#include <wolfssl/wolfcrypt/asn.h>
     35#include <wolfssl/wolfcrypt/coding.h>
     36#include <wolfssl/wolfcrypt/pwdbased.h>
     37#include <wolfssl/wolfcrypt/logging.h>
     38
     39#ifdef NO_INLINE
     40    #include <wolfssl/wolfcrypt/misc.h>
     41#else
     42    #define WOLFSSL_MISC_INCLUDED
     43    #include <wolfcrypt/src/misc.c>
     44#endif
    3345
    3446#if !defined(NO_AES) && defined(HAVE_AES_CBC)
     
    225237
    226238#endif /* !NO_DES3 */
     239
     240
     241#ifdef WOLFSSL_ENCRYPTED_KEYS
     242
     243int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz,
     244    const byte* password, int passwordSz, int hashType)
     245{
     246    int ret = NOT_COMPILED_IN;
     247#ifdef WOLFSSL_SMALL_STACK
     248    byte* key      = NULL;
     249#else
     250    byte  key[WC_MAX_SYM_KEY_SIZE];
     251#endif
     252
     253    (void)derSz;
     254    (void)passwordSz;
     255    (void)hashType;
     256
     257    if (der == NULL || password == NULL || info == NULL || info->keySz == 0) {
     258        return BAD_FUNC_ARG;
     259    }
     260
     261    /* use file's salt for key derivation, hex decode first */
     262    if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {
     263        return BUFFER_E;
     264    }
     265    if (info->ivSz < PKCS5_SALT_SZ)
     266        return BUFFER_E;
     267
     268#ifdef WOLFSSL_SMALL_STACK
     269    key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     270    if (key == NULL) {
     271        return MEMORY_E;
     272    }
     273#endif
     274
     275#ifndef NO_PWDBASED
     276    if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
     277                                        info->keySz, hashType)) != 0) {
     278#ifdef WOLFSSL_SMALL_STACK
     279        XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     280#endif
     281        return ret;
     282    }
     283#endif
     284
     285#ifndef NO_DES3
     286    if (info->cipherType == WC_CIPHER_DES)
     287        ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv);
     288    if (info->cipherType == WC_CIPHER_DES3)
     289        ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv);
     290#endif /* NO_DES3 */
     291#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)
     292    if (info->cipherType == WC_CIPHER_AES_CBC)
     293        ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz,
     294            info->iv);
     295#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */
     296
     297#ifdef WOLFSSL_SMALL_STACK
     298    XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     299#endif
     300
     301    return ret;
     302}
     303
     304int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,
     305    const byte* password, int passwordSz, int hashType)
     306{
     307    int ret = NOT_COMPILED_IN;
     308#ifdef WOLFSSL_SMALL_STACK
     309    byte* key      = NULL;
     310#else
     311    byte  key[WC_MAX_SYM_KEY_SIZE];
     312#endif
     313
     314    (void)derSz;
     315    (void)passwordSz;
     316    (void)hashType;
     317
     318    if (der == NULL || password == NULL || info == NULL || info->keySz == 0 ||
     319            info->ivSz < PKCS5_SALT_SZ) {
     320        return BAD_FUNC_ARG;
     321    }
     322
     323#ifdef WOLFSSL_SMALL_STACK
     324    key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     325    if (key == NULL) {
     326        return MEMORY_E;
     327    }
     328#endif /* WOLFSSL_SMALL_STACK */
     329
     330#ifndef NO_PWDBASED
     331    if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,
     332                                        info->keySz, hashType)) != 0) {
     333#ifdef WOLFSSL_SMALL_STACK
     334        XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     335#endif
     336        return ret;
     337    }
     338#endif
     339
     340#ifndef NO_DES3
     341    if (info->cipherType == WC_CIPHER_DES)
     342        ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);
     343    if (info->cipherType == WC_CIPHER_DES3)
     344        ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);
     345#endif /* NO_DES3 */
     346#if !defined(NO_AES) && defined(HAVE_AES_CBC)
     347    if (info->cipherType == WC_CIPHER_AES_CBC)
     348        ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz,
     349            info->iv);
     350#endif /* !NO_AES && HAVE_AES_CBC */
     351
     352#ifdef WOLFSSL_SMALL_STACK
     353    XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);
     354#endif
     355
     356    return ret;
     357}
     358
     359#endif /* WOLFSSL_ENCRYPTED_KEYS */
     360
     361
     362#ifndef NO_PWDBASED
     363
     364/* Decrypt/Encrypt input in place from parameters based on id
     365 *
     366 * returns a negative value on fail case
     367 */
     368int wc_CryptKey(const char* password, int passwordSz, byte* salt,
     369                      int saltSz, int iterations, int id, byte* input,
     370                      int length, int version, byte* cbcIv, int enc)
     371{
     372    int typeH;
     373    int derivedLen;
     374    int ret = 0;
     375#ifdef WOLFSSL_SMALL_STACK
     376    byte* key;
     377#else
     378    byte key[MAX_KEY_SIZE];
     379#endif
     380
     381    (void)input;
     382    (void)length;
     383    (void)enc;
     384
     385    WOLFSSL_ENTER("wc_CryptKey");
     386
     387    switch (id) {
     388    #ifndef NO_DES3
     389        #ifndef NO_MD5
     390        case PBE_MD5_DES:
     391            typeH = WC_MD5;
     392            derivedLen = 16;           /* may need iv for v1.5 */
     393            break;
     394        #endif
     395        #ifndef NO_SHA
     396        case PBE_SHA1_DES:
     397            typeH = WC_SHA;
     398            derivedLen = 16;           /* may need iv for v1.5 */
     399            break;
     400
     401        case PBE_SHA1_DES3:
     402            typeH = WC_SHA;
     403            derivedLen = 32;           /* may need iv for v1.5 */
     404            break;
     405        #endif /* !NO_SHA */
     406    #endif /* !NO_DES3 */
     407    #if !defined(NO_SHA) && !defined(NO_RC4)
     408        case PBE_SHA1_RC4_128:
     409            typeH = WC_SHA;
     410            derivedLen = 16;
     411            break;
     412    #endif
     413    #ifdef WOLFSSL_AES_256
     414        case PBE_AES256_CBC:
     415            typeH = WC_SHA256;
     416            derivedLen = 32;
     417            break;
     418    #endif
     419        default:
     420            WOLFSSL_MSG("Unknown/Unsupported encrypt/decrypt id");
     421            return ALGO_ID_E;
     422    }
     423
     424#ifdef WOLFSSL_SMALL_STACK
     425    key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     426    if (key == NULL)
     427        return MEMORY_E;
     428#endif
     429
     430    if (version == PKCS5v2)
     431        ret = wc_PBKDF2(key, (byte*)password, passwordSz,
     432                        salt, saltSz, iterations, derivedLen, typeH);
     433#ifndef NO_SHA
     434    else if (version == PKCS5)
     435        ret = wc_PBKDF1(key, (byte*)password, passwordSz,
     436                        salt, saltSz, iterations, derivedLen, typeH);
     437#endif
     438    else if (version == PKCS12v1) {
     439        int  i, idx = 0;
     440        byte unicodePasswd[MAX_UNICODE_SZ];
     441
     442        if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
     443#ifdef WOLFSSL_SMALL_STACK
     444            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     445#endif
     446            return UNICODE_SIZE_E;
     447        }
     448
     449        for (i = 0; i < passwordSz; i++) {
     450            unicodePasswd[idx++] = 0x00;
     451            unicodePasswd[idx++] = (byte)password[i];
     452        }
     453        /* add trailing NULL */
     454        unicodePasswd[idx++] = 0x00;
     455        unicodePasswd[idx++] = 0x00;
     456
     457        ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,
     458                            iterations, derivedLen, typeH, 1);
     459        if (id != PBE_SHA1_RC4_128)
     460            ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,
     461                                iterations, 8, typeH, 2);
     462    }
     463    else {
     464#ifdef WOLFSSL_SMALL_STACK
     465        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     466#endif
     467        WOLFSSL_MSG("Unknown/Unsupported PKCS version");
     468        return ALGO_ID_E;
     469    }
     470
     471    if (ret != 0) {
     472#ifdef WOLFSSL_SMALL_STACK
     473        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     474#endif
     475        return ret;
     476    }
     477
     478    switch (id) {
     479#ifndef NO_DES3
     480    #if !defined(NO_SHA) || !defined(NO_MD5)
     481        case PBE_MD5_DES:
     482        case PBE_SHA1_DES:
     483        {
     484            Des    des;
     485            byte*  desIv = key + 8;
     486
     487            if (version == PKCS5v2 || version == PKCS12v1)
     488                desIv = cbcIv;
     489
     490            if (enc) {
     491                ret = wc_Des_SetKey(&des, key, desIv, DES_ENCRYPTION);
     492            }
     493            else {
     494                ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION);
     495            }
     496            if (ret != 0) {
     497#ifdef WOLFSSL_SMALL_STACK
     498                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     499#endif
     500                return ret;
     501            }
     502
     503            if (enc) {
     504                wc_Des_CbcEncrypt(&des, input, input, length);
     505            }
     506            else {
     507                wc_Des_CbcDecrypt(&des, input, input, length);
     508            }
     509            break;
     510        }
     511    #endif /* !NO_SHA || !NO_MD5 */
     512
     513    #ifndef NO_SHA
     514        case PBE_SHA1_DES3:
     515        {
     516            Des3   des;
     517            byte*  desIv = key + 24;
     518
     519            if (version == PKCS5v2 || version == PKCS12v1)
     520                desIv = cbcIv;
     521
     522            ret = wc_Des3Init(&des, NULL, INVALID_DEVID);
     523            if (ret != 0) {
     524#ifdef WOLFSSL_SMALL_STACK
     525                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     526#endif
     527                return ret;
     528            }
     529            if (enc) {
     530                ret = wc_Des3_SetKey(&des, key, desIv, DES_ENCRYPTION);
     531            }
     532            else {
     533                ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION);
     534            }
     535            if (ret != 0) {
     536#ifdef WOLFSSL_SMALL_STACK
     537                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     538#endif
     539                return ret;
     540            }
     541            if (enc) {
     542                ret = wc_Des3_CbcEncrypt(&des, input, input, length);
     543            }
     544            else {
     545                ret = wc_Des3_CbcDecrypt(&des, input, input, length);
     546            }
     547            if (ret != 0) {
     548#ifdef WOLFSSL_SMALL_STACK
     549                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     550#endif
     551                return ret;
     552            }
     553            break;
     554        }
     555    #endif /* !NO_SHA */
     556#endif
     557#if !defined(NO_RC4) && !defined(NO_SHA)
     558        case PBE_SHA1_RC4_128:
     559        {
     560            Arc4    dec;
     561
     562            wc_Arc4SetKey(&dec, key, derivedLen);
     563            wc_Arc4Process(&dec, input, input, length);
     564            break;
     565        }
     566#endif
     567#if !defined(NO_AES) && defined(HAVE_AES_CBC)
     568    #ifdef WOLFSSL_AES_256
     569        case PBE_AES256_CBC:
     570        {
     571            Aes aes;
     572            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
     573            if (ret == 0) {
     574                if (enc) {
     575                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
     576                                                                AES_ENCRYPTION);
     577                }
     578                else {
     579                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
     580                                                                AES_DECRYPTION);
     581                }
     582            }
     583            if (ret == 0) {
     584                if (enc)
     585                    ret = wc_AesCbcEncrypt(&aes, input, input, length);
     586                else
     587                    ret = wc_AesCbcDecrypt(&aes, input, input, length);
     588            }
     589            if (ret != 0) {
     590#ifdef WOLFSSL_SMALL_STACK
     591                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     592#endif
     593                return ret;
     594            }
     595            ForceZero(&aes, sizeof(Aes));
     596            break;
     597        }
     598    #endif /* WOLFSSL_AES_256 */
     599#endif /* !NO_AES && HAVE_AES_CBC */
     600
     601        default:
     602#ifdef WOLFSSL_SMALL_STACK
     603            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     604#endif
     605            WOLFSSL_MSG("Unknown/Unsupported encrypt/decryption algorithm");
     606            return ALGO_ID_E;
     607    }
     608
     609#ifdef WOLFSSL_SMALL_STACK
     610    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     611#endif
     612
     613    return ret;
     614}
     615
     616#endif /* !NO_PWDBASED */
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/wc_port.c

    r352 r372  
    4343#endif
    4444
    45 #if defined(FREESCALE_LTC_TFM)
     45#ifdef FREESCALE_LTC_TFM
    4646    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
    4747#endif
    4848
    49 #ifdef WOLFSSL_ATMEL
     49#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)
    5050    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
     51#endif
     52
     53#if defined(WOLFSSL_STSAFEA100)
     54    #include <wolfssl/wolfcrypt/port/st/stsafe.h>
    5155#endif
    5256
     
    5862    #include <wolfssl/wolfcrypt/memory.h>
    5963    #include <wolfssl/wolfcrypt/mem_track.h>
     64#endif
     65
     66#if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
     67    defined(WOLFSSL_IMX6_CAAM_BLOB)
     68    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
     69#endif
     70
     71#ifdef WOLF_CRYPTO_DEV
     72    #include <wolfssl/wolfcrypt/cryptodev.h>
    6073#endif
    6174
     
    7790    if (initRefCount == 0) {
    7891        WOLFSSL_ENTER("wolfCrypt_Init");
     92
     93    #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
     94        {
     95            word32 rngMallocFail;
     96            time_t seed = time(NULL);
     97            srand((word32)seed);
     98            rngMallocFail = rand() % 2000; /* max 2000 */
     99            printf("\n--- RNG MALLOC FAIL AT %d---\n", rngMallocFail);
     100            wolfSSL_SetMemFailCount(rngMallocFail);
     101        }
     102    #endif
     103
     104    #ifdef WOLF_CRYPTO_DEV
     105        wc_CryptoDev_Init();
     106    #endif
    79107
    80108    #ifdef WOLFSSL_ASYNC_CRYPT
     
    125153    #endif
    126154
    127     #ifdef WOLFSSL_ATMEL
    128         atmel_init();
     155    #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)
     156        ret = atmel_init();
     157        if (ret != 0) {
     158            WOLFSSL_MSG("CryptoAuthLib init failed");
     159            return ret;
     160        }
     161    #endif
     162
     163    #if defined(WOLFSSL_STSAFEA100)
     164        stsafe_interface_init();
    129165    #endif
    130166
    131167    #ifdef WOLFSSL_ARMASM
    132168        WOLFSSL_MSG("Using ARM hardware acceleration");
     169    #endif
     170
     171    #ifdef WOLFSSL_AFALG
     172        WOLFSSL_MSG("Using AF_ALG for crypto acceleration");
    133173    #endif
    134174
     
    154194#endif
    155195
     196#if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
     197    defined(WOLFSSL_IMX6_CAAM_BLOB)
     198        if ((ret = wc_caamInit()) != 0) {
     199            return ret;
     200        }
     201#endif
     202
    156203        initRefCount = 1;
    157204    }
     
    190237    #endif
    191238
     239    #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \
     240        defined(WOLFSSL_IMX6_CAAM_BLOB)
     241        wc_caamFree();
     242    #endif
     243
    192244        initRefCount = 0; /* allow re-init */
    193245    }
     
    196248}
    197249
    198 #if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
     250#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) && \
     251        !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
    199252
    200253/* File Handling Helpers */
    201 /* returns 0 if file found, -1 if no files or negative error */
     254/* returns 0 if file found, WC_READDIR_NOFILE if no files or negative error */
    202255int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
    203256{
    204     int ret = -1; /* default to no files found */
     257    int ret = WC_READDIR_NOFILE; /* default to no files found */
     258    int pathLen = 0;
     259    int dnameLen = 0;
    205260
    206261    if (name)
     
    212267
    213268    XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
     269    pathLen = (int)XSTRLEN(path);
    214270
    215271#ifdef USE_WINDOWS_API
    216     XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 4);
    217     XSTRNCAT(ctx->name, "\\*", 3);
     272    if (pathLen > MAX_FILENAME_SZ - 3)
     273        return BAD_PATH_ERROR;
     274
     275    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);
     276    XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen);
    218277
    219278    ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);
     
    225284    do {
    226285        if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
    227             XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
    228             XSTRNCAT(ctx->name, "\\", 2);
    229             XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
     286            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
     287
     288            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
     289                return BAD_PATH_ERROR;
     290            }
     291            XSTRNCPY(ctx->name, path, pathLen + 1);
     292            ctx->name[pathLen] = '\\';
     293            XSTRNCPY(ctx->name + pathLen + 1,
     294                     ctx->FindFileData.cFileName,
     295                     MAX_FILENAME_SZ - pathLen - 1);
    230296            if (name)
    231297                *name = ctx->name;
     
    241307
    242308    while ((ctx->entry = readdir(ctx->dir)) != NULL) {
    243         XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
    244         XSTRNCAT(ctx->name, "/", 1);
    245         XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
     309        dnameLen = (int)XSTRLEN(ctx->entry->d_name);
     310
     311        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
     312            ret = BAD_PATH_ERROR;
     313            break;
     314        }
     315        XSTRNCPY(ctx->name, path, pathLen + 1);
     316        ctx->name[pathLen] = '/';
     317        XSTRNCPY(ctx->name + pathLen + 1,
     318                 ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);
    246319
    247320        if (stat(ctx->name, &ctx->s) != 0) {
     
    249322            ret = BAD_PATH_ERROR;
    250323            break;
    251         } else if (ctx->s.st_mode & S_IFREG) {
     324        } else if (S_ISREG(ctx->s.st_mode)) {
    252325            if (name)
    253326                *name = ctx->name;
     
    261334}
    262335
    263 /* returns 0 if file found, -1 if no more files */
     336/* returns 0 if file found, WC_READDIR_NOFILE if no more files */
    264337int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
    265338{
    266     int ret = -1; /* default to no file found */
     339    int ret = WC_READDIR_NOFILE; /* default to no file found */
     340    int pathLen = 0;
     341    int dnameLen = 0;
    267342
    268343    if (name)
     
    274349
    275350    XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
     351    pathLen = (int)XSTRLEN(path);
    276352
    277353#ifdef USE_WINDOWS_API
    278354    while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
    279355        if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
    280             XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
    281             XSTRNCAT(ctx->name, "\\", 2);
    282             XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
     356            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);
     357
     358            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
     359                return BAD_PATH_ERROR;
     360            }
     361            XSTRNCPY(ctx->name, path, pathLen + 1);
     362            ctx->name[pathLen] = '\\';
     363            XSTRNCPY(ctx->name + pathLen + 1,
     364                     ctx->FindFileData.cFileName,
     365                     MAX_FILENAME_SZ - pathLen - 1);
    283366            if (name)
    284367                *name = ctx->name;
     
    288371#else
    289372    while ((ctx->entry = readdir(ctx->dir)) != NULL) {
    290         XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
    291         XSTRNCAT(ctx->name, "/", 1);
    292         XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
     373        dnameLen = (int)XSTRLEN(ctx->entry->d_name);
     374
     375        if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {
     376            ret = BAD_PATH_ERROR;
     377            break;
     378        }
     379        XSTRNCPY(ctx->name, path, pathLen + 1);
     380        ctx->name[pathLen] = '/';
     381        XSTRNCPY(ctx->name + pathLen + 1,
     382                 ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1);
    293383
    294384        if (stat(ctx->name, &ctx->s) != 0) {
     
    296386            ret = BAD_PATH_ERROR;
    297387            break;
    298         } else if (ctx->s.st_mode & S_IFREG) {
     388        } else if (S_ISREG(ctx->s.st_mode)) {
    299389            if (name)
    300390                *name = ctx->name;
     
    403493#endif /* USE_WOLF_STRTOK */
    404494
     495#ifdef USE_WOLF_STRSEP
     496char* wc_strsep(char **stringp, const char *delim)
     497{
     498    char *s, *tok;
     499    const char *spanp;
     500
     501    /* null check */
     502    if (stringp == NULL || *stringp == NULL)
     503        return NULL;
     504
     505    s = *stringp;
     506    for (tok = s; *tok; ++tok) {
     507        for (spanp = delim; *spanp; ++spanp) {
     508            /* found delimiter */
     509            if (*tok == *spanp) {
     510                *tok = '\0'; /* replace delim with null term */
     511                *stringp = tok + 1; /* return past delim */
     512                return s;
     513            }
     514        }
     515    }
     516
     517    *stringp = NULL;
     518    return s;
     519}
     520#endif /* USE_WOLF_STRSEP */
     521
    405522#if WOLFSSL_CRYPT_HW_MUTEX
    406523/* Mutex for protection of cryptography hardware */
     
    445562/* Mutex Ports */
    446563/* ---------------------------------------------------------------------------*/
     564#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
     565    static mutex_cb*     compat_mutex_cb = NULL;
     566
     567    /* Function that locks or unlocks a mutex based on the flag passed in.
     568     *
     569     * flag lock or unlock i.e. CRYPTO_LOCK
     570     * type the type of lock to unlock or lock
     571     * file name of the file calling
     572     * line the line number from file calling
     573     */
     574    int wc_LockMutex_ex(int flag, int type, const char* file, int line)
     575    {
     576        if (compat_mutex_cb != NULL) {
     577            compat_mutex_cb(flag, type, file, line);
     578            return 0;
     579        }
     580        else {
     581            WOLFSSL_MSG("Mutex call back function not set. Call wc_SetMutexCb");
     582            return BAD_STATE_E;
     583        }
     584    }
     585
     586
     587    /* Set the callback function to use for locking/unlocking mutex
     588     *
     589     * cb callback function to use
     590     */
     591    int wc_SetMutexCb(mutex_cb* cb)
     592    {
     593        compat_mutex_cb = cb;
     594        return 0;
     595    }
     596#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
    447597#ifdef SINGLE_THREADED
    448598
     
    602752        else
    603753            return BAD_MUTEX_E;
     754    }
     755
     756#elif defined(WOLFSSL_VXWORKS)
     757
     758    int wc_InitMutex(wolfSSL_Mutex* m)
     759    {
     760        if (m) {
     761            if ((*m = semMCreate(0)) != SEM_ID_NULL)
     762                return 0;
     763        }
     764        return BAD_MUTEX_E;
     765    }
     766
     767
     768    int wc_FreeMutex(wolfSSL_Mutex* m)
     769    {
     770        if (m) {
     771            if (semDelete(*m) == OK)
     772                return 0;
     773        }
     774        return BAD_MUTEX_E;
     775    }
     776
     777
     778    int wc_LockMutex(wolfSSL_Mutex* m)
     779    {
     780        if (m) {
     781            if (semTake(*m, WAIT_FOREVER) == OK)
     782                return 0;
     783        }
     784        return BAD_MUTEX_E;
     785    }
     786
     787
     788    int wc_UnLockMutex(wolfSSL_Mutex* m)
     789    {
     790        if (m) {
     791            if (semGive(*m) == OK)
     792                return 0;
     793        }
     794        return BAD_MUTEX_E;
    604795    }
    605796
     
    11701361    }
    11711362
     1363#elif defined(WOLFSSL_NUCLEUS_1_2)
     1364
     1365    int wc_InitMutex(wolfSSL_Mutex* m)
     1366    {
     1367        /* Call the Nucleus function to create the semaphore */
     1368        if (NU_Create_Semaphore(m, "WOLFSSL_MTX", 1,
     1369                                NU_PRIORITY) == NU_SUCCESS) {
     1370            return 0;
     1371        }
     1372
     1373        return BAD_MUTEX_E;
     1374    }
     1375
     1376    int wc_FreeMutex(wolfSSL_Mutex* m)
     1377    {
     1378        if (NU_Delete_Semaphore(m) == NU_SUCCESS)
     1379            return 0;
     1380
     1381        return BAD_MUTEX_E;
     1382    }
     1383
     1384    int wc_LockMutex(wolfSSL_Mutex* m)
     1385    {
     1386        /* passing suspend task option */
     1387        if (NU_Obtain_Semaphore(m, NU_SUSPEND) == NU_SUCCESS)
     1388            return 0;
     1389
     1390        return BAD_MUTEX_E;
     1391    }
     1392
     1393    int wc_UnLockMutex(wolfSSL_Mutex* m)
     1394    {
     1395        if (NU_Release_Semaphore(m) == NU_SUCCESS)
     1396            return 0;
     1397
     1398        return BAD_MUTEX_E;
     1399    }
     1400
    11721401#else
    11731402    #warning No mutex handling defined
     
    11751404#endif
    11761405
     1406#ifndef NO_ASN_TIME
     1407#if defined(_WIN32_WCE)
     1408time_t windows_time(time_t* timer)
     1409{
     1410    SYSTEMTIME     sysTime;
     1411    FILETIME       fTime;
     1412    ULARGE_INTEGER intTime;
     1413    time_t         localTime;
     1414
     1415    if (timer == NULL)
     1416        timer = &localTime;
     1417
     1418    GetSystemTime(&sysTime);
     1419    SystemTimeToFileTime(&sysTime, &fTime);
     1420
     1421    XMEMCPY(&intTime, &fTime, sizeof(FILETIME));
     1422    /* subtract EPOCH */
     1423    intTime.QuadPart -= 0x19db1ded53e8000;
     1424    /* to secs */
     1425    intTime.QuadPart /= 10000000;
     1426    *timer = (time_t)intTime.QuadPart;
     1427
     1428    return *timer;
     1429}
     1430#endif /*  _WIN32_WCE */
     1431
     1432#if defined(WOLFSSL_APACHE_MYNEWT)
     1433#include "os/os_time.h"
     1434
     1435time_t mynewt_time(time_t* timer)
     1436{
     1437    time_t now;
     1438    struct os_timeval tv;
     1439    os_gettimeofday(&tv, NULL);
     1440    now = (time_t)tv.tv_sec;
     1441    if(timer != NULL) {
     1442        *timer = now;
     1443    }
     1444    return now;
     1445}
     1446#endif /* WOLFSSL_APACHE_MYNEWT */
     1447
     1448#if defined(WOLFSSL_GMTIME)
     1449struct tm* gmtime(const time_t* timer)
     1450{
     1451    #define YEAR0          1900
     1452    #define EPOCH_YEAR     1970
     1453    #define SECS_DAY       (24L * 60L * 60L)
     1454    #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))
     1455    #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
     1456
     1457    static const int _ytab[2][12] =
     1458    {
     1459        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
     1460        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
     1461    };
     1462
     1463    static struct tm st_time;
     1464    struct tm* ret = &st_time;
     1465    time_t secs = *timer;
     1466    unsigned long dayclock, dayno;
     1467    int year = EPOCH_YEAR;
     1468
     1469    dayclock = (unsigned long)secs % SECS_DAY;
     1470    dayno    = (unsigned long)secs / SECS_DAY;
     1471
     1472    ret->tm_sec  = (int) dayclock % 60;
     1473    ret->tm_min  = (int)(dayclock % 3600) / 60;
     1474    ret->tm_hour = (int) dayclock / 3600;
     1475    ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */
     1476
     1477    while(dayno >= (unsigned long)YEARSIZE(year)) {
     1478        dayno -= YEARSIZE(year);
     1479        year++;
     1480    }
     1481
     1482    ret->tm_year = year - YEAR0;
     1483    ret->tm_yday = (int)dayno;
     1484    ret->tm_mon  = 0;
     1485
     1486    while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {
     1487        dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];
     1488        ret->tm_mon++;
     1489    }
     1490
     1491    ret->tm_mday  = (int)++dayno;
     1492    ret->tm_isdst = 0;
     1493
     1494    return ret;
     1495}
     1496#endif /* WOLFSSL_GMTIME */
     1497
     1498
     1499#if defined(HAVE_RTP_SYS)
     1500#define YEAR0          1900
     1501
     1502struct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */
     1503{
     1504    static struct tm st_time;
     1505    struct tm* ret = &st_time;
     1506
     1507    DC_RTC_CALENDAR cal;
     1508    dc_rtc_time_get(&cal, TRUE);
     1509
     1510    ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */
     1511    ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */
     1512    ret->tm_mday  = cal.day;
     1513    ret->tm_hour  = cal.hour;
     1514    ret->tm_min   = cal.minute;
     1515    ret->tm_sec   = cal.second;
     1516
     1517    return ret;
     1518}
     1519
     1520#endif /* HAVE_RTP_SYS */
     1521
     1522
     1523#if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)
     1524
     1525/*
     1526 * time() is just a stub in Microchip libraries. We need our own
     1527 * implementation. Use SNTP client to get seconds since epoch.
     1528 */
     1529time_t pic32_time(time_t* timer)
     1530{
     1531#ifdef MICROCHIP_TCPIP_V5
     1532    DWORD sec = 0;
     1533#else
     1534    uint32_t sec = 0;
     1535#endif
     1536    time_t localTime;
     1537
     1538    if (timer == NULL)
     1539        timer = &localTime;
     1540
     1541#ifdef MICROCHIP_MPLAB_HARMONY
     1542    sec = TCPIP_SNTP_UTCSecondsGet();
     1543#else
     1544    sec = SNTPGetUTCSeconds();
     1545#endif
     1546    *timer = (time_t) sec;
     1547
     1548    return *timer;
     1549}
     1550
     1551#endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */
     1552
     1553#if defined(MICRIUM)
     1554
     1555time_t micrium_time(time_t* timer)
     1556{
     1557    CLK_TS_SEC sec;
     1558
     1559    Clk_GetTS_Unix(&sec);
     1560
     1561    if (timer != NULL)
     1562        *timer = sec;
     1563
     1564    return (time_t) sec;
     1565}
     1566
     1567#endif /* MICRIUM */
     1568
     1569#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
     1570
     1571time_t mqx_time(time_t* timer)
     1572{
     1573    time_t localTime;
     1574    TIME_STRUCT time_s;
     1575
     1576    if (timer == NULL)
     1577        timer = &localTime;
     1578
     1579    _time_get(&time_s);
     1580    *timer = (time_t) time_s.SECONDS;
     1581
     1582    return *timer;
     1583}
     1584
     1585#endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */
     1586
     1587
     1588#if defined(WOLFSSL_TIRTOS)
     1589
     1590time_t XTIME(time_t * timer)
     1591{
     1592    time_t sec = 0;
     1593
     1594    sec = (time_t) Seconds_get();
     1595
     1596    if (timer != NULL)
     1597        *timer = sec;
     1598
     1599    return sec;
     1600}
     1601
     1602#endif /* WOLFSSL_TIRTOS */
     1603
     1604#if defined(WOLFSSL_XILINX)
     1605#include "xrtcpsu.h"
     1606
     1607time_t XTIME(time_t * timer)
     1608{
     1609    time_t sec = 0;
     1610    XRtcPsu_Config* con;
     1611    XRtcPsu         rtc;
     1612
     1613    con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);
     1614    if (con != NULL) {
     1615        if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {
     1616            sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);
     1617        }
     1618        else {
     1619            WOLFSSL_MSG("Unable to initialize RTC");
     1620        }
     1621    }
     1622
     1623    if (timer != NULL)
     1624        *timer = sec;
     1625
     1626    return sec;
     1627}
     1628
     1629#endif /* WOLFSSL_XILINX */
     1630#endif /* !NO_ASN_TIME */
     1631
     1632#ifndef WOLFSSL_LEANPSK
     1633char* mystrnstr(const char* s1, const char* s2, unsigned int n)
     1634{
     1635    unsigned int s2_len = (unsigned int)XSTRLEN(s2);
     1636
     1637    if (s2_len == 0)
     1638        return (char*)s1;
     1639
     1640    while (n >= s2_len && s1[0]) {
     1641        if (s1[0] == s2[0])
     1642            if (XMEMCMP(s1, s2, s2_len) == 0)
     1643                return (char*)s1;
     1644        s1++;
     1645        n--;
     1646    }
     1647
     1648    return NULL;
     1649}
     1650#endif
     1651
     1652/* custom memory wrappers */
     1653#ifdef WOLFSSL_NUCLEUS_1_2
     1654
     1655    /* system memory pool */
     1656    extern NU_MEMORY_POOL System_Memory;
     1657
     1658    void* nucleus_malloc(unsigned long size, void* heap, int type)
     1659    {
     1660        STATUS status;
     1661        void*  stack_ptr;
     1662
     1663        status = NU_Allocate_Memory(&System_Memory, &stack_ptr, size,
     1664                                    NU_NO_SUSPEND);
     1665        if (status == NU_SUCCESS) {
     1666            return 0;
     1667        } else {
     1668            return stack_ptr;
     1669        }
     1670    }
     1671
     1672    void* nucleus_realloc(void* ptr, unsigned long size, void* heap, int type)
     1673    {
     1674        STATUS     status;
     1675        DM_HEADER* old_header;
     1676        word32     old_size, copy_size;
     1677        void*      new_mem;
     1678
     1679        /* if ptr is NULL, behave like malloc */
     1680        new_mem = nucleus_malloc(size, NULL, 0);
     1681        if (new_mem == 0 || ptr == 0) {
     1682            return new_mem;
     1683        }
     1684
     1685        /* calculate old memory block size */
     1686        /* mem pointers stored in block headers (ref dm_defs.h) */
     1687        old_header = (DM_HEADER*) ((byte*)ptr - DM_OVERHEAD);
     1688        old_size   = (byte*)old_header->dm_next_memory - (byte*)ptr;
     1689
     1690        /* copy old to new */
     1691        if (old_size < size) {
     1692            copy_size = old_size;
     1693        } else {
     1694            copy_size = size;
     1695        }
     1696        XMEMCPY(new_mem, ptr, copy_size);
     1697
     1698        /* free old */
     1699        nucleus_free(ptr, NULL, 0);
     1700
     1701        return new_mem;
     1702    }
     1703
     1704    void nucleus_free(void* ptr, void* heap, int type)
     1705    {
     1706        if (ptr != NULL)
     1707            NU_Deallocate_Memory(ptr);
     1708    }
     1709
     1710#endif /* WOLFSSL_NUCLEUS_1_2 */
    11771711
    11781712#if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH)
  • asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/wolfmath.c

    r352 r372  
    3030#include <wolfssl/wolfcrypt/settings.h>
    3131
    32 #ifdef USE_FAST_MATH
    33     #include <wolfssl/wolfcrypt/tfm.h>
    34 #else
    3532    #include <wolfssl/wolfcrypt/integer.h>
    36 #endif
    3733
    3834#include <wolfssl/wolfcrypt/error-crypt.h>
     
    9288}
    9389
     90#ifndef WC_NO_RNG
    9491int get_rand_digit(WC_RNG* rng, mp_digit* d)
    9592{
     
    10097int mp_rand(mp_int* a, int digits, WC_RNG* rng)
    10198{
    102     int ret;
    103     mp_digit d;
    104 
    105     if (rng == NULL)
    106         return MISSING_RNG_E;
    107 
    108     if (a == NULL)
    109         return BAD_FUNC_ARG;
     99    int ret = 0;
     100    DECLARE_VAR(d, mp_digit, 1, rng ? rng->heap : NULL);
     101
     102    if (rng == NULL) {
     103        ret = MISSING_RNG_E; goto exit;
     104    }
     105
     106    if (a == NULL
     107    #ifdef WOLFSSL_ASYNC_CRYPT
     108        || d == NULL
     109    #endif
     110    ) {
     111        ret = BAD_FUNC_ARG; goto exit;
     112    }
    110113
    111114    mp_zero(a);
    112115    if (digits <= 0) {
    113         return MP_OKAY;
     116        ret = MP_OKAY; goto exit;
    114117    }
    115118
    116119    /* first place a random non-zero digit */
    117120    do {
    118         ret = get_rand_digit(rng, &d);
     121        ret = get_rand_digit(rng, d);
    119122        if (ret != 0) {
    120             return ret;
    121         }
    122     } while (d == 0);
    123 
    124     if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
    125         return ret;
     123            goto exit;
     124        }
     125    } while (*d == 0);
     126
     127    if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) {
     128        goto exit;
    126129    }
    127130
    128131    while (--digits > 0) {
    129132        if ((ret = mp_lshd(a, 1)) != MP_OKAY) {
    130             return ret;
    131         }
    132         if ((ret = get_rand_digit(rng, &d)) != 0) {
    133             return ret;
    134         }
    135         if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
    136             return ret;
    137         }
    138     }
     133            goto exit;
     134        }
     135        if ((ret = get_rand_digit(rng, d)) != 0) {
     136            goto exit;
     137        }
     138        if ((ret = mp_add_d(a, *d, a)) != MP_OKAY) {
     139            goto exit;
     140        }
     141    }
     142
     143exit:
     144    FREE_VAR(d, rng ? rng->heap : NULL);
    139145
    140146    return ret;
    141147}
    142148#endif /* WC_RSA_BLINDING */
     149#endif
     150
     151/* export an mp_int as unsigned char or hex string
     152 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
     153 * return MP_OKAY on success */
     154int wc_export_int(mp_int* mp, byte* buf, word32* len, word32 keySz,
     155    int encType)
     156{
     157    int err;
     158
     159    if (mp == NULL)
     160        return BAD_FUNC_ARG;
     161
     162    /* check buffer size */
     163    if (*len < keySz) {
     164        *len = keySz;
     165        return BUFFER_E;
     166    }
     167
     168    *len = keySz;
     169    XMEMSET(buf, 0, *len);
     170
     171    if (encType == WC_TYPE_HEX_STR) {
     172    #ifdef WC_MP_TO_RADIX
     173        err = mp_tohex(mp, (char*)buf);
     174    #else
     175        err = NOT_COMPILED_IN;
     176    #endif
     177    }
     178    else {
     179        err = mp_to_unsigned_bin(mp, buf + (keySz - mp_unsigned_bin_size(mp)));
     180    }
     181
     182    return err;
     183}
    143184
    144185
     
    236277}
    237278
     279/* sz: make sure the buffer is at least that size and zero padded.
     280 *     A `sz == 0` will use the size of `src`.
     281 *     The calulcates sz is stored into dst->len in `wc_bigint_alloc`.
     282 */
     283int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz)
     284{
     285    int err;
     286    word32 x, y;
     287
     288    if (src == NULL || dst == NULL)
     289        return BAD_FUNC_ARG;
     290
     291    /* get size of source */
     292    x = mp_unsigned_bin_size(src);
     293    if (sz < x)
     294        sz = x;
     295
     296    /* make sure destination is allocated and large enough */
     297    err = wc_bigint_alloc(dst, sz);
     298    if (err == MP_OKAY) {
     299
     300        /* leading zero pad */
     301        y = sz - x;
     302        XMEMSET(dst->buf, 0, y);
     303
     304        /* export src as unsigned bin to destination buf */
     305        err = mp_to_unsigned_bin(src, dst->buf + y);
     306    }
     307
     308    return err;
     309}
     310
    238311int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst)
    239312{
    240     int err;
    241     word32 sz;
    242 
    243313    if (src == NULL || dst == NULL)
    244314        return BAD_FUNC_ARG;
    245315
    246     sz = mp_unsigned_bin_size(src);
    247     err = wc_bigint_alloc(dst, sz);
    248     if (err == MP_OKAY)
    249         err = mp_to_unsigned_bin(src, dst->buf);
    250 
    251     return err;
     316    return wc_mp_to_bigint_sz(src, dst, 0);
    252317}
    253318
Note: See TracChangeset for help on using the changeset viewer.