Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/tls.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/tls.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/tls.c	(revision 464)
@@ -60,17 +60,9 @@
 #endif /* HAVE_QSH */
 
-#if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
-        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
-    (defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES))
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
 static int TLSX_KeyShare_IsSupported(int namedGroup);
 #endif
 
-#if ((!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
-        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
-    (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
-        && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
-    ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
-        defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))) && \
-     defined(HAVE_TLS_EXTENSIONS)
+#ifdef HAVE_SUPPORTED_CURVES
 static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
 #endif
@@ -135,13 +127,34 @@
 
 #ifdef WOLFSSL_RENESAS_TSIP_TLS
+    
+    #if (WOLFSSL_RENESAS_TSIP_VER >=109)
+
+    int tsip_generateMasterSecretEx(
+            byte        cipherSuiteFirst,
+            byte        cipherSuite,
+            const byte* pr,                 /* pre-master    */
+            const byte* cr,                 /* client random */
+            const byte* sr,                 /* server random */
+            byte*       ms);
+
+    #elif (WOLFSSL_RENESAS_TSIP_VER >=106)
+    
+    int tsip_generateMasterSecret(
+            const byte* pre,
+            const byte* cr,
+            const byte* sr,
+            byte*       ms);
+    
+    #endif     
+
     int tsip_useable(const WOLFSSL *ssl);
-    int tsip_generateMasterSecret(const byte *pre,
-                                const byte *cr,const byte *sr,
-                                byte *ms/* out */);
     int tsip_generateSeesionKey(WOLFSSL *ssl);
-    int tsip_generateVerifyData(const byte *ms, const byte *side,
-                                const byte *handshake_hash,
-                                byte *hashes /* out */);
-#endif
+    int tsip_generateVerifyData(
+            const byte* ms,
+            const byte* side,
+            const byte* handshake_hash,
+            byte*       hashes);
+
+#endif /*WOLFSSL_RENESAS_TSIP_TLS*/
 
 int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
@@ -535,4 +548,17 @@
     !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
         if (tsip_useable(ssl)) {
+            
+            #if (WOLFSSL_RENESAS_TSIP_VER>=109)
+
+            ret = tsip_generateMasterSecretEx(
+                            ssl->options.cipherSuite0,
+                            ssl->options.cipherSuite,                
+                            &ssl->arrays->preMasterSecret[VERSION_SZ],
+                            ssl->arrays->clientRandom,
+                            ssl->arrays->serverRandom,
+                            ssl->arrays->tsip_masterSecret);
+            
+            #elif (WOLFSSL_RENESAS_TSIP_VER>=106)
+
             ret = tsip_generateMasterSecret(
                             &ssl->arrays->preMasterSecret[VERSION_SZ],
@@ -540,4 +566,10 @@
                             ssl->arrays->serverRandom,
                             ssl->arrays->tsip_masterSecret);
+
+            #else
+
+            ret = NOT_COMPILED_IN;
+
+            #endif
         } else
 #endif
@@ -642,69 +674,4 @@
     return ret;
 }
-
-
-static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2])
-{
-    if (verify) {
-        seq[0] = ssl->keys.peer_sequence_number_hi;
-        seq[1] = ssl->keys.peer_sequence_number_lo++;
-        if (seq[1] > ssl->keys.peer_sequence_number_lo) {
-            /* handle rollover */
-            ssl->keys.peer_sequence_number_hi++;
-        }
-    }
-    else {
-        seq[0] = ssl->keys.sequence_number_hi;
-        seq[1] = ssl->keys.sequence_number_lo++;
-        if (seq[1] > ssl->keys.sequence_number_lo) {
-            /* handle rollover */
-            ssl->keys.sequence_number_hi++;
-        }
-    }
-}
-
-
-#ifdef WOLFSSL_DTLS
-static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2])
-{
-    if (order == PREV_ORDER) {
-        /* Previous epoch case */
-        seq[0] = (((word32)ssl->keys.dtls_epoch - 1) << 16) |
-                 (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF);
-        seq[1] = ssl->keys.dtls_prev_sequence_number_lo;
-    }
-    else if (order == PEER_ORDER) {
-        seq[0] = ((word32)ssl->keys.curEpoch << 16) |
-                 (ssl->keys.curSeq_hi & 0xFFFF);
-        seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */
-    }
-    else {
-        seq[0] = ((word32)ssl->keys.dtls_epoch << 16) |
-                 (ssl->keys.dtls_sequence_number_hi & 0xFFFF);
-        seq[1] = ssl->keys.dtls_sequence_number_lo;
-    }
-}
-#endif /* WOLFSSL_DTLS */
-
-
-static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
-{
-    word32 seq[2] = {0, 0};
-
-    if (!ssl->options.dtls) {
-        GetSEQIncrement(ssl, verifyOrder, seq);
-    }
-    else {
-#ifdef WOLFSSL_DTLS
-        DtlsGetSEQ(ssl, verifyOrder, seq);
-#endif
-    }
-
-    c32toa(seq[0], out);
-    c32toa(seq[1], out + OPAQUE32_LEN);
-}
-
-
-/*** end copy ***/
 
 
@@ -1170,18 +1137,21 @@
 
 int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
-             int content, int verify)
+             int content, int verify, int epochOrder)
 {
     Hmac   hmac;
     byte   myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
     int    ret = 0;
+    const byte* macSecret = NULL;
+    word32 hashSz = 0;
+
+    if (ssl == NULL)
+        return BAD_FUNC_ARG;
+
 #ifdef HAVE_TRUNCATED_HMAC
-    word32 hashSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
+    hashSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
                                         : ssl->specs.hash_size;
 #else
-    word32 hashSz = ssl->specs.hash_size;
-#endif
-
-    if (ssl == NULL)
-        return BAD_FUNC_ARG;
+    hashSz = ssl->specs.hash_size;
+#endif
 
 #ifdef HAVE_FUZZER
@@ -1198,5 +1168,8 @@
 #endif
 
-    wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
+    if (!ssl->options.dtls)
+        wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
+    else
+        wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, epochOrder);
 #if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
     !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION)
@@ -1218,7 +1191,17 @@
         return ret;
 
+
+#ifdef WOLFSSL_DTLS
+    if (ssl->options.dtls)
+        macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder);
+    else
+        macSecret = wolfSSL_GetMacSecret(ssl, verify);
+#else
+    macSecret = wolfSSL_GetMacSecret(ssl, verify);
+#endif
     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
-                                              wolfSSL_GetMacSecret(ssl, verify),
+                                              macSecret,
                                               ssl->specs.hash_size);
+
     if (ret == 0) {
         /* Constant time verification required. */
@@ -1375,4 +1358,41 @@
 }
 
