Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfssl/test.h
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfssl/test.h	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfssl/test.h	(revision 464)
@@ -4,6 +4,11 @@
 #define wolfSSL_TEST_H
 
-#include <stdio.h>
-#include <stdlib.h>
+#ifdef FUSION_RTOS
+    #include <fclstdio.h>
+    #include <fclstdlib.h>
+#else
+    #include <stdio.h>
+    #include <stdlib.h>
+#endif
 #include <assert.h>
 #include <ctype.h>
@@ -56,4 +61,5 @@
     #define SOCKET_T SOCKET
     #define SNPRINTF _snprintf
+    #define XSLEEP_MS(t) Sleep(t)
 #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
     #include <string.h>
@@ -70,7 +76,7 @@
     }
     #if defined(HAVE_KEIL_RTX)
-        #define sleep(t) os_dly_wait(t/1000+1);
+        #define XSLEEP_MS(t)  os_dly_wait(t)
     #elif defined(WOLFSSL_CMSIS_RTOS) || defined(WOLFSSL_CMSIS_RTOSv2)
-        #define sleep(t) osDelay(t/1000+1);
+        #define XSLEEP_MS(t)  osDelay(t)
     #endif
 #elif defined(WOLFSSL_TIRTOS)
@@ -89,4 +95,5 @@
     };
     #define SOCKET_T int
+    #define XSLEEP_MS(t) Task_sleep(t/1000)
 #elif defined(WOLFSSL_VXWORKS)
     #include <hostLib.h>
@@ -144,4 +151,7 @@
     #endif
 #endif
+    #ifdef FREESCALE_MQX
+        typedef int socklen_t ;
+    #endif
     #define SOCKET_T int
     #ifndef SO_NOSIGPIPE
@@ -149,5 +159,16 @@
     #endif
     #define SNPRINTF snprintf
+
+    #define XSELECT_WAIT(x,y) do { \
+        struct timeval tv = {(x),(y)}; \
+        select(0, NULL, NULL, NULL, &tv); \
+    } while (0)
+    #define XSLEEP_US(u) XSELECT_WAIT(0,u)
+    #define XSLEEP_MS(m) XSELECT_WAIT(0,(m)*1000)
 #endif /* USE_WINDOWS_API */
+
+#ifndef XSLEEP_MS
+    #define XSLEEP_MS(t) sleep(t/1000)
+#endif
 
 #ifdef WOLFSSL_ASYNC_CRYPT
@@ -231,5 +252,5 @@
         #define INFINITE -1
         #define WAIT_OBJECT_0 0L
-    #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
+    #elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET) || defined(FREESCALE_MQX)
         typedef unsigned int  THREAD_RETURN;
         typedef int           THREAD_TYPE;
@@ -287,10 +308,14 @@
     #define DEFAULT_MIN_RSAKEY_BITS 2048
 #else
+    #ifndef DEFAULT_MIN_RSAKEY_BITS
     #define DEFAULT_MIN_RSAKEY_BITS 1024
+    #endif
 #endif
 #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
     #define DEFAULT_MIN_ECCKEY_BITS 256
 #else
+    #ifndef DEFAULT_MIN_ECCKEY_BITS
     #define DEFAULT_MIN_ECCKEY_BITS 224
+    #endif
 #endif
 
@@ -410,4 +435,5 @@
     ssl_callback on_result;
     WOLFSSL_CTX* ctx;
+    unsigned char isSharedCtx:1;
 } callback_functions;
 
