Index: asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/pwdbased.c
===================================================================
--- asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/pwdbased.c	(revision 337)
+++ asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/pwdbased.c	(revision 372)
@@ -31,9 +31,7 @@
 #include <wolfssl/wolfcrypt/pwdbased.h>
 #include <wolfssl/wolfcrypt/hmac.h>
+#include <wolfssl/wolfcrypt/hash.h>
 #include <wolfssl/wolfcrypt/integer.h>
 #include <wolfssl/wolfcrypt/error-crypt.h>
-#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
-    #include <wolfssl/wolfcrypt/sha512.h>
-#endif
 
 #ifdef NO_INLINE
@@ -45,118 +43,125 @@
 
 
-#ifndef NO_SHA
-/* PBKDF1 needs at least SHA available */
+/* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */
+int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
+    const byte* passwd, int passwdLen, const byte* salt, int saltLen,
+    int iterations, int hashType, void* heap)
+{
+    int  err;
+    int  keyLeft, ivLeft, i;
+    int  digestLeft, store;
+    int  keyOutput = 0;
+    int  diestLen;
+    byte digest[WC_MAX_DIGEST_SIZE];
+#ifdef WOLFSSL_SMALL_STACK
+    wc_HashAlg* hash = NULL;
+#else
+    wc_HashAlg  hash[1];
+#endif
+    enum wc_HashType hashT;
+
+    (void)heap;
+
+    if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){
+        return BAD_FUNC_ARG;
+    }
+
+    if (iterations <= 0)
+        iterations = 1;
+
+    hashT = wc_HashTypeConvert(hashType);
+    err = wc_HashGetDigestSize(hashT);
+    if (err < 0)
+        return err;
+    diestLen = err;
+
+    /* initialize hash */
+#ifdef WOLFSSL_SMALL_STACK
+    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,
+                                DYNAMIC_TYPE_HASHCTX);
+    if (hash == NULL)
+        return MEMORY_E;
+#endif
+
+    err = wc_HashInit(hash, hashT);
+    if (err != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
+    #endif
+        return err;
+            }
+
+    keyLeft = keyLen;
+    ivLeft  = ivLen;
+    while (keyOutput < (keyLen + ivLen)) {
+        digestLeft = diestLen;
+        /* D_(i - 1) */
+        if (keyOutput) { /* first time D_0 is empty */
+            err = wc_HashUpdate(hash, hashT, digest, diestLen);
+            if (err != 0) break;
+            }
+
+        /* data */
+        err = wc_HashUpdate(hash, hashT, passwd, passwdLen);
+        if (err != 0) break;
+
+        /* salt */
+        if (salt) {
+            err = wc_HashUpdate(hash, hashT, salt, saltLen);
+            if (err != 0) break;
+    }
+
+        err = wc_HashFinal(hash, hashT, digest);
+        if (err != 0) break;
+
+        /* count */
+    for (i = 1; i < iterations; i++) {
+            err = wc_HashUpdate(hash, hashT, digest, diestLen);
+            if (err != 0) break;
+
+            err = wc_HashFinal(hash, hashT, digest);
+            if (err != 0) break;
+            }
+
+        if (keyLeft) {
+            store = min(keyLeft, diestLen);
+            XMEMCPY(&key[keyLen - keyLeft], digest, store);
+
+            keyOutput  += store;
+            keyLeft    -= store;
+            digestLeft -= store;
+            }
+
+        if (ivLeft && digestLeft) {
+            store = min(ivLeft, digestLeft);
+            if (iv != NULL)
+                XMEMCPY(&iv[ivLen - ivLeft],
+                        &digest[diestLen - digestLeft], store);
+            keyOutput += store;
+            ivLeft    -= store;
+        }
+    }
+
+    wc_HashFree(hash, hashT);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
+#endif
+
+    if (err != 0)
+        return err;
+
+    if (keyOutput != (keyLen + ivLen))
+        return BUFFER_E;
+
+    return err;
+    }
+
+/* PKCS#5 v1.5 */
 int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
            int sLen, int iterations, int kLen, int hashType)
 {
-    wc_Sha  sha;
-#ifndef NO_MD5
-    wc_Md5  md5;
-#endif
-    int  hLen = (int)WC_SHA_DIGEST_SIZE;
-    int  i, ret = 0;
-    byte buffer[WC_SHA_DIGEST_SIZE];  /* max size */
-
-    if (hashType != WC_MD5 && hashType != WC_SHA)
-        return BAD_FUNC_ARG;
-
-#ifndef NO_MD5
-    if (hashType == WC_MD5)
-        hLen = (int)WC_MD5_DIGEST_SIZE;
-#endif
-
-    if ((kLen > hLen) || (kLen < 0))
-        return BAD_FUNC_ARG;
-
-    if (iterations < 1)
-        return BAD_FUNC_ARG;
-
-    switch (hashType) {
-#ifndef NO_MD5
-        case WC_MD5:
-            ret = wc_InitMd5(&md5);
-            if (ret != 0) {
-                return ret;
-            }
-            ret = wc_Md5Update(&md5, passwd, pLen);
-            if (ret != 0) {
-                return ret;
-            }
-            ret = wc_Md5Update(&md5, salt,   sLen);
-            if (ret != 0) {
-                return ret;
-            }
-            ret = wc_Md5Final(&md5,  buffer);
-            if (ret != 0) {
-                return ret;
-            }
-            break;
-#endif /* NO_MD5 */
-        case WC_SHA:
-        default:
-            ret = wc_InitSha(&sha);
-            if (ret != 0)
-                return ret;
-            wc_ShaUpdate(&sha, passwd, pLen);
-            wc_ShaUpdate(&sha, salt,   sLen);
-            wc_ShaFinal(&sha,  buffer);
-            break;
-    }
-
-    for (i = 1; i < iterations; i++) {
-        if (hashType == WC_SHA) {
-            wc_ShaUpdate(&sha, buffer, hLen);
-            wc_ShaFinal(&sha,  buffer);
-        }
-#ifndef NO_MD5
-        else {
-            ret = wc_Md5Update(&md5, buffer, hLen);
-            if (ret != 0) {
-                return ret;
-            }
-            ret = wc_Md5Final(&md5,  buffer);
-            if (ret != 0) {
-                return ret;
-            }
-        }
-#endif
-    }
-    XMEMCPY(output, buffer, kLen);
-
-    return 0;
-}
-#endif /* NO_SHA */
-
-
-int GetDigestSize(int hashType)
-{
-    int hLen;
-
-    switch (hashType) {
-#ifndef NO_MD5
-        case WC_MD5:
-            hLen = WC_MD5_DIGEST_SIZE;
-            break;
-#endif
-#ifndef NO_SHA
-        case WC_SHA:
-            hLen = WC_SHA_DIGEST_SIZE;
-            break;
-#endif
-#ifndef NO_SHA256
-        case WC_SHA256:
-            hLen = WC_SHA256_DIGEST_SIZE;
-            break;
-#endif
-#ifdef WOLFSSL_SHA512
-        case WC_SHA512:
-            hLen = WC_SHA512_DIGEST_SIZE;
-            break;
-#endif
-        default:
-            return BAD_FUNC_ARG;
-    }
-
-    return hLen;
+    return wc_PBKDF1_ex(output, kLen, NULL, 0,
+        passwd, pLen, salt, sLen, iterations, hashType, NULL);
 }
 