+#ifdef WOLFSSL_TLS13
+
+/**
+ * Creates a new extension and prepend it to the provided list.
+ * Checks for duplicate extensions, keeps the newest.
+ */
+static int TLSX_Prepend(TLSX** list, TLSX_Type type, void* data, void* heap)
+{
+    TLSX* extension = TLSX_New(type, data, heap);
+    TLSX* curr = *list;
+
+    if (extension == NULL)
+        return MEMORY_E;
+
+    /* remove duplicate extensions, there should be only one of each type. */
+    while (curr && curr->next) {
+        if (curr->next->type == type) {
+            TLSX *next = curr->next;
+
+            curr->next = next->next;
+            next->next = NULL;
+
+            TLSX_FreeAll(next, heap);
+        }
+        curr = curr->next;
+    }
+
+    if (curr)
+        curr->next = extension;
+    else
+        *list = extension;
+
+    return 0;
+}
+
+#endif /* WOLFSSL_TLS13 */
+
 #ifndef NO_WOLFSSL_CLIENT
 
@@ -2961,4 +2981,27 @@
 {
     int ret;
+#if !defined(NO_WOLFSSL_SERVER)
+    byte status_type;
+    word16 size = 0;
+#if defined(WOLFSSL_TLS13)
+    DecodedCert* cert;
+#endif
+#endif
+
+#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER) \
+    && defined(WOLFSSL_TLS13)
+    OcspRequest* request;
+    TLSX* extension;
+    CertificateStatusRequest* csr;
+#endif
+
+#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13) \
+ || !defined(NO_WOLFSSL_SERVER) 
+    word32 offset = 0;
+#endif
+
+#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13)
+    word32 resp_length;
+#endif
 
     /* shut up compiler warnings */
@@ -2967,7 +3010,6 @@
     if (!isRequest) {
 #ifndef NO_WOLFSSL_CLIENT
-        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
-        CertificateStatusRequest* csr = extension ?
-                              (CertificateStatusRequest*)extension->data : NULL;
+        extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+        csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
 
         if (!csr) {
@@ -2990,6 +3032,6 @@
                     /* propagate nonce */
                     if (csr->request.ocsp.nonceSz) {
-                        OcspRequest* request =
-                             (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
+                        request = 
+                            (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
 
                         if (request) {
@@ -3007,7 +3049,4 @@
     #ifdef WOLFSSL_TLS13
         if (ssl->options.tls1_3) {
-            word32       resp_length;
-            word32       offset = 0;
-
             /* Get the new extension potentially created above. */
             extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
@@ -3027,10 +3066,8 @@
                     ret = BUFFER_ERROR;
             }
-        #if !defined(NO_WOLFSSL_SERVER)
             if (ret == 0) {
                 csr->response.buffer = input + offset;
                 csr->response.length = resp_length;
             }
-        #endif
 
             return ret;
@@ -3046,12 +3083,6 @@
     else {
 #ifndef NO_WOLFSSL_SERVER
-        byte   status_type;
-        word16 offset = 0;
-        word16 size = 0;
-
         if (length == 0)
             return 0;
-        if (length < ENUM_LEN)
-            return BUFFER_ERROR;
 
         status_type = input[offset++];
@@ -3061,5 +3092,5 @@
 
                 /* skip responder_id_list */
-                if (length - offset < OPAQUE16_LEN)
+                if ((int)(length - offset) < OPAQUE16_LEN)
                     return BUFFER_ERROR;
 
@@ -3068,5 +3099,5 @@
 
                 /* skip request_extensions */
-                if (length - offset < OPAQUE16_LEN)
+                if ((int)(length - offset) < OPAQUE16_LEN)
                     return BUFFER_ERROR;
 
@@ -3100,9 +3131,27 @@
             return ret; /* throw error */
 
-    #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
+    #if defined(WOLFSSL_TLS13)
         if (ssl->options.tls1_3) {
-            OcspRequest* request;
-            TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
-            CertificateStatusRequest* csr = extension ?
+            cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
+                                         DYNAMIC_TYPE_DCERT);
+            if (cert == NULL) {
+                return MEMORY_E;
+            }
+            InitDecodedCert(cert, ssl->buffers.certificate->buffer,
+                            ssl->buffers.certificate->length, ssl->heap);
+            ret = ParseCert(cert, CERT_TYPE, 1, ssl->ctx->cm);
+            if (ret != 0 ) {
+                XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+                return ret;
+            }
+            ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap);
+            if (ret != 0 ) {
+                XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+                return ret;
+            }
+            XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
+
+            extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
+            csr = extension ?
                 (CertificateStatusRequest*)extension->data : NULL;
             if (csr == NULL)
@@ -3454,5 +3503,5 @@
 
         while (length > offset) {
-            if (length - offset < ENUM_LEN + OPAQUE16_LEN)
+            if ((int)(length - offset) < ENUM_LEN + OPAQUE16_LEN)
                 return BUFFER_ERROR;
 
@@ -3469,5 +3518,5 @@
                 case WOLFSSL_CSR2_OCSP_MULTI:
                     /* skip responder_id_list */
-                    if (length - offset < OPAQUE16_LEN)
+                    if ((int)(length - offset) < OPAQUE16_LEN)
                         return BUFFER_ERROR;
 
@@ -3478,5 +3527,5 @@
                     offset += OPAQUE16_LEN + size;
                     /* skip request_extensions */
-                    if (length - offset < OPAQUE16_LEN)
+                    if ((int)(length - offset) < OPAQUE16_LEN)
                         return BUFFER_ERROR;
 
@@ -3507,12 +3556,17 @@
             #endif
 
-            /* accept the first good status_type and return */
-            ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
+            /* TLS 1.3 servers MUST NOT act upon presence or information in
+             * this extension (RFC 8448 Section 4.4.2.1).
+             */
+            if (!IsAtLeastTLSv1_3(ssl->version)) {
+                /* accept the first good status_type and return */
+                ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
                                          status_type, 0, ssl->heap, ssl->devId);
-            if (ret != WOLFSSL_SUCCESS)
-                return ret; /* throw error */
-
-            TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
-            ssl->status_request_v2 = status_type;
+                if (ret != WOLFSSL_SUCCESS)
+                    return ret; /* throw error */
+
+                TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
+                ssl->status_request_v2 = status_type;
+            }
 
             return 0;
@@ -3708,5 +3762,5 @@
 #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
        Use --enable-ecc in the configure script or define HAVE_ECC. \
-       Alternatively use FFDHE for DH ciperhsuites.
+       Alternatively use FFDHE for DH ciphersuites.
 #endif
 
@@ -3854,16 +3908,13 @@
         #endif
         }
-        else {
-        #ifdef HAVE_FFDHE
-            return;
-        #endif
-        }
-    }
-
+    }
+ #ifdef HAVE_FFDHE
+        return;
+ #endif
     /* turns semaphore on to avoid sending this extension. */
     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
 }
 
-#endif
+#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
 
 #ifndef NO_WOLFSSL_SERVER
@@ -3897,5 +3948,6 @@
 }
 
-#endif
+#endif /* !NO_WOLFSSL_SERVER */
+
 #ifndef NO_WOLFSSL_CLIENT
 
@@ -4056,4 +4108,9 @@
 
     ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
+    if (ext == NULL) {
+        WOLFSSL_MSG("Could not find supported groups extension");
+        return 0;
+    }
+
     curve = (SupportedCurve*)ext->data;
     name = curve->name;
@@ -4081,5 +4138,5 @@
 }
 
-#endif
+#endif /* WOLFSSL_TLS13 && !WOLFSSL_NO_SERVER_GROUPS_EXT */
 
 #if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12)
@@ -4130,6 +4187,8 @@
 
 
-    if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS)
+    if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS) {
+        TLSX_FreeAll(priority, ssl->heap);
         return ret;
+    }
     ret = 0;
 
