Index: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hmac.c
===================================================================
--- asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hmac.c	(revision 352)
+++ asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hmac.c	(revision 372)
@@ -1,3 +1,3 @@
-/* hmac.h
+/* hmac.c
  *
  * Copyright (C) 2006-2017 wolfSSL Inc.
@@ -30,4 +30,16 @@
 #ifndef NO_HMAC
 
+#if defined(HAVE_FIPS) && \
+    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
+
+    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
+    #define FIPS_NO_WRAPPERS
+
+    #ifdef USE_WINDOWS_API
+        #pragma code_seg(".fipsA$b")
+        #pragma const_seg(".fipsB$b")
+    #endif
+#endif
+
 #include <wolfssl/wolfcrypt/hmac.h>
 
@@ -41,5 +53,8 @@
 
 /* fips wrapper calls, user can call direct */
-#ifdef HAVE_FIPS
+/* If building for old FIPS. */
+#if defined(HAVE_FIPS) && \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
+
     /* does init */
     int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
@@ -47,5 +62,6 @@
         if (hmac == NULL || (key == NULL && keySz != 0) ||
            !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||
-                type == WC_SHA384 || type == WC_SHA512 || type == BLAKE2B_ID)) {
+                type == WC_SHA384 || type == WC_SHA512 ||
+                type == BLAKE2B_ID)) {
             return BAD_FUNC_ARG;
         }
@@ -101,8 +117,5 @@
     #endif /* HAVE_HKDF */
 
-#else /* else build without fips */
-
-
-#include <wolfssl/wolfcrypt/error-crypt.h>
+#else /* else build without fips, or for new fips */
 
 
@@ -111,6 +124,9 @@
     int ret;
 
-    if (!(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
-            type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
+    if (!(type == WC_MD5 || type == WC_SHA ||
+            type == WC_SHA224 || type == WC_SHA256 ||
+            type == WC_SHA384 || type == WC_SHA512 ||
+            type == WC_SHA3_224 || type == WC_SHA3_256 ||
+            type == WC_SHA3_384 || type == WC_SHA3_512 ||
             type == BLAKE2B_ID)) {
         return BAD_FUNC_ARG;
@@ -142,5 +158,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -148,4 +163,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             ret = WC_SHA512_DIGEST_SIZE;
@@ -159,4 +175,23 @@
     #endif /* HAVE_BLAKE2 */
 
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = WC_SHA3_224_DIGEST_SIZE;
+            break;
+
+        case WC_SHA3_256:
+            ret = WC_SHA3_256_DIGEST_SIZE;
+            break;
+
+        case WC_SHA3_384:
+            ret = WC_SHA3_384_DIGEST_SIZE;
+            break;
+
+        case WC_SHA3_512:
+            ret = WC_SHA3_512_DIGEST_SIZE;
+            break;
+
+    #endif
+
         default:
             ret = BAD_FUNC_ARG;
@@ -167,5 +202,5 @@
 }
 
-static int _InitHmac(Hmac* hmac, int type, void* heap)
+int _InitHmac(Hmac* hmac, int type, void* heap)
 {
     int ret = 0;
@@ -196,5 +231,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -202,4 +236,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             ret = wc_InitSha512(&hmac->hash.sha512);
@@ -212,4 +247,19 @@
             break;
     #endif /* HAVE_BLAKE2 */
+
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_256:
+            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_384:
+            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+        case WC_SHA3_512:
+            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
+            break;
+    #endif
 
         default:
@@ -238,29 +288,20 @@
 
     if (hmac == NULL || (key == NULL && length != 0) ||
-        !(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
-            type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
+       !(type == WC_MD5 || type == WC_SHA ||
+            type == WC_SHA224 || type == WC_SHA256 ||
+            type == WC_SHA384 || type == WC_SHA512 ||
+            type == WC_SHA3_224 || type == WC_SHA3_256 ||
+            type == WC_SHA3_384 || type == WC_SHA3_512 ||
             type == BLAKE2B_ID)) {
         return BAD_FUNC_ARG;
     }
 
+    /* if set key has already been run then make sure and free existing */
+    if (hmac->macType != 0) {
+        wc_HmacFree(hmac);
+        }
+
     hmac->innerHashKeyed = 0;
     hmac->macType = (byte)type;
-
-#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
-    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
-    #if defined(HAVE_CAVIUM)
-        if (length > HMAC_BLOCK_SIZE) {
-            return WC_KEY_SIZE_E;
-        }
-
-        if (key != NULL) {
-            XMEMCPY(hmac->ipad, key, length);
-        }
-        hmac->keyLen = (word16)length;
-
-        return 0; /* nothing to do here */
-    #endif /* HAVE_CAVIUM */
-    }
-#endif /* WOLFSSL_ASYNC_CRYPT */
 
     ret = _InitHmac(hmac, type, heap);
@@ -362,5 +403,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -383,4 +423,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             hmac_block_size = WC_SHA512_BLOCK_SIZE;
@@ -424,4 +465,79 @@
     #endif /* HAVE_BLAKE2 */
 
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
+            if (length <= WC_SHA3_224_BLOCK_SIZE) {
+                if (key != NULL) {
+                    XMEMCPY(ip, key, length);
+                }
+            }
+            else {
+                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
+                if (ret != 0)
+                    break;
+                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
+                if (ret != 0)
+                    break;
+
+                length = WC_SHA3_224_DIGEST_SIZE;
+            }
+            break;
+        case WC_SHA3_256:
+            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
+            if (length <= WC_SHA3_256_BLOCK_SIZE) {
+                if (key != NULL) {
+                    XMEMCPY(ip, key, length);
+                }
+            }
+            else {
+                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
+                if (ret != 0)
+                    break;
+                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
+                if (ret != 0)
+                    break;
+
+                length = WC_SHA3_256_DIGEST_SIZE;
+            }
+            break;
+        case WC_SHA3_384:
+            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
+            if (length <= WC_SHA3_384_BLOCK_SIZE) {
+                if (key != NULL) {
+                    XMEMCPY(ip, key, length);
+                }
+            }
+            else {
+                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
+                if (ret != 0)
+                    break;
+                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
+                if (ret != 0)
+                    break;
+
+                length = WC_SHA3_384_DIGEST_SIZE;
+            }
+            break;
+        case WC_SHA3_512:
+            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
+            if (length <= WC_SHA3_512_BLOCK_SIZE) {
+                if (key != NULL) {
+                    XMEMCPY(ip, key, length);
+                }
+            }
+            else {
+                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
+                if (ret != 0)
+                    break;
+                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
+                if (ret != 0)
+                    break;
+
+                length = WC_SHA3_512_DIGEST_SIZE;
+            }
+            break;
+    #endif /* WOLFSSL_SHA3 */
+
         default:
             return BAD_FUNC_ARG;
@@ -430,5 +546,9 @@
 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
     if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
-    #if defined(HAVE_INTEL_QA)
+    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
+        #ifdef HAVE_INTEL_QA
+        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
+        #endif
+        {
         if (length > hmac_block_size)
             length = hmac_block_size;
@@ -437,4 +557,5 @@
 
         return ret;
+        }
         /* no need to pad below */
     #endif
@@ -489,5 +610,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -496,4 +616,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,
@@ -508,4 +629,23 @@
             break;
     #endif /* HAVE_BLAKE2 */
+
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
+                                                       WC_SHA3_224_BLOCK_SIZE);
+            break;
+        case WC_SHA3_256:
+            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
+                                                       WC_SHA3_256_BLOCK_SIZE);
+            break;
+        case WC_SHA3_384:
+            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
+                                                       WC_SHA3_384_BLOCK_SIZE);
+            break;
+        case WC_SHA3_512:
+            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
+                                                       WC_SHA3_512_BLOCK_SIZE);
+            break;
+    #endif /* WOLFSSL_SHA3 */
 
         default:
@@ -533,6 +673,8 @@
         return NitroxHmacUpdate(hmac, msg, length);
     #elif defined(HAVE_INTEL_QA)
+        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
         return IntelQaHmac(&hmac->asyncDev, hmac->macType,
             (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
+        }
     #endif
     }
@@ -570,5 +712,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -576,4 +717,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
@@ -586,4 +728,19 @@
             break;
     #endif /* HAVE_BLAKE2 */
+
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
+            break;
+        case WC_SHA3_256:
+            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
+            break;
+        case WC_SHA3_384:
+            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
+            break;
+        case WC_SHA3_512:
+            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
+            break;
+    #endif /* WOLFSSL_SHA3 */
 
         default:
@@ -610,8 +767,10 @@
 
     #if defined(HAVE_CAVIUM)
-        return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen);
+        return NitroxHmacFinal(hmac, hash, hashLen);
     #elif defined(HAVE_INTEL_QA)
+        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
         return IntelQaHmac(&hmac->asyncDev, hmac->macType,
             (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
+        }
     #endif
     }
@@ -697,5 +856,4 @@
     #endif /* !NO_SHA256 */
 
-    #ifdef WOLFSSL_SHA512
     #ifdef WOLFSSL_SHA384
         case WC_SHA384:
@@ -714,4 +872,5 @@
             break;
     #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
         case WC_SHA512:
             ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
@@ -748,4 +907,63 @@
     #endif /* HAVE_BLAKE2 */
 
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
+                                                       WC_SHA3_224_BLOCK_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
+                                                          WC_SHA3_224_DIGEST_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
+            break;
+        case WC_SHA3_256:
+            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
+                                                       WC_SHA3_256_BLOCK_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
+                                                          WC_SHA3_256_DIGEST_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
+            break;
+        case WC_SHA3_384:
+            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
+                                                       WC_SHA3_384_BLOCK_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
+                                                          WC_SHA3_384_DIGEST_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
+            break;
+        case WC_SHA3_512:
+            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
+                                                       WC_SHA3_512_BLOCK_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
+                                                          WC_SHA3_512_DIGEST_SIZE);
+            if (ret != 0)
+                break;
+            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
+            break;
+    #endif /* WOLFSSL_SHA3 */
+
         default:
             ret = BAD_FUNC_ARG;