@@ -168,29 +173,43 @@
     int    hLen;
     int    j, ret;
-    Hmac   hmac;
 #ifdef WOLFSSL_SMALL_STACK
     byte*  buffer;
-#else
-    byte   buffer[MAX_DIGEST_SIZE];
-#endif
-
-    hLen = GetDigestSize(hashType);
+    Hmac*  hmac;
+#else
+    byte   buffer[WC_MAX_DIGEST_SIZE];
+    Hmac   hmac[1];
+#endif
+    enum wc_HashType hashT;
+
+    if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (iterations <= 0)
+        iterations = 1;
+
+    hashT = wc_HashTypeConvert(hashType);
+    hLen = wc_HashGetDigestSize(hashT);
     if (hLen < 0)
         return BAD_FUNC_ARG;
 
 #ifdef WOLFSSL_SMALL_STACK
-    buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     if (buffer == NULL)
         return MEMORY_E;
-#endif
-
-    ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
+    hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_HMAC);
+    if (buffer == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
     if (ret == 0) {
-        ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen);
+        /* use int hashType here, since HMAC FIPS uses the old unique value */
+        ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);
 
         while (ret == 0 && kLen) {
             int currentLen;
 
-            ret = wc_HmacUpdate(&hmac, salt, sLen);
+            ret = wc_HmacUpdate(hmac, salt, sLen);
             if (ret != 0)
                 break;
@@ -200,5 +219,5 @@
                 byte b = (byte)(i >> ((3-j) * 8));
 
-                ret = wc_HmacUpdate(&hmac, &b, 1);
+                ret = wc_HmacUpdate(hmac, &b, 1);
                 if (ret != 0)
                     break;
@@ -209,5 +228,5 @@
                 break;
 
-            ret = wc_HmacFinal(&hmac, buffer);
+            ret = wc_HmacFinal(hmac, buffer);
             if (ret != 0)
                 break;
@@ -217,8 +236,8 @@
 
             for (j = 1; j < iterations; j++) {
-                ret = wc_HmacUpdate(&hmac, buffer, hLen);
+                ret = wc_HmacUpdate(hmac, buffer, hLen);
                 if (ret != 0)
                     break;
-                ret = wc_HmacFinal(&hmac, buffer);
+                ret = wc_HmacFinal(hmac, buffer);
                 if (ret != 0)
                     break;
@@ -234,9 +253,10 @@
             i++;
         }
-        wc_HmacFree(&hmac);
+        wc_HmacFree(hmac);
     }
 
 #ifdef WOLFSSL_SMALL_STACK
     XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(hmac, NULL, DYNAMIC_TYPE_HMAC);
 #endif
 