@@ -4231,5 +4290,5 @@
 }
 
-#endif
+#endif /* HAVE_SUPPORTED_CURVES */
 
 #ifndef NO_WOLFSSL_SERVER
@@ -4262,5 +4321,9 @@
     SupportedCurve* curve     = NULL;
     word32          oid       = 0;
+#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
+                              defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
+                                (!defined(NO_RSA) && defined(WOLFSSL_STATIC_DH))
     word32          pkOid     = 0;
+#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 || (!NO_RSA && STATIC_DH) */
     word32          defOid    = 0;
     word32          defSz     = 80; /* Maximum known curve size is 66. */
@@ -4274,5 +4337,19 @@
 
     (void)oid;
-
+    (void)pkOid;
+
+    if (first == CHACHA_BYTE) {
+        switch (second) {
+            case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+            case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256:
+            case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
+            case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
+                return 1; /* no suite restriction */
+            case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+            case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
+            case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
+                break;
+        }
+    }
     if (first == ECC_BYTE || first == CHACHA_BYTE)
         extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
@@ -4296,5 +4373,5 @@
         switch (curve->name) {
 #ifdef HAVE_ECC
-    #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
         #ifndef NO_ECC_SECP
             case WOLFSSL_ECC_SECP160R1:
@@ -4315,6 +4392,6 @@
                 break;
         #endif /* HAVE_ECC_KOBLITZ */
-    #endif
-    #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+        #endif
+    #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
         #ifndef NO_ECC_SECP
             case WOLFSSL_ECC_SECP192R1:
@@ -4330,5 +4407,5 @@
         #endif /* HAVE_ECC_KOBLITZ */
     #endif
-    #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
         #ifndef NO_ECC_SECP
             case WOLFSSL_ECC_SECP224R1:
@@ -4344,5 +4421,5 @@
         #endif /* HAVE_ECC_KOBLITZ */
     #endif
-    #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifndef NO_ECC_SECP
             case WOLFSSL_ECC_SECP256R1:
@@ -4353,5 +4430,5 @@
     #endif /* !NO_ECC256 || HAVE_ALL_CURVES */
 #endif
-        #ifdef HAVE_CURVE25519
+        #if (defined(HAVE_CURVE25519) || defined(HAVE_ED25519)) && ECC_MIN_KEY_SZ <= 256
             case WOLFSSL_ECC_X25519:
                 oid = ECC_X25519_OID;
@@ -4365,5 +4442,5 @@
         #endif /* HAVE_CURVE25519 */
 #ifdef HAVE_ECC
-    #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifdef HAVE_ECC_KOBLITZ
             case WOLFSSL_ECC_SECP256K1:
@@ -4379,6 +4456,20 @@
         #endif /* HAVE_ECC_BRAINPOOL */
     #endif
-#endif
-        #ifdef HAVE_CURVE448
+    #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
+        #ifndef NO_ECC_SECP
+            case WOLFSSL_ECC_SECP384R1:
+                pkOid = oid = ECC_SECP384R1_OID;
+                octets = 48;
+                break;
+        #endif /* !NO_ECC_SECP */
+        #ifdef HAVE_ECC_BRAINPOOL
+            case WOLFSSL_ECC_BRAINPOOLP384R1:
+                pkOid = oid = ECC_BRAINPOOLP384R1_OID;
+                octets = 48;
+                break;
+        #endif /* HAVE_ECC_BRAINPOOL */
+    #endif
+#endif
+        #if (defined(HAVE_CURVE448) || defined(HAVE_ED448)) && ECC_MIN_KEY_SZ <= 448
             case WOLFSSL_ECC_X448:
                 oid = ECC_X448_OID;
@@ -4392,19 +4483,5 @@
         #endif /* HAVE_CURVE448 */
 #ifdef HAVE_ECC
-    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
-        #ifndef NO_ECC_SECP
-            case WOLFSSL_ECC_SECP384R1:
-                pkOid = oid = ECC_SECP384R1_OID;
-                octets = 48;
-                break;
-        #endif /* !NO_ECC_SECP */
-        #ifdef HAVE_ECC_BRAINPOOL
-            case WOLFSSL_ECC_BRAINPOOLP384R1:
-                pkOid = oid = ECC_BRAINPOOLP384R1_OID;
-                octets = 48;
-                break;
-        #endif /* HAVE_ECC_BRAINPOOL */
-    #endif
-    #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
         #ifdef HAVE_ECC_BRAINPOOL
             case WOLFSSL_ECC_BRAINPOOLP512R1:
@@ -4414,5 +4491,5 @@
         #endif /* HAVE_ECC_BRAINPOOL */
     #endif
-    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
         #ifndef NO_ECC_SECP
             case WOLFSSL_ECC_SECP521R1:
@@ -4456,4 +4533,5 @@
         if (first == ECC_BYTE) {
             switch (second) {
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
                 /* ECDHE_ECDSA */
                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
@@ -4472,5 +4550,5 @@
                 break;
 
-#ifdef WOLFSSL_STATIC_DH
+    #ifdef WOLFSSL_STATIC_DH
                 /* ECDH_ECDSA */
                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
@@ -4493,5 +4571,6 @@
                     key |= ssl->pkCurveOID == oid;
                 break;
-#endif /* WOLFSSL_STATIC_DH */
+    #endif /* WOLFSSL_STATIC_DH */
+#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
 #ifndef NO_RSA
                 /* ECDHE_RSA */
@@ -4509,5 +4588,5 @@
                 break;
 
-#ifdef WOLFSSL_STATIC_DH
+    #ifdef WOLFSSL_STATIC_DH
                 /* ECDH_RSA */
                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
@@ -4530,5 +4609,5 @@
                     key |= ssl->pkCurveOID == pkOid;
                 break;
-#endif /* WOLFSSL_STATIC_DH */
+    #endif /* WOLFSSL_STATIC_DH */
 #endif
                 default:
@@ -4552,4 +4631,5 @@
         if (first == CHACHA_BYTE) {
             switch (second) {
+#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
                 /* ECDHE_ECDSA */
                 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
@@ -4559,4 +4639,5 @@
                     ephmSuite = 1;
                 break;
+#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
 #ifndef NO_RSA
                 /* ECDHE_RSA */
@@ -4816,5 +4897,5 @@
         #endif
         }
-        else {
+        else if (ssl->secure_renegotiation != NULL) {
         #ifndef NO_WOLFSSL_CLIENT
             if (!ssl->secure_renegotiation->enabled) {
@@ -4982,10 +5063,19 @@
         }
 
-        if (length == 0) {
+        if (length > SESSION_TICKET_LEN) {
+            ret = BAD_TICKET_MSG_SZ;
+        } else if (IsAtLeastTLSv1_3(ssl->version)) {
+            WOLFSSL_MSG("Process client ticket rejected, TLS 1.3 no support");
+            ssl->options.rejectTicket = 1;
+            ret = 0;  /* not fatal */
+        } else if (ssl->options.noTicketTls12) {
+            /* ignore ticket request */
+        } else if (length == 0) {
             /* blank ticket */
             ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
             if (ret == WOLFSSL_SUCCESS) {
                 ret = 0;
-                TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);  /* send blank ticket */
+                /* send blank ticket */
+                TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
                 ssl->options.createTicket = 1;  /* will send ticket msg */
                 ssl->options.useTicket    = 1;
@@ -5015,4 +5105,8 @@
                 ssl->options.rejectTicket = 1;
                 ret = 0;  /* not fatal */
+            } else if (ret == VERSION_ERROR) {
+                WOLFSSL_MSG("Process client ticket rejected, bad TLS version");
+                ssl->options.rejectTicket = 1;
+                ret = 0;  /* not fatal */
             } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
                 WOLFSSL_MSG("Process client ticket fatal error, not using");
@@ -5876,8 +5970,6 @@
         *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
     }
-#ifndef WOLFSSL_TLS13_DRAFT_18
     else if (msgType == server_hello || msgType == hello_retry_request)
         *pSz += OPAQUE16_LEN;
-#endif
     else
         return SANITY_MSG_E;
@@ -5957,22 +6049,10 @@
         *pSz += (word16)(OPAQUE8_LEN + *cnt);
     }
-#ifndef WOLFSSL_TLS13_DRAFT_18
     else if (msgType == server_hello || msgType == hello_retry_request) {
-    #ifdef WOLFSSL_TLS13_DRAFT
-        if (ssl->version.major == SSLv3_MAJOR &&
-                                          ssl->version.minor == TLSv1_3_MINOR) {
-            output[0] = TLS_DRAFT_MAJOR;
-            output[1] = TLS_DRAFT_MINOR;
-        }
-        else
-    #endif
-        {
-            output[0] = ssl->version.major;
-            output[1] = ssl->version.minor;
-        }
+        output[0] = ssl->version.major;
+        output[1] = ssl->version.minor;
 
         *pSz += OPAQUE16_LEN;
     }
-#endif
     else
         return SANITY_MSG_E;
@@ -5998,4 +6078,5 @@
     int newMinor = 0;
     int set = 0;
+    int ret;
 
     if (msgType == client_hello) {
@@ -6050,9 +6131,10 @@
                 if (!ssl->options.tls1_3) {
                     ssl->options.tls1_3 = 1;
-                    TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
-                              ssl->heap);
-#ifndef WOLFSSL_TLS13_DRAFT_18
+                    ret = TLSX_Prepend(&ssl->extensions,
+                              TLSX_SUPPORTED_VERSIONS, ssl, ssl->heap);
+                    if (ret != 0) {
+                        return ret;
+                    }
                     TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
-#endif
                 }
                 if (minor > newMinor) {
@@ -6075,5 +6157,4 @@
         }
     }
-#ifndef WOLFSSL_TLS13_DRAFT_18
     else if (msgType == server_hello || msgType == hello_retry_request) {
         /* Must contain one version. */
@@ -6084,11 +6165,4 @@
         minor = input[OPAQUE8_LEN];
 
-    #ifdef WOLFSSL_TLS13_DRAFT
-        if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
-            major = SSLv3_MAJOR;
-            minor = TLSv1_3_MINOR;
-        }
-    #endif
-
         if (major != pv.major)
             return VERSION_ERROR;
@@ -6120,5 +6194,4 @@
         }
     }
-#endif
     else
         return SANITY_MSG_E;
@@ -6155,5 +6228,5 @@
 #endif /* WOLFSSL_TLS13 */
 
-#if defined(WOLFSSL_TLS13)
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
 
 /******************************************************************************/
@@ -6302,4 +6375,7 @@
         XMEMCPY(&cookie->data + len, mac, macSz);
 
+    if (extension->data != NULL)
+        XFREE(extension->data, ssl->heap, DYNAMIC_TYPE_TLSX);
+
     extension->data = (void*)cookie;
     extension->resp = (byte)resp;
@@ -6321,5 +6397,5 @@
 
 #endif
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
 /******************************************************************************/
 /* Signature Algorithms                                                       */
@@ -6418,4 +6494,8 @@
         return BUFFER_ERROR;
 
+    /* Sig Algo list size must be even. */
+    if (suites->hashSigAlgoSz % 2 != 0)
+        return BUFFER_ERROR;
+
     /* truncate hashSigAlgo list if too long */
     suites->hashSigAlgoSz = len;
@@ -6453,6 +6533,5 @@
 /******************************************************************************/
 
-#ifdef WOLFSSL_TLS13
-#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+#if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
 /* Return the size of the SignatureAlgorithms extension's data.
  *
@@ -6541,5 +6620,4 @@
 #define SAC_WRITE     TLSX_SignatureAlgorithmsCert_Write
 #define SAC_PARSE     TLSX_SignatureAlgorithmsCert_Parse
-#endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
 #endif /* WOLFSSL_TLS13 */
 
@@ -6549,5 +6627,5 @@
 /******************************************************************************/
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
 /* Create a key share entry using named Diffie-Hellman parameters group.
  * Generates a key pair.
@@ -6623,5 +6701,5 @@
     }
 
-    /* Allocate space for the public key. */
+    /* Allocate space for the public key */
     dataSz = params->p_len;
     keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
@@ -6630,5 +6708,5 @@
         goto end;
     }
-    /* Allocate space for the private key. */
+    /* Allocate space for the private key */
     key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
     if (key == NULL) {
@@ -6644,18 +6722,32 @@
         goto end;
 
-    /* Generate a new key pair. */
-    ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, (byte*)key, &keySz, keyData,
-                               &dataSz);
-#ifdef WOLFSSL_ASYNC_CRYPT
-    /* TODO: Make this function non-blocking */
-    if (ret == WC_PENDING_E) {
-        ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
-    }
-#endif
+#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
+    if (ssl->staticKE.dhKey) {
+        DerBuffer* keyDer = ssl->staticKE.dhKey;
+        word32 idx = 0;
+        WOLFSSL_MSG("Using static DH key");
+        ret = wc_DhKeyDecode(keyDer->buffer, &idx, dhKey, keyDer->length);
+        if (ret == 0) {
+            ret = wc_DhExportKeyPair(dhKey, (byte*)key, &keySz, keyData, &dataSz);
+        }
+    }
+    else
+#endif
+    {
+        /* Generate a new key pair */
+        ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, (byte*)key, &keySz, keyData,
+                                &dataSz);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make this function non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+    }
     if (ret != 0)
         goto end;
 
     if (params->p_len != dataSz) {
-        /* Pad the front of the key data with zeros. */
+        /* Zero pad the front of the public key to match prime "p" size */
         XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz);
         XMEMSET(keyData, 0, params->p_len - dataSz);