@@ -472,6 +498,4 @@
 err_sys(const char* msg)
 {
-    printf("wolfSSL error: %s\n", msg);
-
 #if !defined(__GNUC__)
     /* scan-build (which pretends to be gnuc) can get confused and think the
@@ -484,4 +508,34 @@
 #endif
     {
+        printf("wolfSSL error: %s\n", msg);
+
+        XEXIT_T(EXIT_FAILURE);
+    }
+}
+
+static WC_INLINE
+#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR)
+THREAD_RETURN
+#else
+WC_NORETURN void
+#endif
+err_sys_with_errno(const char* msg)
+{
+#if !defined(__GNUC__)
+    /* scan-build (which pretends to be gnuc) can get confused and think the
+     * msg pointer can be null even when hardcoded and then it won't exit,
+     * making null pointer checks above the err_sys() call useless.
+     * We could just always exit() but some compilers will complain about no
+     * possible return, with gcc we know the attribute to handle that with
+     * WC_NORETURN. */
+    if (msg)
+#endif
+    {
+#if defined(HAVE_STRING_H) && defined(HAVE_ERRNO_H)
+        printf("wolfSSL error: %s: %s\n", msg, strerror(errno));
+#else
+        printf("wolfSSL error: %s\n", msg);
+#endif
+
         XEXIT_T(EXIT_FAILURE);
     }
@@ -492,4 +546,15 @@
 extern char* myoptarg;
 
+/**
+ *
+ * @param argc Number of argv strings
+ * @param argv Array of string arguments
+ * @param optstring String containing the supported alphanumeric arguments.
+ *                  A ':' following a character means that it requires a
+ *                  value in myoptarg to be set. A ';' means that the
+ *                  myoptarg is optional. myoptarg is set to "" if not
+ *                  present.
+ * @return Option letter in argument
+ */
 static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
 {
@@ -541,5 +606,5 @@
     cp = (char*)strchr(optstring, c);
 
-    if (cp == NULL || c == ':')
+    if (cp == NULL || c == ':' || c == ';')
         return '?';
 
@@ -557,4 +622,18 @@
         else
             return '?';
+    }
+    else if (*cp == ';') {
+        myoptarg = (char*)"";
+        if (*next != '\0') {
+            myoptarg = next;
+            next     = NULL;
+        }
+        else if (myoptind < argc) {
+            /* Check if next argument is not a parameter argument */
+            if (argv[myoptind] && argv[myoptind][0] != '-') {
+                myoptarg = argv[myoptind];
+                myoptind++;
+            }
+        }
     }
 
@@ -935,5 +1014,5 @@
 
     if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
-        err_sys("socket failed\n");
+        err_sys_with_errno("socket failed\n");
     }
 
@@ -945,5 +1024,5 @@
         int       res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
         if (res < 0)
-            err_sys("setsockopt SO_NOSIGPIPE failed\n");
+            err_sys_with_errno("setsockopt SO_NOSIGPIPE failed\n");
     }
 #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\
@@ -961,5 +1040,5 @@
         int       res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
         if (res < 0)
-            err_sys("setsockopt TCP_NODELAY failed\n");
+            err_sys_with_errno("setsockopt TCP_NODELAY failed\n");
     }
 #endif
@@ -979,5 +1058,5 @@
     if (!udp) {
         if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
-            err_sys("tcp connect failed");
+            err_sys_with_errno("tcp connect failed");
     }
 }
@@ -987,5 +1066,5 @@
 {
     if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0)
-        err_sys("tcp connect failed");
+        err_sys_with_errno("tcp connect failed");
 }
 
@@ -1085,10 +1164,19 @@
         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
         if (res < 0)
-            err_sys("setsockopt SO_REUSEADDR failed\n");
-    }
+            err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
+    }
+#ifdef SO_REUSEPORT
+    {
+        int       res, on  = 1;
+        socklen_t len = sizeof(on);
+        res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
+        if (res < 0)
+            err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
+    }
+#endif
 #endif
 
     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
-        err_sys("tcp bind failed");
+        err_sys_with_errno("tcp bind failed");
     if (!udp) {
         #ifdef WOLFSSL_KEIL_TCP_NET
@@ -1098,5 +1186,5 @@
         #endif
         if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0)
-                err_sys("tcp listen failed");
+                err_sys_with_errno("tcp listen failed");
     }
     #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \
@@ -1155,10 +1243,19 @@
         res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
         if (res < 0)
-            err_sys("setsockopt SO_REUSEADDR failed\n");
-    }
+            err_sys_with_errno("setsockopt SO_REUSEADDR failed\n");
+    }
+#ifdef SO_REUSEPORT
+    {
+        int       res, on  = 1;
+        socklen_t len = sizeof(on);
+        res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len);
+        if (res < 0)
+            err_sys_with_errno("setsockopt SO_REUSEPORT failed\n");
+    }
+#endif
 #endif
 
     if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