@@ -244,181 +264,56 @@
 }
 
-#ifdef WOLFSSL_SHA512
-    #define PBKDF_DIGEST_SIZE WC_SHA512_BLOCK_SIZE
-#elif !defined(NO_SHA256)
-    #define PBKDF_DIGEST_SIZE WC_SHA256_BLOCK_SIZE
-#else
-    #define PBKDF_DIGEST_SIZE WC_SHA_DIGEST_SIZE
-#endif
-
-/* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */
-int GetPKCS12HashSizes(int hashType, word32* v, word32* u)
-{
-    if (!v || !u)
-        return BAD_FUNC_ARG;
-
-    switch (hashType) {
-#ifndef NO_MD5
-        case WC_MD5:
-            *v = WC_MD5_BLOCK_SIZE;
-            *u = WC_MD5_DIGEST_SIZE;
-            break;
-#endif
-#ifndef NO_SHA
-        case WC_SHA:
-            *v = WC_SHA_BLOCK_SIZE;
-            *u = WC_SHA_DIGEST_SIZE;
-            break;
-#endif
-#ifndef NO_SHA256
-        case WC_SHA256:
-            *v = WC_SHA256_BLOCK_SIZE;
-            *u = WC_SHA256_DIGEST_SIZE;
-            break;
-#endif
-#ifdef WOLFSSL_SHA512
-        case WC_SHA512:
-            *v = WC_SHA512_BLOCK_SIZE;
-            *u = WC_SHA512_DIGEST_SIZE;
-            break;
-#endif
-        default:
-            return BAD_FUNC_ARG;
-    }
-
-    return 0;
-}
-
 /* helper for PKCS12_PBKDF(), does hash operation */