@@ -6865,5 +6957,5 @@
     /* Translate named group to a curve id. */
     switch (kse->group) {
-    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP256R1:
@@ -6874,5 +6966,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP384R1:
@@ -6883,5 +6975,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP521R1:
@@ -6892,5 +6984,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #ifdef HAVE_X448
+    #if defined(HAVE_X448) && ECC_MIN_KEY_SZ <= 448
         case WOLFSSL_ECC_X448:
             curveId = ECC_X448;
@@ -6915,11 +7007,24 @@
     if (ret != 0)
         goto end;
-    ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId);
-#ifdef WOLFSSL_ASYNC_CRYPT
-    /* TODO: Make this function non-blocking */
-    if (ret == WC_PENDING_E) {
-        ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE);
-    }
-#endif
+
+#ifdef WOLFSSL_STATIC_EPHEMERAL
+    if (ssl->staticKE.ecKey) {
+        DerBuffer* keyDer = ssl->staticKE.ecKey;
+        word32 idx = 0;
+        WOLFSSL_MSG("Using static ECDH key");
+        ret = wc_EccPrivateKeyDecode(keyDer->buffer, &idx, eccKey, keyDer->length);
+    }
+    else
+#endif
+    {
+        /* Generate ephemeral ECC key */
+        ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId);
+    #ifdef WOLFSSL_ASYNC_CRYPT
+        /* TODO: Make this function non-blocking */
+        if (ret == WC_PENDING_E) {
+            ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE);
+        }
+    #endif
+    }
     if (ret != 0)
         goto end;