-        err_sys("tcp bind failed");
+        err_sys_with_errno("tcp bind failed");
 
     #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS)
@@ -1201,6 +1298,6 @@
                               int udp, int sctp, int ready_file, int do_listen)
 {
-    SOCKADDR_IN_T client;
-    socklen_t client_len = sizeof(client);
+    SOCKADDR_IN_T client_addr;
+    socklen_t client_len = sizeof(client_addr);
     tcp_ready* ready = NULL;
 
@@ -1259,8 +1356,8 @@
     }
 
-    *clientfd = accept(*sockfd, (struct sockaddr*)&client,
+    *clientfd = accept(*sockfd, (struct sockaddr*)&client_addr,
                       (ACCEPT_THIRD_T)&client_len);
     if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
-        err_sys("tcp accept failed");
+        err_sys_with_errno("tcp accept failed");
     }
 }
@@ -1273,5 +1370,5 @@
         int ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
         if (ret == SOCKET_ERROR)
-            err_sys("ioctlsocket failed");
+            err_sys_with_errno("ioctlsocket failed");
     #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \
         || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \
@@ -1281,8 +1378,8 @@
         int flags = fcntl(*sockfd, F_GETFL, 0);
         if (flags < 0)
-            err_sys("fcntl get failed");
+            err_sys_with_errno("fcntl get failed");
         flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
         if (flags < 0)
-            err_sys("fcntl set failed");
+            err_sys_with_errno("fcntl set failed");
     #endif
 }
@@ -1303,5 +1400,5 @@
 
     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
-    strncpy(identity, kIdentityStr, id_max_len);
+    XSTRNCPY(identity, kIdentityStr, id_max_len);
 
     if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
@@ -1337,5 +1434,5 @@
 
     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
-    if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
+    if (XSTRNCMP(identity, kIdentityStr, XSTRLEN(kIdentityStr)) != 0)
         return 0;
 
@@ -1371,4 +1468,5 @@
     int i;
     int b = 0x01;
+    const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
 
     (void)ssl;
@@ -1377,5 +1475,5 @@
 
     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
-    strncpy(identity, kIdentityStr, id_max_len);
+    XSTRNCPY(identity, kIdentityStr, id_max_len);
 
     for (i = 0; i < 32; i++, b += 0x22) {
@@ -1385,5 +1483,5 @@
     }
 
-    *ciphersuite = "TLS13-AES128-GCM-SHA256";
+    *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
 
     return 32;   /* length of key in octets or 0 for error */
@@ -1397,4 +1495,5 @@
     int i;
     int b = 0x01;
+    const char* userCipher = (const char*)wolfSSL_get_psk_callback_ctx(ssl);
 
     (void)ssl;
@@ -1402,5 +1501,5 @@
 
     /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
-    if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0)
+    if (XSTRNCMP(identity, kIdentityStr, XSTRLEN(kIdentityStr)) != 0)
         return 0;
 
@@ -1411,10 +1510,10 @@
     }
 
-    *ciphersuite = "TLS13-AES128-GCM-SHA256";
+    *ciphersuite = userCipher ? userCipher : "TLS13-AES128-GCM-SHA256";
 
     return 32;   /* length of key in octets or 0 for error */
 }
 
-#endif /* NO_PSK */
+#endif /* !NO_PSK */
 
 
@@ -1499,6 +1598,5 @@
 static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
 {
-    (void)ioCtx;
-    (void)response;
+    return EmbedOcspRespFree(ioCtx, response);
 }
 #endif
@@ -1513,5 +1611,5 @@
         int ret;
         long int fileSz;
-        XFILE file;
+        XFILE lFile;
 
         if (fname == NULL || buf == NULL || bufLen == NULL)
@@ -1523,13 +1621,13 @@
 
         /* open file (read-only binary) */