@@ -774,8 +992,4 @@
 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
     hmac->keyLen = 0;
-    #ifdef HAVE_CAVIUM
-        hmac->dataLen = 0;
-        hmac->data    = NULL;        /* buffered input data */
-    #endif /* HAVE_CAVIUM */
 
     ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
@@ -794,17 +1008,109 @@
         return;
 
+    switch (hmac->macType) {
+    #ifndef NO_MD5
+        case WC_MD5:
+            wc_Md5Free(&hmac->hash.md5);
+            break;
+    #endif /* !NO_MD5 */
+
+    #ifndef NO_SHA
+        case WC_SHA:
+            wc_ShaFree(&hmac->hash.sha);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifdef WOLFSSL_SHA224
+        case WC_SHA224:
+            wc_Sha224Free(&hmac->hash.sha224);
+            break;
+    #endif /* WOLFSSL_SHA224 */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            wc_Sha256Free(&hmac->hash.sha256);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            wc_Sha384Free(&hmac->hash.sha384);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+    #ifdef WOLFSSL_SHA512
+        case WC_SHA512:
+            wc_Sha512Free(&hmac->hash.sha512);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+
+    #ifdef HAVE_BLAKE2
+        case BLAKE2B_ID:
+            break;
+    #endif /* HAVE_BLAKE2 */
+
+    #ifdef WOLFSSL_SHA3
+        case WC_SHA3_224:
+            wc_Sha3_224_Free(&hmac->hash.sha3);
+            break;
+        case WC_SHA3_256:
+            wc_Sha3_256_Free(&hmac->hash.sha3);
+            break;
+        case WC_SHA3_384:
+            wc_Sha3_384_Free(&hmac->hash.sha3);
+            break;
+        case WC_SHA3_512:
+            wc_Sha3_512_Free(&hmac->hash.sha3);
+            break;
+    #endif /* WOLFSSL_SHA3 */
+
+        default:
+            break;
+    }
+
 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
     wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
-
-#ifdef HAVE_CAVIUM
-    XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC);
-    hmac->data = NULL;
-#endif /* HAVE_CAVIUM */
 #endif /* WOLFSSL_ASYNC_CRYPT */
+
+    switch (hmac->macType) {
+    #ifndef NO_MD5
+        case WC_MD5:
+            wc_Md5Free(&hmac->hash.md5);
+            break;
+    #endif /* !NO_MD5 */
+
+    #ifndef NO_SHA
+        case WC_SHA:
+            wc_ShaFree(&hmac->hash.sha);
+            break;
+    #endif /* !NO_SHA */
+
+    #ifdef WOLFSSL_SHA224
+        case WC_SHA224:
+            wc_Sha224Free(&hmac->hash.sha224);
+            break;
+    #endif /* WOLFSSL_SHA224 */
+
+    #ifndef NO_SHA256
+        case WC_SHA256:
+            wc_Sha256Free(&hmac->hash.sha256);
+            break;
+    #endif /* !NO_SHA256 */
+
+    #ifdef WOLFSSL_SHA512
+    #ifdef WOLFSSL_SHA384
+        case WC_SHA384:
+            wc_Sha384Free(&hmac->hash.sha384);
+            break;
+    #endif /* WOLFSSL_SHA384 */
+        case WC_SHA512:
+            wc_Sha512Free(&hmac->hash.sha512);
+            break;
+    #endif /* WOLFSSL_SHA512 */
+    }
 }
 
 int wolfSSL_GetHmacMaxSize(void)
 {
-    return MAX_DIGEST_SIZE;
+    return WC_MAX_DIGEST_SIZE;
 }
 
@@ -824,5 +1130,5 @@
                         const byte* inKey, word32 inKeySz, byte* out)
     {
-        byte   tmp[MAX_DIGEST_SIZE]; /* localSalt helper */
+        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
         Hmac   myHmac;
         int    ret;
@@ -869,5 +1175,5 @@
                        const byte* info, word32 infoSz, byte* out, word32 outSz)
     {
-        byte   tmp[MAX_DIGEST_SIZE];
+        byte   tmp[WC_MAX_DIGEST_SIZE];
         Hmac   myHmac;
         int    ret = 0;
@@ -930,5 +1236,5 @@
                        byte* out,         word32 outSz)
     {
-        byte   prk[MAX_DIGEST_SIZE];
+        byte   prk[WC_MAX_DIGEST_SIZE];
         int    hashSz = wc_HmacSizeByType(type);
         int    ret;