@@ -7410,5 +7515,5 @@
     /* find supported curve */
     switch (keyShareEntry->group) {
-    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP256R1:
@@ -7417,5 +7522,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP384R1:
@@ -7424,5 +7529,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP521R1:
@@ -7431,5 +7536,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #ifdef HAVE_X448
+    #if defined(HAVE_X448) && ECC_MIN_KEY_SZ <= 448
         case WOLFSSL_ECC_X448:
             curveId = ECC_X448;
@@ -7452,4 +7557,13 @@
     }
     ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum;
+
+#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
+    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
+    !defined(HAVE_SELFTEST)
+    ret = wc_ecc_set_rng(keyShareKey, ssl->rng);
+    if (ret != 0) {
+        return ret;
+    }
+#endif
 
     do {
@@ -7897,5 +8011,5 @@
             break;
     #endif
-    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP256R1:
@@ -7903,13 +8017,13 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #ifdef HAVE_CURVE25519
+    #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
         case WOLFSSL_ECC_X25519:
             break;
     #endif
-    #ifdef HAVE_CURVE448
+    #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
         case WOLFSSL_ECC_X448:
             break;
     #endif
-    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP384R1:
@@ -7917,5 +8031,5 @@
         #endif /* !NO_ECC_SECP */
     #endif
-    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
         #ifndef NO_ECC_SECP
         case WOLFSSL_ECC_SECP521R1:
@@ -7944,5 +8058,5 @@
     if (ssl->numGroups == 0) {
 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
-    #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+    #if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
         #ifndef NO_ECC_SECP
             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP256R1;
@@ -7951,20 +8065,20 @@
 #endif
     #ifndef HAVE_FIPS
-        #if defined(HAVE_CURVE25519)
+        #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519;
         #endif
     #endif
     #ifndef HAVE_FIPS
-        #if defined(HAVE_CURVE448)
+        #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X448;
         #endif
     #endif
 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
-    #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
         #ifndef NO_ECC_SECP
             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP384R1;
         #endif
     #endif
-    #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+    #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
         #ifndef NO_ECC_SECP
             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP521R1;
@@ -8091,11 +8205,15 @@
             return BAD_KEY_SHARE_DATA;
 
-    #ifdef OPENSSL_EXTRA
         if ((clientKSE->group & NAMED_DH_MASK) == 0) {
+            /* Check max value supported. */
+            if (clientKSE->group > WOLFSSL_ECC_MAX) {
+                continue;
+            }
+        #ifdef OPENSSL_EXTRA
             /* Check if server supports group. */
-            if (ssl->ctx->disabledCurves & (1 << clientKSE->group))
+            if (ssl->ctx->disabledCurves & ((word32)1 << clientKSE->group))
                 continue;
-        }
-    #endif
+        #endif
+        }
         if (!TLSX_KeyShare_IsSupported(clientKSE->group))
             continue;
@@ -8405,5 +8523,5 @@
 
         /* Length of identities and of binders. */
-        if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN)
+        if ((int)(length - idx) < OPAQUE16_LEN + OPAQUE16_LEN)
             return BUFFER_E;
 
@@ -8955,10 +9073,10 @@
  * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
  *
- * max      The maximum early data size.
+ * maxSz    The maximum early data size.
  * output   The buffer to write into.
  * msgType  The type of the message this extension is being written into.
  * returns the number of bytes written into the buffer.
  */