-        file = XFOPEN(fname, "rb");
-        if (!file) {
+        lFile = XFOPEN(fname, "rb");
+        if (!lFile) {
             printf("Error loading %s\n", fname);
             return BAD_PATH_ERROR;
         }
 
-        fseek(file, 0, SEEK_END);
-        fileSz = (int)ftell(file);
-        rewind(file);
+        fseek(lFile, 0, SEEK_END);
+        fileSz = (int)ftell(lFile);
+        rewind(lFile);
         if (fileSz  > 0) {
             *bufLen = (size_t)fileSz;
@@ -1540,5 +1638,5 @@
             }
             else {
-                size_t readLen = fread(*buf, *bufLen, 1, file);
+                size_t readLen = fread(*buf, *bufLen, 1, lFile);
 
                 /* check response code */
@@ -1549,5 +1647,5 @@
             ret = BUFFER_E;
         }
-        fclose(file);
+        fclose(lFile);
 
         return ret;
@@ -1676,5 +1774,11 @@
 #endif /* !NO_CERTS */
 
-static int myVerifyFail = 0;
+enum {
+    VERIFY_OVERRIDE_ERROR,
+    VERIFY_FORCE_FAIL,
+    VERIFY_USE_PREVERFIY,
+    VERIFY_OVERRIDE_DATE_ERR,
+};
+static THREAD_LS_T int myVerifyAction = VERIFY_OVERRIDE_ERROR;
 
 /* The verify callback is called for every certificate only when
@@ -1728,5 +1832,5 @@
         XFREE(issuer,  0, DYNAMIC_TYPE_OPENSSL);
 #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM)
-/* avoid printing duplicate certs */
+        /* avoid printing duplicate certs */
         if (store->depth == 1) {
             /* retrieve x509 certs and display them on stdout */
@@ -1763,10 +1867,16 @@
 
     /* Testing forced fail case by return zero */
-    if (myVerifyFail) {
+    if (myVerifyAction == VERIFY_FORCE_FAIL) {
         return 0; /* test failure case */
     }
 
+    if (myVerifyAction == VERIFY_OVERRIDE_DATE_ERR && 
+        (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E)) {
+        printf("Overriding cert date error as example for bad clock testing\n");
+        return 1;
+    }
+
     /* If error indicate we are overriding it for testing purposes */
-    if (store->error != 0) {
+    if (store->error != 0 && myVerifyAction == VERIFY_OVERRIDE_ERROR) {
         printf("\tAllowing failed certificate check, testing only "
             "(shouldn't do this in production)\n");
@@ -1774,24 +1884,5 @@
 
     /* A non-zero return code indicates failure override */
-    return 1;
-}
-
-
-static WC_INLINE int myDateCb(int preverify, WOLFSSL_X509_STORE_CTX* store)
-{
-    char buffer[WOLFSSL_MAX_ERROR_SZ];
-    (void)preverify;
-
-    printf("In verification callback, error = %d, %s\n", store->error,
-                                 wolfSSL_ERR_error_string(store->error, buffer));
-    printf("Subject's domain name is %s\n", store->domain);
-
-    if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
-        printf("Overriding cert date error as example for bad clock testing\n");
-        return 1;
-    }
-    printf("Cert error is not date error, not overriding\n");
-
-    return 0;
+    return (myVerifyAction == VERIFY_OVERRIDE_ERROR) ? 1 : preverify;
 }
 
@@ -1917,9 +2008,9 @@
         #if !defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)
             int depth, res;
-            XFILE file;
+            XFILE keyFile;
             for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
-                file = XFOPEN(ntruKeyFile, "rb");
-                if (file != NULL) {
-                    fclose(file);
+                keyFile = XFOPEN(ntruKeyFile, "rb");
+                if (keyFile != NULL) {
+                    fclose(keyFile);
                     return depth;
                 }
@@ -1948,12 +2039,133 @@
 #define STACK_CHECK_VAL 0x01
 
+struct stack_size_debug_context {
+  unsigned char *myStack;
+  size_t stackSize;
+#ifdef HAVE_STACK_SIZE_VERBOSE
+  size_t *stackSizeHWM_ptr;
+  thread_func fn;
+  void *args;
+#endif
+};
+
+#ifdef HAVE_STACK_SIZE_VERBOSE
+
+/* per-subtest stack high water mark tracking.
+ *
+ * enable with
+ *
+ * ./configure --enable-stacksize=verbose [...]
+ */
+
+static THREAD_RETURN debug_stack_size_verbose_shim(struct stack_size_debug_context *shim_args) {
+  StackSizeCheck_myStack = shim_args->myStack;
+  StackSizeCheck_stackSize = shim_args->stackSize;
+  StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr;
+  return shim_args->fn(shim_args->args);
+}
+
+static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p)
+{
+    if (StackSizeCheck_myStack == NULL)
+        return -BAD_FUNC_ARG;
+
+    StackSizeCheck_stackOffsetPointer = p;
+
+    printf("setting stack relative offset reference mark in %s to +%lu\n",
+        funcname, (unsigned long)((char*)(StackSizeCheck_myStack +
+                                  StackSizeCheck_stackSize) - (char *)p));
+
+    return 0;
+}
+
+static WC_INLINE ssize_t StackSizeHWM(void)
+{
+    size_t i;
+    ssize_t used;
+
+    if (StackSizeCheck_myStack == NULL)
+        return -BAD_FUNC_ARG;
+
+    for (i = 0; i < StackSizeCheck_stackSize; i++) {
+        if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) {
+            break;
+        }
+    }
+
+    used = StackSizeCheck_stackSize - i;
+    if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used)
+      *StackSizeCheck_stackSizeHWM_ptr = used;
+
+    return used;
+}
+
+static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
+{
+    ssize_t used = StackSizeHWM();
+    if (used < 0)
+        return used;
+    if (StackSizeCheck_stackOffsetPointer)
+        used -= (ssize_t)(((char *)StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)StackSizeCheck_stackOffsetPointer);
+    return used;
+}
+
+static
+#ifdef __GNUC__
+__attribute__((unused)) __attribute__((noinline))
+#endif
+int StackSizeHWMReset(void)
+{
+    volatile ssize_t i;
+
+    if (StackSizeCheck_myStack == NULL)
+        return -BAD_FUNC_ARG;
+
+    for (i = (ssize_t)((char *)&i - (char *)StackSizeCheck_myStack) - (ssize_t)sizeof i - 1; i >= 0; --i)
+    {
+        StackSizeCheck_myStack[i] = STACK_CHECK_VAL;
+    }
+
+    return 0;
+}
+
+#define STACK_SIZE_CHECKPOINT(...) ({  \
+    ssize_t HWM = StackSizeHWM_OffsetCorrected();    \
+    __VA_ARGS__;                                     \
+    printf("    relative stack peak usage = %ld bytes\n", HWM);  \
+    StackSizeHWMReset();                             \
+    })
+
+#define STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max, ...) ({  \
+    ssize_t HWM = StackSizeHWM_OffsetCorrected();    \
+    int _ret;                                        \
+    __VA_ARGS__;                                     \
+    printf("    relative stack peak usage = %ld bytes\n", HWM);  \
+    _ret = StackSizeHWMReset();                      \
+    if ((max >= 0) && (HWM > (ssize_t)(max))) {      \
+        printf("    relative stack usage at %s L%d exceeds designated max %ld bytes.\n", __FILE__, __LINE__, (ssize_t)(max)); \
+        _ret = -1;                                   \
+    }                                                \
+    _ret;                                            \
+    })
+
+
+#ifdef __GNUC__
+#define STACK_SIZE_INIT() (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0))
+#endif
+
+#endif /* HAVE_STACK_SIZE_VERBOSE */
+
 static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
 {
-    int            ret, i, used;
+    size_t         i;
+    int            ret;
     void*          status;
     unsigned char* myStack = NULL;
-    int            stackSize = 1024*152;
+    size_t         stackSize = 1024*1024;
     pthread_attr_t myAttr;
     pthread_t      threadId;
+#ifdef HAVE_STACK_SIZE_VERBOSE
+    struct stack_size_debug_context shim_args;
+#endif
 
 #ifdef PTHREAD_STACK_MIN
@@ -1964,5 +2176,5 @@
     ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
     if (ret != 0 || myStack == NULL)
-        err_sys("posix_memalign failed\n");
+        err_sys_with_errno("posix_memalign failed\n");
 
     XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
@@ -1976,5 +2188,15 @@
         err_sys("attr_setstackaddr failed");
 
+#ifdef HAVE_STACK_SIZE_VERBOSE
+    StackSizeCheck_stackSizeHWM = 0;
+    shim_args.myStack = myStack;
+    shim_args.stackSize = stackSize;
+    shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
+    shim_args.fn = tf;
+    shim_args.args = args;
+    ret = pthread_create(&threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args);
+#else
     ret = pthread_create(&threadId, &myAttr, tf, args);
+#endif
     if (ret != 0) {
         perror("pthread_create failed");
@@ -1993,14 +2215,111 @@
 
     free(myStack);
-
-    used = stackSize - i;
-    printf("stack used = %d\n", used);
+#ifdef HAVE_STACK_SIZE_VERBOSE
+    printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM > (stackSize - i)
+        ? (unsigned long)StackSizeCheck_stackSizeHWM
+        : (unsigned long)(stackSize - i));
+#else
+    {
+      size_t used = stackSize - i;
+      printf("stack used = %lu\n", (unsigned long)used);
+    }
+#endif
 
     return (int)((size_t)status);
 }
 