-int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
+static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
                  byte* Ai, word32 u, int iterations)
 {
     int i;
     int ret = 0;
-
-    if (buffer == NULL || Ai == NULL)
+#ifdef WOLFSSL_SMALL_STACK
+    wc_HashAlg* hash = NULL;
+#else
+    wc_HashAlg  hash[1];
+#endif
+    enum wc_HashType hashT;
+
+    if (buffer == NULL || Ai == NULL) {
         return BAD_FUNC_ARG;
-
-    switch (hashType) {
-#ifndef NO_MD5
-        case WC_MD5:
-            {
-                wc_Md5 md5;
-                ret = wc_InitMd5(&md5);
-                if (ret != 0) {
-                    break;
                 }
-                ret = wc_Md5Update(&md5, buffer, totalLen);
-                if (ret != 0) {
-                    break;
+
+    hashT = wc_HashTypeConvert(hashType);
+
+    /* initialize hash */
+#ifdef WOLFSSL_SMALL_STACK
+    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
+                                DYNAMIC_TYPE_HASHCTX);
+    if (hash == NULL)
+        return MEMORY_E;
+#endif
+
+    ret = wc_HashInit(hash, hashT);
+                    if (ret != 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
+    #endif
+        return ret;
+            }
+
+    ret = wc_HashUpdate(hash, hashT, buffer, totalLen);
+
+    if (ret == 0)
+        ret = wc_HashFinal(hash, hashT, Ai);
+
+                for (i = 1; i < iterations; i++) {
+        if (ret == 0)
+            ret = wc_HashUpdate(hash, hashT, Ai, u);
+        if (ret == 0)
+            ret = wc_HashFinal(hash, hashT, Ai);
                 }
-                ret = wc_Md5Final(&md5, Ai);
-                if (ret != 0) {
-                    break;
-                }
-
-                for (i = 1; i < iterations; i++) {
-                    ret = wc_Md5Update(&md5, Ai, u);
-                    if (ret != 0) {
-                        break;
-                    }
-                    ret = wc_Md5Final(&md5, Ai);
-                    if (ret != 0) {
-                        break;
-                    }
-                }
-            }
-            break;
-#endif /* NO_MD5 */
-#ifndef NO_SHA
-        case WC_SHA:
-            {
-                wc_Sha sha;
-                ret = wc_InitSha(&sha);
-                if (ret != 0)
-                    break;
-                ret = wc_ShaUpdate(&sha, buffer, totalLen);
-                if (ret != 0) {
-                    break;
-                }
-                ret = wc_ShaFinal(&sha, Ai);
-                if (ret != 0) {
-                    break;
-                }
-
-                for (i = 1; i < iterations; i++) {
-                    ret = wc_ShaUpdate(&sha, Ai, u);
-                    if (ret != 0) {
-                        break;
-                    }
-                    ret = wc_ShaFinal(&sha, Ai);
-                    if (ret != 0) {
-                        break;
-                    }
-                }
-            }
-            break;
-#endif /* NO_SHA */
-#ifndef NO_SHA256
-        case WC_SHA256:
-            {
-                wc_Sha256 sha256;
-                ret = wc_InitSha256(&sha256);
-                if (ret != 0)
-                    break;
-
-                ret = wc_Sha256Update(&sha256, buffer, totalLen);
-                if (ret != 0)
-                    break;
-
-                ret = wc_Sha256Final(&sha256, Ai);
-                if (ret != 0)
-                    break;
-
-                for (i = 1; i < iterations; i++) {
-                    ret = wc_Sha256Update(&sha256, Ai, u);
-                    if (ret != 0)
-                        break;
-
-                    ret = wc_Sha256Final(&sha256, Ai);
-                    if (ret != 0)
-                        break;
-                }
-            }
-            break;
-#endif /* NO_SHA256 */
-#ifdef WOLFSSL_SHA512
-        case WC_SHA512:
-            {
-                wc_Sha512 sha512;
-                ret = wc_InitSha512(&sha512);
-                if (ret != 0)
-                    break;
-
-                ret = wc_Sha512Update(&sha512, buffer, totalLen);
-                if (ret != 0)
-                    break;
-
-                ret = wc_Sha512Final(&sha512, Ai);
-                if (ret != 0)
-                    break;
-
-                for (i = 1; i < iterations; i++) {
-                    ret = wc_Sha512Update(&sha512, Ai, u);
-                    if (ret != 0)
-                        break;
-
-                    ret = wc_Sha512Final(&sha512, Ai);
-                    if (ret != 0)
-                        break;
-                }
-            }
-            break;
-#endif /* WOLFSSL_SHA512 */
-
-        default:
-            ret = BAD_FUNC_ARG;
-            break;
-    }
+
+    wc_HashFree(hash, hashT);
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
+#endif
 
     return ret;
@@ -426,6 +321,7 @@
 
 
-int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
-                 int saltLen, int iterations, int kLen, int hashType, int id)
+int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
+    const byte* salt, int saltLen, int iterations, int kLen, int hashType,
+    int id)
 {
     return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,
@@ -456,29 +352,43 @@
     byte*  B;
 #else
-    byte   Ai[PBKDF_DIGEST_SIZE];
-    byte   B[PBKDF_DIGEST_SIZE];
-#endif
-
-    if (!iterations)
+    byte   Ai[WC_MAX_DIGEST_SIZE];
+    byte   B[WC_MAX_BLOCK_SIZE];
+#endif
+    enum wc_HashType hashT;
+
+    (void)heap;
+
+    if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (iterations <= 0)
         iterations = 1;
 
-    ret = GetPKCS12HashSizes(hashType, &v, &u);
+    hashT = wc_HashTypeConvert(hashType);
+    ret = wc_HashGetDigestSize(hashT);
     if (ret < 0)
-        return BAD_FUNC_ARG;
-
-#ifdef WOLFSSL_SMALL_STACK
-    Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        return ret;
+    u = ret;
+
+    ret = wc_HashGetBlockSize(hashT);
+    if (ret < 0)
+        return ret;
+    v = ret;
+
+#ifdef WOLFSSL_SMALL_STACK
+    Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     if (Ai == NULL)
         return MEMORY_E;
 
-    B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
     if (B == NULL) {
-        XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
         return MEMORY_E;
     }
 #endif
 
-    XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE);
-    XMEMSET(B,  0, PBKDF_DIGEST_SIZE);
+    XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE);
+    XMEMSET(B,  0, WC_MAX_BLOCK_SIZE);
 
     dLen = v;
@@ -496,6 +406,6 @@
         if (buffer == NULL) {
 #ifdef WOLFSSL_SMALL_STACK
-            XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-            XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
+            XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);
 #endif
             return MEMORY_E;
@@ -584,6 +494,6 @@
 
 #ifdef WOLFSSL_SMALL_STACK
-    XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-    XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);
 #endif
 
@@ -740,5 +650,5 @@
 #else
         byte* t = x + (2*r - 1) * 64;
-        j = (t[0] | (t[1] << 8) | (t[2] << 16) | (t[3] << 24)) & (n-1);
+        j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1);
 #endif
 #ifdef WORD64_AVAILABLE
@@ -828,5 +738,5 @@
 #endif
 
-#undef PBKDF_DIGEST_SIZE
+#undef WC_MAX_DIGEST_SIZE
 
 #endif /* NO_PWDBASED */