-static int TLSX_EarlyData_Write(word32 max, byte* output, byte msgType,
+static int TLSX_EarlyData_Write(word32 maxSz, byte* output, byte msgType,
                                 word16* pSz)
 {
@@ -8966,5 +9084,5 @@
         return 0;
     else if (msgType == session_ticket) {
-        c32toa(max, output);
+        c32toa(maxSz, output);
         *pSz += OPAQUE32_LEN;
         return 0;
@@ -9023,9 +9141,9 @@
 /* Use the data to create a new Early Data object in the extensions.
  *
- * ssl  The SSL/TLS object.
- * max  The maximum early data size.
+ * ssl    The SSL/TLS object.
+ * maxSz  The maximum early data size.
  * returns 0 on success and other values indicate failure.
  */
-int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max)
+int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 maxSz)
 {
     int   ret = 0;
@@ -9046,5 +9164,5 @@
 
     extension->resp = 1;
-    extension->val  = max;
+    extension->val  = maxSz;
 
     return 0;
@@ -9106,7 +9224,9 @@
         switch (extension->type) {
 
+#ifdef HAVE_SNI
             case TLSX_SERVER_NAME:
                 SNI_FREE_ALL((SNI*)extension->data, heap);
                 break;
+#endif
 
             case TLSX_TRUSTED_CA_KEYS:
@@ -9118,4 +9238,5 @@
                 break;
 
+            case TLSX_EXTENDED_MASTER_SECRET:
             case TLSX_TRUNCATED_HMAC:
                 /* Nothing to do. */
@@ -9154,5 +9275,5 @@
                 ALPN_FREE_ALL((ALPN*)extension->data, heap);
                 break;
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS:
                 break;
@@ -9166,7 +9287,9 @@
                 break;
 
+    #ifdef WOLFSSL_SEND_HRR_COOKIE
             case TLSX_COOKIE:
                 CKE_FREE_ALL((Cookie*)extension->data, heap);
                 break;
+    #endif
 
     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -9189,5 +9312,5 @@
     #endif
 
-    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+    #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS_CERT:
                 break;
@@ -9235,7 +9358,7 @@
         length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
 
-
         switch (extension->type) {
 
+#ifdef HAVE_SNI
             case TLSX_SERVER_NAME:
                 /* SNI only sends the name on the request. */
@@ -9243,4 +9366,5 @@
                     length += SNI_GET_SIZE((SNI*)extension->data);
                 break;
+#endif
 
             case TLSX_TRUSTED_CA_KEYS:
@@ -9254,4 +9378,5 @@
                 break;
 
+            case TLSX_EXTENDED_MASTER_SECRET:
             case TLSX_TRUNCATED_HMAC:
                 /* always empty. */
@@ -9294,5 +9419,5 @@
                 length += ALPN_GET_SIZE((ALPN*)extension->data);
                 break;
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS:
                 length += SA_GET_SIZE(extension->data);
@@ -9309,7 +9434,9 @@
                 break;
 
+    #ifdef WOLFSSL_SEND_HRR_COOKIE
             case TLSX_COOKIE:
                 ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
                 break;
+    #endif
 
     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -9336,5 +9463,5 @@
     #endif
 
-    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+    #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS_CERT:
                 length += SAC_GET_SIZE(extension->data);
@@ -9387,4 +9514,5 @@
         /* extension data should be written internally. */
         switch (extension->type) {
+#ifdef HAVE_SNI
             case TLSX_SERVER_NAME:
                 if (isRequest) {
@@ -9393,4 +9521,5 @@
                 }
                 break;
+#endif
 
             case TLSX_TRUSTED_CA_KEYS:
@@ -9404,4 +9533,9 @@
                 WOLFSSL_MSG("Max Fragment Length extension to write");
                 offset += MFL_WRITE((byte*)extension->data, output + offset);
+                break;
+
+            case TLSX_EXTENDED_MASTER_SECRET:
+                WOLFSSL_MSG("Extended Master Secret");
+                /* always empty. */
                 break;
 
@@ -9461,5 +9595,5 @@
                 offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
                 break;
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS:
                 WOLFSSL_MSG("Signature Algorithms extension to write");
@@ -9479,4 +9613,5 @@
                 break;
 
+    #ifdef WOLFSSL_SEND_HRR_COOKIE
             case TLSX_COOKIE:
                 WOLFSSL_MSG("Cookie extension to write");
@@ -9484,4 +9619,5 @@
                                 msgType, &offset);
                 break;
+    #endif
 
     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -9514,5 +9650,5 @@
     #endif
 
-    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+    #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS_CERT:
                 WOLFSSL_MSG("Signature Algorithms extension to write");
@@ -9733,10 +9869,5 @@
 #endif /* HAVE_QSH */
 
-#if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
-        !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
-    (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
-        && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
-    ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
-        defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))
+#ifdef HAVE_SUPPORTED_CURVES
 
 /* Populates the default supported groups / curves */
@@ -9745,6 +9876,4 @@
     int ret = WOLFSSL_SUCCESS;
 #ifdef WOLFSSL_TLS13
-    int i;
-
 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
     if (ssl->options.resuming && ssl->session.namedGroup != 0) {
@@ -9755,4 +9884,5 @@
 
     if (ssl->numGroups != 0) {
+        int i;
         for (i = 0; i < ssl->numGroups; i++) {
             ret = TLSX_UseSupportedCurve(extensions, ssl->group[i], ssl->heap);
@@ -9764,7 +9894,7 @@
 #endif /* WOLFSSL_TLS13 */
 
-#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+#if defined(HAVE_ECC)
         /* list in order by strength, since not all servers choose by strength */
-        #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9773,5 +9903,5 @@
             #endif
         #endif
-        #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
             #ifdef HAVE_ECC_BRAINPOOL
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9780,5 +9910,5 @@
             #endif
         #endif
-        #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9792,8 +9922,8 @@
             #endif
         #endif
-#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
+#endif /* HAVE_ECC */
 
         #ifndef HAVE_FIPS
-            #if defined(HAVE_CURVE448)
+            #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
                 ret = TLSX_UseSupportedCurve(extensions,
                                                    WOLFSSL_ECC_X448, ssl->heap);
@@ -9803,5 +9933,5 @@
 
 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
-        #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
+        #if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9820,8 +9950,8 @@
             #endif
         #endif
-#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
+#endif /* HAVE_ECC */
 
         #ifndef HAVE_FIPS
-            #if defined(HAVE_CURVE25519)
+            #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
                 ret = TLSX_UseSupportedCurve(extensions,
                                                  WOLFSSL_ECC_X25519, ssl->heap);
@@ -9831,5 +9961,5 @@
 
 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
-        #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9845,5 +9975,5 @@
 
     #ifndef HAVE_FIPS
-        #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9857,5 +9987,5 @@
             #endif
         #endif
-        #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
+        #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
             #ifndef NO_ECC_SECP
                 ret = TLSX_UseSupportedCurve(extensions,
@@ -9875,7 +10005,7 @@
         #endif
     #endif /* HAVE_FIPS */
-#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
-
-                /* Add FFDHE supported groups. */
+#endif /* HAVE_ECC */
+
+            /* Add FFDHE supported groups. */
         #ifdef HAVE_FFDHE_8192
             if (8192/8 >= ssl->options.minDhKeySz &&
@@ -9930,5 +10060,46 @@
 }
 
-#endif
+#endif /* HAVE_SUPPORTED_CURVES */
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+
+static const word16 preferredGroup[] = {
+#if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
+    defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256
+    WOLFSSL_ECC_SECP256R1,
+#endif
+#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
+    WOLFSSL_ECC_X25519,
+#endif
+#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
+    WOLFSSL_ECC_X448,
+#endif
+#if defined(HAVE_ECC) && (!defined(NO_ECC384) || \
+    defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384
+    WOLFSSL_ECC_SECP384R1,
+#endif
+#if defined(HAVE_ECC) && (!defined(NO_ECC521) || \
+    defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521
+    WOLFSSL_ECC_SECP521R1,
+#endif
+#if defined(HAVE_FFDHE_2048)
+    WOLFSSL_FFDHE_2048,
+#endif
+#if defined(HAVE_FFDHE_3072)
+    WOLFSSL_FFDHE_3072,
+#endif
+#if defined(HAVE_FFDHE_4096)
+    WOLFSSL_FFDHE_4096,
+#endif
+#if defined(HAVE_FFDHE_6144)
+    WOLFSSL_FFDHE_6144,
+#endif
+#if defined(HAVE_FFDHE_8192)
+    WOLFSSL_FFDHE_8192,
+#endif
+};
+#define PREFERRED_GROUP_SZ (sizeof(preferredGroup) / sizeof(*preferredGroup))
+
+#endif /* WOLFSSL_TLS13 && HAVE_SUPPORTED_CURVES */
 
 int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
@@ -10052,5 +10223,5 @@
     } /* is not server */
 
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
     WOLFSSL_MSG("Adding signature algorithms extension");
     if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap))
@@ -10061,5 +10232,5 @@
     ret = 0;
 #endif
-    #ifdef WOLFSSL_TLS13
+#ifdef WOLFSSL_TLS13
         if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
             /* Add mandatory TLS v1.3 extension: supported version */
@@ -10079,7 +10250,7 @@
             ret = 0;
         }
-    #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
-
-        #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+    #endif /* !(HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
+ 
+        #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             if (ssl->certHashSigAlgoSz > 0) {
                 WOLFSSL_MSG("Adding signature algorithms cert extension");
@@ -10089,41 +10260,40 @@
                 }
             }
-        #endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
-
+        #endif
+
+        #if defined(HAVE_SUPPORTED_CURVES)
             if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
                 word16 namedGroup;
 
-        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
                 if (ssl->options.resuming && ssl->session.namedGroup != 0)
                     namedGroup = ssl->session.namedGroup;
                 else
-        #endif
-                {
-        #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
-                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
-                    namedGroup = WOLFSSL_ECC_SECP256R1;
-        #elif defined(HAVE_CURVE25519)
-                    namedGroup = WOLFSSL_ECC_X25519;
-        #elif defined(HAVE_CURVE448)
-                    namedGroup = WOLFSSL_ECC_X448;
-        #elif defined(HAVE_ECC) && (!defined(NO_ECC384) || \
-                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
-                    namedGroup = WOLFSSL_ECC_SECP384R1;
-        #elif defined(HAVE_ECC) && (!defined(NO_ECC521) || \
-                              defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
-                    namedGroup = WOLFSSL_ECC_SECP521R1;
-        #elif defined(HAVE_FFDHE_2048)
-                    namedGroup = WOLFSSL_FFDHE_2048;
-        #elif defined(HAVE_FFDHE_3072)
-                    namedGroup = WOLFSSL_FFDHE_3072;
-        #elif defined(HAVE_FFDHE_4096)
-                    namedGroup = WOLFSSL_FFDHE_4096;
-        #elif defined(HAVE_FFDHE_6144)
-                    namedGroup = WOLFSSL_FFDHE_6144;
-        #elif defined(HAVE_FFDHE_8192)
-                    namedGroup = WOLFSSL_FFDHE_8192;
-        #else
+            #endif
+                if (PREFERRED_GROUP_SZ == 0) {
+                    WOLFSSL_MSG("No groups in preference list");
                     return KEY_SHARE_ERROR;
-        #endif
+                }
+                else if (ssl->numGroups > 0) {
+                    int set = 0;
+                    int i, j;
+
+                    /* Default to first group in supported list. */
+                    namedGroup = ssl->group[0];
+                    /* Try to find preferred in supported list. */
+                    for (i = 0; i < (int)PREFERRED_GROUP_SZ && !set; i++) {
+                        for (j = 0; j < ssl->numGroups; j++) {
+                            if (preferredGroup[i] == ssl->group[j]) {
+                                /* Most preferred that is supported. */
+                                namedGroup = ssl->group[j];
+                                set = 1;
+                                break;
+                            }
+                        }
+                    }
+                }
+                else {
+                    /* Choose the most preferred group. */
+                    namedGroup = preferredGroup[0];
                 }
                 ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
@@ -10131,4 +10301,5 @@
                     return ret;
             }
+        #endif
 
         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -10171,4 +10342,5 @@
                 byte cipherSuite0 = TLS13_BYTE;
                 byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
+                int cipherSuiteFlags = WOLFSSL_CIPHER_SUITE_FLAG_NONE;
                 const char* cipherName = NULL;
 
@@ -10179,5 +10351,5 @@
                         ssl->arrays->psk_key, MAX_PSK_KEY_LEN, &cipherName);
                     if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