+static WC_INLINE int StackSizeCheck_launch(func_args* args, thread_func tf, pthread_t *threadId, void **stack_context)
+{
+    int ret;
+    unsigned char* myStack = NULL;
+    size_t stackSize = 1024*1024;
+    pthread_attr_t myAttr;
+
+#ifdef PTHREAD_STACK_MIN
+    if (stackSize < PTHREAD_STACK_MIN)
+        stackSize = PTHREAD_STACK_MIN;
+#endif
+
+    struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)malloc(sizeof *shim_args);
+    if (! shim_args) {
+        perror("malloc");
+        exit(EXIT_FAILURE);
+    }
+
+    ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
+    if (ret != 0 || myStack == NULL)
+        err_sys_with_errno("posix_memalign failed\n");
+
+    XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
+
+    ret = pthread_attr_init(&myAttr);
+    if (ret != 0)
+        err_sys("attr_init failed");
+
+    ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
+    if (ret != 0)
+        err_sys("attr_setstackaddr failed");
+
+    shim_args->myStack = myStack;
+    shim_args->stackSize = stackSize;
+#ifdef HAVE_STACK_SIZE_VERBOSE
+    shim_args->stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
+    shim_args->fn = tf;
+    shim_args->args = args;
+    ret = pthread_create(threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)shim_args);
+#else
+    ret = pthread_create(threadId, &myAttr, tf, args);
+#endif
+    if (ret != 0) {
+        fprintf(stderr,"pthread_create failed: %s",strerror(ret));
+        exit(EXIT_FAILURE);
+    }
+
+    *stack_context = (void *)shim_args;
+
+    return 0;
+}
+
+static WC_INLINE int StackSizeCheck_reap(pthread_t threadId, void *stack_context)
+{
+    struct stack_size_debug_context *shim_args = (struct stack_size_debug_context *)stack_context;
+    size_t i;
+    void *status;
+    int ret = pthread_join(threadId, &status);
+    if (ret != 0)
+        err_sys("pthread_join failed");
+
+    for (i = 0; i < shim_args->stackSize; i++) {
+        if (shim_args->myStack[i] != STACK_CHECK_VAL) {
+            break;
+        }
+    }
+
+    free(shim_args->myStack);
+#ifdef HAVE_STACK_SIZE_VERBOSE
+    printf("stack used = %lu\n",
+        *shim_args->stackSizeHWM_ptr > (shim_args->stackSize - i)
+        ? (unsigned long)*shim_args->stackSizeHWM_ptr
+        : (unsigned long)(shim_args->stackSize - i));
+#else
+    {
+      size_t used = shim_args->stackSize - i;
+      printf("stack used = %lu\n", (unsigned long)used);
+    }
+#endif
+    free(shim_args);
+
+    return (int)((size_t)status);
+}
+
 
 #endif /* HAVE_STACK_SIZE */
 
