Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/bio.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/bio.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/bio.c	(revision 464)
@@ -160,20 +160,18 @@
 static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz)
 {
-    int ret = sz;
-
     if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
         if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf,
                         sz) != WOLFSSL_SUCCESS)
         {
-            ret = WOLFSSL_FATAL_ERROR;
+            return WOLFSSL_FATAL_ERROR;
         }
     }
     else {
-        if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, ret)
+        if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, sz)
                 != WOLFSSL_SUCCESS) {
-            ret = WOLFSSL_FATAL_ERROR;
-        }
-    }
-    return ret;
+            return WOLFSSL_FATAL_ERROR;
+        }
+    }
+    return sz;
 }
 #endif /* WOLFCRYPT_ONLY */
@@ -232,5 +230,11 @@
     #ifndef NO_FILESYSTEM
         if (bio && bio->type == WOLFSSL_BIO_FILE) {
-            ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
+            if (bio->ptr)
+                ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
+        #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\
+            && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
+            else
+                ret = (int)XREAD(bio->num, buf, len);
+        #endif
         }
     #endif
@@ -574,9 +578,9 @@
 
         /* write bios */
-        if (bio && bio->type == WOLFSSL_BIO_BIO) {
+        if (bio->type == WOLFSSL_BIO_BIO) {
             ret = wolfSSL_BIO_BIO_write(bio, data, len);
         }
 
-        if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
+        if (bio->type == WOLFSSL_BIO_MEMORY) {
             ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
         }
@@ -584,10 +588,16 @@
     #ifndef NO_FILESYSTEM
         if (bio && bio->type == WOLFSSL_BIO_FILE) {
-            ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
+            if (bio->ptr)
+                ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
+        #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\
+            && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
+            else
+                ret = (int)XWRITE(bio->num, data, len);
+        #endif
         }
     #endif
 
     #ifndef WOLFCRYPT_ONLY
-        if (bio && bio->type == WOLFSSL_BIO_SSL) {
+        if (bio->type == WOLFSSL_BIO_SSL) {
             /* already got eof, again is error */
             if (front->eof) {
@@ -599,5 +609,5 @@
         }
 
-        if (bio && bio->type == WOLFSSL_BIO_MD) {
+        if (bio->type == WOLFSSL_BIO_MD) {
             if (bio->next != NULL) { /* data passing through MD BIO */
                 ret = wolfSSL_BIO_MD_write(bio, data, len);
@@ -608,8 +618,4 @@
         /* advance to the next bio in list */
         bio = bio->next;
-    }
-
-    if (frmt != NULL) {
-        XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
     }
 
@@ -619,4 +625,8 @@
                                  WOLFSSL_BIO_CB_WRITE | WOLFSSL_BIO_CB_RETURN,
                                  (const char*)data, 0, 0, ret);
+    }
+
+    if (frmt != NULL) {
+        XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
     }
 
@@ -943,9 +953,11 @@
     }
 
-    if (bio->type == WOLFSSL_BIO_MD) {
-        /* MD is a wrapper only get next bio */
+    if (bio->type == WOLFSSL_BIO_MD ||
+            bio->type == WOLFSSL_BIO_BASE64) {
+        /* these are wrappers only, get next bio */
         while (bio->next != NULL) {
             bio = bio->next;
-            if (bio->type != WOLFSSL_BIO_MD) {
+            if (bio->type == WOLFSSL_BIO_MD ||
+                    bio->type == WOLFSSL_BIO_BASE64) {
                 break;
             }
@@ -1308,4 +1320,5 @@
                 const WOLFSSL_EVP_MD* md =
                     wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr);
+                wolfSSL_EVP_MD_CTX_cleanup((WOLFSSL_EVP_MD_CTX*)bio->ptr);
                 wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr);
                 wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md);
@@ -1322,4 +1335,29 @@
 
 #ifndef NO_FILESYSTEM
+/**
+ * Creates a new file BIO object
+ * @param fd file descriptor for to use for the new object
+ * @param close_flag BIO_NOCLOSE or BIO_CLOSE
+ * @return New BIO object or NULL on failure
+ */
+WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag)
+{
+    WOLFSSL_BIO* bio;
+
+    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
+    if (!bio) {
+        WOLFSSL_MSG("wolfSSL_BIO_new error");
+        return NULL;
+    }
+
+    if (wolfSSL_BIO_set_fd(bio, fd, close_flag) != WOLFSSL_SUCCESS) {
+        wolfSSL_BIO_free(bio);
+        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
+        return NULL;
+    }
+
+    return bio;
+}
+
 long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
 {
@@ -1528,4 +1566,5 @@
 long wolfSSL_BIO_set_nbio(WOLFSSL_BIO* bio, long on)
 {
+    int ret = 0;
     #ifndef WOLFSSL_DTLS
     (void)on;
@@ -1539,7 +1578,7 @@
                 int flag = XFCNTL(bio->num, F_GETFL, 0);
                 if (on)
-                    XFCNTL(bio->num, F_SETFL, flag | O_NONBLOCK);
+                    ret = XFCNTL(bio->num, F_SETFL, flag | O_NONBLOCK);
                 else
-                    XFCNTL(bio->num, F_SETFL, flag & ~O_NONBLOCK);
+                    ret = XFCNTL(bio->num, F_SETFL, flag & ~O_NONBLOCK);
             }
         #endif
@@ -1555,6 +1594,8 @@
             break;
     }
-
-    return 1;
+    if (ret != -1)
+        return 1;
+    else
+        return 0;
 }
 
@@ -1678,4 +1719,5 @@
 int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
 {
+    WOLFSSL_BIO* mem_bio;
     WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
 
@@ -1683,9 +1725,17 @@
         return WOLFSSL_FATAL_ERROR;
 
+    mem_bio = bio;
+    /* Return pointer from last memory BIO in chain */
+    while (bio->next) {
+        bio = bio->next;
+        if (bio->type == WOLFSSL_BIO_MEMORY)
+            mem_bio = bio;
+    }
+
     if (p) {
-        *(byte**)p = (byte*)bio->ptr;
-    }
-
-    return bio->num;
+        *(byte**)p = (byte*)mem_bio->ptr;
+    }
+
+    return mem_bio->num;
 }
 