-                                                           &cipherSuite) != 0) {
+                                               &cipherSuite, &cipherSuiteFlags) != 0) {
                         return PSK_KEY_ERROR;
                     }
@@ -10193,7 +10365,7 @@
                 }
                 ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
-                /* TODO: Callback should be able to change ciphersuite. */
                 ssl->options.cipherSuite0 = cipherSuite0;
                 ssl->options.cipherSuite  = cipherSuite;
+                (void)cipherSuiteFlags;
                 ret = SetCipherSpecs(ssl);
                 if (ret != 0)
@@ -10237,5 +10409,5 @@
         }
 
-    #endif
+#endif
 
     (void)isServer;
@@ -10264,5 +10436,5 @@
         QSH_VALIDATE_REQUEST(ssl, semaphore);
         WOLF_STK_VALIDATE_REQUEST(ssl);
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
         if (ssl->suites->hashSigAlgoSz == 0)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
@@ -10271,18 +10443,22 @@
         if (!IsAtLeastTLSv1_2(ssl))
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+    #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
         if (!IsAtLeastTLSv1_3(ssl->version)) {
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
-    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
+        #endif
+        #ifdef WOLFSSL_EARLY_DATA
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+        #endif
+        #ifdef WOLFSSL_SEND_HRR_COOKIE
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+        #endif
+        #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
+        #endif
+        }
     #endif
-    #ifdef WOLFSSL_EARLY_DATA
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
-    #endif
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
-    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
-    #endif
-        }
 #endif
     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
@@ -10299,6 +10475,7 @@
     #ifndef NO_CERTS
     else if (msgType == certificate_request) {
+        /* Don't send out any extension except those that are turned off. */
         XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
 #endif
@@ -10353,5 +10530,5 @@
         WOLF_STK_VALIDATE_REQUEST(ssl);
         QSH_VALIDATE_REQUEST(ssl, semaphore);
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
         if (ssl->suites->hashSigAlgoSz == 0)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
@@ -10360,17 +10537,21 @@
         if (!IsAtLeastTLSv1_2(ssl))
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+    #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
         if (!IsAtLeastTLSv1_3(ssl->version)) {
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
-    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
+        #endif
+        #ifdef WOLFSSL_EARLY_DATA
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
+        #endif
+        #ifdef WOLFSSL_SEND_HRR_COOKIE
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+        #endif
+        #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
+        #endif
+        }
     #endif
-    #ifdef WOLFSSL_EARLY_DATA
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
-    #endif
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
-    #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
-            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
-    #endif
-        }
     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
         /* Must write Pre-shared Key extension at the end in TLS v1.3.
@@ -10393,6 +10574,7 @@
     #ifndef NO_CERTS
     else if (msgType == certificate_request) {
+        /* Don't send out any extension except those that are turned off. */
         XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
 #endif