+#ifndef STACK_SIZE_CHECKPOINT
+#define STACK_SIZE_CHECKPOINT(...) (__VA_ARGS__)
+#endif
+#ifndef STACK_SIZE_INIT
+#define STACK_SIZE_INIT()
+#endif
 
 #ifdef STACK_TRAP
@@ -2021,11 +2340,9 @@
     struct rlimit  rl;
     if (getrlimit(RLIMIT_STACK, &rl) != 0)
-        err_sys("getrlimit failed");
+        err_sys_with_errno("getrlimit failed");
     printf("rlim_cur = %llu\n", rl.rlim_cur);
     rl.rlim_cur = 1024*21;  /* adjust trap size here */
-    if (setrlimit(RLIMIT_STACK, &rl) != 0) {
-        perror("setrlimit");
-        err_sys("setrlimit failed");
-    }
+    if (setrlimit(RLIMIT_STACK, &rl) != 0)
+        err_sys_with_errno("setrlimit failed");
 }
 
@@ -2390,5 +2707,5 @@
     encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
     if (encCtx == NULL)
-        err_sys("AtomicEncCtx malloc failed");
+        err_sys_with_errno("AtomicEncCtx malloc failed");
     XMEMSET(encCtx, 0, sizeof(AtomicEncCtx));
 
@@ -2396,5 +2713,5 @@
     if (decCtx == NULL) {
         free(encCtx);
-        err_sys("AtomicDecCtx malloc failed");
+        err_sys_with_errno("AtomicDecCtx malloc failed");
     }
     XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));
@@ -2665,4 +2982,11 @@
     }
 
+#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_FIPS) && \
+                                                         !defined(HAVE_SELFTEST)
+    if (ret == 0) {
+        ret = wc_ecc_set_rng(privKey, wolfSSL_GetRNG(ssl));
+    }
+#endif
+
     /* generate shared secret and return it */
     if (ret == 0) {
@@ -2874,5 +3198,5 @@
         ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz);
         if (ret == 0)
-            ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey);
+            ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey, NULL, 0);
         wc_ed448_free(&myKey);
     }
@@ -2906,5 +3230,6 @@
         ret = wc_ed448_import_public(key, keySz, &myKey);
         if (ret == 0) {
-            ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey);
+            ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey,
+                                                                       NULL, 0);
         }
         wc_ed448_free(&myKey);
@@ -3499,6 +3824,46 @@
 #endif /* HAVE_PK_CALLBACKS */
 
-
-
+static WC_INLINE int SimulateWantWriteIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
+{
+    static int wantWriteFlag = 1;
+
+    int sent;
+    int sd = *(int*)ctx;
+
+    (void)ssl;
+
+    if (!wantWriteFlag)
+    {
+        wantWriteFlag = 1;
+
+        sent = wolfIO_Send(sd, buf, sz, 0);
+        if (sent < 0) {
+            int err = errno;
+
+            if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+                return WOLFSSL_CBIO_ERR_WANT_WRITE;
+            }
+            else if (err == SOCKET_ECONNRESET) {
+                return WOLFSSL_CBIO_ERR_CONN_RST;
+            }
+            else if (err == SOCKET_EINTR) {
+                return WOLFSSL_CBIO_ERR_ISR;
+            }
+            else if (err == SOCKET_EPIPE) {
+                return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+            }
+            else {
+                return WOLFSSL_CBIO_ERR_GENERAL;
+            }
+        }
+
+        return sent;
+    }
+    else
+    {
+        wantWriteFlag = 0;
+        return WOLFSSL_CBIO_ERR_WANT_WRITE;
+    }
+}
 
 #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \
@@ -3567,12 +3932,20 @@
 
 
-#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
-                                    defined(HAVE_POLY1305)
-
+#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
+    ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || \
+      defined(HAVE_AESGCM))
+
+#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
     #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