@@ -10467,20 +10649,24 @@
                 if (IsAtLeastTLSv1_3(ssl->version)) {
                     XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-        #ifndef WOLFSSL_TLS13_DRAFT_18
                     TURN_OFF(semaphore,
                                      TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
-        #endif
+            #ifdef HAVE_SUPPORTED_CURVES
                     if (!ssl->options.noPskDheKe)
                         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+            #endif
         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
         #endif
                 }
+        #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
                 else {
+            #ifdef HAVE_SUPPORTED_CURVES
                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
-        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            #endif
+            #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+            #endif
+                }
         #endif
-                }
     #endif
             break;
@@ -10489,10 +10675,12 @@
         case hello_retry_request:
             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-        #ifndef WOLFSSL_TLS13_DRAFT_18
                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
-        #endif
+        #ifdef HAVE_SUPPORTED_CURVES
             if (!ssl->options.noPskDheKe)
                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #endif
+        #ifdef WOLFSSL_SEND_HRR_COOKIE
             TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
+        #endif
             break;
     #endif
@@ -10500,8 +10688,15 @@
     #ifdef WOLFSSL_TLS13
         case encrypted_extensions:
+            /* Send out all extension except those that are turned on. */
+        #ifdef HAVE_ECC
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+        #endif
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #ifdef HAVE_SESSION_TICKET
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
+        #endif
+        #ifdef HAVE_SUPPORTED_CURVES
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #endif
         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
@@ -10509,4 +10704,7 @@
         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
+        #endif
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
         #endif
         #if defined(HAVE_SECURE_RENEGOTIATION)
@@ -10529,4 +10727,5 @@
     #ifndef NO_CERTS
         case certificate:
+            /* Don't send out any extension except those that are turned off. */
             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
             TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
@@ -10587,20 +10786,24 @@
                 if (IsAtLeastTLSv1_3(ssl->version)) {
                     XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-        #ifndef WOLFSSL_TLS13_DRAFT_18
                     TURN_OFF(semaphore,
                                      TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
-        #endif
+            #ifdef HAVE_SUPPORTED_CURVES
                     if (!ssl->options.noPskDheKe)
                         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
-        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+            #endif
+            #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+            #endif
+                }
+        #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
+                else {
+            #ifdef HAVE_SUPPORTED_CURVES
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+            #endif
+            #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
+                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
+            #endif
+                }
         #endif
-                }
-                else {
-                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
-        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
-                    TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
-        #endif
-                }
     #endif
                 break;
@@ -10609,9 +10812,9 @@
             case hello_retry_request:
                 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
-        #ifndef WOLFSSL_TLS13_DRAFT_18
                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
-        #endif
+        #ifdef HAVE_SUPPORTED_CURVES
                 if (!ssl->options.noPskDheKe)
                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #endif
                 /* Cookie is written below as last extension. */
                 break;
@@ -10620,8 +10823,15 @@
     #ifdef WOLFSSL_TLS13
             case encrypted_extensions:
+                /* Send out all extension except those that are turned on. */
+        #ifdef HAVE_ECC
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
+        #endif
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
+        #ifdef HAVE_SESSION_TICKET
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
+        #endif
+        #ifdef HAVE_SUPPORTED_CURVES
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
+        #endif
         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
@@ -10630,4 +10840,7 @@
                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
         #endif
+        #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+            TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
+        #endif
         #if defined(HAVE_SECURE_RENEGOTIATION)
             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
@@ -10649,4 +10862,6 @@
         #ifndef NO_CERTS
             case certificate:
+                /* Don't send out any extension except those that are turned
+                 * off. */
                 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
@@ -10666,5 +10881,5 @@
             return ret;
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
         if (msgType == hello_retry_request) {
             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
@@ -10785,4 +11000,5 @@
 
         switch (type) {
+#ifdef HAVE_SNI
             case TLSX_SERVER_NAME:
                 WOLFSSL_MSG("SNI extension received");
@@ -10791,5 +11007,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SNI)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10805,4 +11021,5 @@
                 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
                 break;
+#endif
 
             case TLSX_TRUSTED_CA_KEYS:
@@ -10812,5 +11029,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_TRUSTED_CA)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10828,5 +11045,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_MAX_FRAGMENT)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10848,5 +11065,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_TRUNCATED_HMAC)
                 if (IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -10861,5 +11078,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10882,5 +11099,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
                 if (IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -10895,5 +11112,5 @@
             #endif
 
- #ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10912,5 +11129,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -10930,5 +11147,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13)
                 if (IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -10951,5 +11168,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SECURE_RENEGOTIATION)
                 if (IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -10964,5 +11181,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello) {
@@ -10979,5 +11196,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_QSH)
                 if (IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -10993,5 +11210,5 @@
             #endif
 
-#ifdef WOLFSSL_TLS13
+#if defined(WOLFSSL_TLS13) && defined(HAVE_ALPN)
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -11007,5 +11224,5 @@
                 ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
                 break;
-#if !defined(WOLFSSL_NO_SIGALG)
+#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS:
                 WOLFSSL_MSG("Signature Algorithms extension received");
@@ -11016,5 +11233,5 @@
                 if (!IsAtLeastTLSv1_2(ssl))
                     break;
-#ifdef WOLFSSL_TLS13
+            #ifdef WOLFSSL_TLS13
                 if (IsAtLeastTLSv1_3(ssl->version) &&
                         msgType != client_hello &&
@@ -11022,5 +11239,5 @@
                     return EXT_NOT_ALLOWED;
                 }
-#endif
+            #endif
                 ret = SA_PARSE(ssl, input + offset, size, isRequest, suites);
                 break;
@@ -11048,4 +11265,5 @@
                 break;
 
+    #ifdef WOLFSSL_SEND_HRR_COOKIE
             case TLSX_COOKIE:
                 WOLFSSL_MSG("Cookie extension received");
@@ -11064,4 +11282,5 @@
                 ret = CKE_PARSE(ssl, input + offset, size, msgType);
                 break;
+    #endif
 
     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -11138,5 +11357,5 @@
     #endif
 
-    #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
+    #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
             case TLSX_SIGNATURE_ALGORITHMS_CERT:
                 WOLFSSL_MSG("Signature Algorithms extension received");
@@ -11167,4 +11386,5 @@
             #endif
 
+    #ifdef HAVE_SUPPORTED_CURVES
                 if (!IsAtLeastTLSv1_3(ssl->version))
                     break;
@@ -11174,4 +11394,6 @@
                     return EXT_NOT_ALLOWED;
                 }
+    #endif
+
                 ret = KS_PARSE(ssl, input + offset, size, msgType);
                 break;
@@ -11632,4 +11854,5 @@
 
 #ifndef WOLFSSL_NO_TLS12
+    WOLFSSL_ABI
     WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
     {
@@ -11656,4 +11879,5 @@
      * returns the method data for a TLS v1.3 server.
      */
+    WOLFSSL_ABI
     WOLFSSL_METHOD* wolfTLSv1_3_server_method(void)
     {