+    #define WOLFSSL_TICKET_KEY_SZ CHACHA20_POLY1305_AEAD_KEYSIZE
+#elif defined(HAVE_AESGCM)
+    #include <wolfssl/wolfcrypt/aes.h>
+    #include <wolfssl/wolfcrypt/wc_encrypt.h> /* AES IV sizes in FIPS mode */
+    #define WOLFSSL_TICKET_KEY_SZ AES_256_KEY_SIZE
+#endif
 
     typedef struct key_ctx {
-        byte name[WOLFSSL_TICKET_NAME_SZ];        /* name for this context */
-        byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; /* cipher key */
+        byte name[WOLFSSL_TICKET_NAME_SZ]; /* name for this context */
+        byte key[WOLFSSL_TICKET_KEY_SZ];   /* cipher key */
     } key_ctx;
 
@@ -3606,7 +3979,4 @@
                              void* userCtx)
     {
-        (void)ssl;
-        (void)userCtx;
-
         int ret;
         word16 sLen = XHTONS(inLen);
@@ -3614,5 +3984,14 @@
         int  aadSz = WOLFSSL_TICKET_NAME_SZ + WOLFSSL_TICKET_IV_SZ + 2;
         byte* tmp = aad;
-
+    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
+        /* chahca20/poly1305 */
+    #elif defined(HAVE_AESGCM)
+        Aes aes;
+    #endif
+
+        (void)ssl;
+        (void)userCtx;
+
+        /* encrypt */
         if (enc) {
             XMEMCPY(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ);
@@ -3626,6 +4005,7 @@
             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
             tmp += WOLFSSL_TICKET_IV_SZ;
-            XMEMCPY(tmp, &sLen, 2);
-
+            XMEMCPY(tmp, &sLen, sizeof(sLen));
+
+        #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
             ret = wc_ChaCha20Poly1305_Encrypt(myKey_ctx.key, iv,
                                               aad, aadSz,
@@ -3633,12 +4013,25 @@
                                               ticket,
                                               mac);
+        #elif defined(HAVE_AESGCM)
+            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+            if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
+
+            ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
+            if (ret == 0) {
+                ret = wc_AesGcmEncrypt(&aes, ticket, ticket, inLen,
+                                       iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
+                                       aad, aadSz);
+            }
+            wc_AesFree(&aes);
+        #endif
+            
             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
             *outLen = inLen;  /* no padding in this mode */
-        } else {
-            /* decrypt */
-
+        }
+        /* decrypt */
+        else {
             /* see if we know this key */
             if (XMEMCMP(key_name, myKey_ctx.name, WOLFSSL_TICKET_NAME_SZ) != 0){
-                printf("client presented unknown ticket key name ");
+                printf("client presented unknown ticket key name %s\n", key_name);
                 return WOLFSSL_TICKET_RET_FATAL;
             }
@@ -3649,6 +4042,7 @@
             XMEMCPY(tmp, iv, WOLFSSL_TICKET_IV_SZ);
             tmp += WOLFSSL_TICKET_IV_SZ;
-            XMEMCPY(tmp, &sLen, 2);
-
+            XMEMCPY(tmp, &sLen, sizeof(sLen));
+
+        #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
             ret = wc_ChaCha20Poly1305_Decrypt(myKey_ctx.key, iv,
                                               aad, aadSz,
@@ -3656,4 +4050,17 @@
                                               mac,
                                               ticket);
+        #elif defined(HAVE_AESGCM)
+            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+            if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
+
+            ret = wc_AesGcmSetKey(&aes, myKey_ctx.key, sizeof(myKey_ctx.key));
+            if (ret == 0) {
+                ret = wc_AesGcmDecrypt(&aes, ticket, ticket, inLen,
+                                        iv, GCM_NONCE_MID_SZ, mac, AES_BLOCK_SIZE,
+                                        aad, aadSz);
+            }
+            wc_AesFree(&aes);
+        #endif
+
             if (ret != 0) return WOLFSSL_TICKET_RET_REJECT;
             *outLen = inLen;  /* no padding in this mode */
@@ -3663,5 +4070,6 @@
     }
 
-#endif  /* HAVE_SESSION_TICKET && CHACHA20 && POLY1305 */
+#endif /* HAVE_SESSION_TICKET && ((HAVE_CHACHA && HAVE_POLY1305) || HAVE_AESGCM) */
+
 
 static WC_INLINE word16 GetRandomPort(void)
