]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/WolfSSL/src/tls.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / src / tls.c
index edac823a92bb844866961135e0318e43e5e9ca98..f4c76d738f9e22f19fa5864946b11caf1de4c2fc 100644 (file)
@@ -1,15 +1,15 @@
 /* tls.c
  *
- * Copyright (C) 2006-2014 wolfSSL Inc.
+ * Copyright (C) 2006-2015 wolfSSL Inc.
  *
- * This file is part of CyaSSL.
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
  *
- * CyaSSL is free software; you can redistribute it and/or modify
+ * wolfSSL is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * CyaSSL is distributed in the hope that it will be useful,
+ * wolfSSL is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+
 #ifdef HAVE_CONFIG_H
     #include <config.h>
 #endif
 
-#include <cyassl/ctaocrypt/settings.h>
+#include <wolfssl/wolfcrypt/settings.h>
 
-#include <cyassl/ssl.h>
-#include <cyassl/internal.h>
-#include <cyassl/error-ssl.h>
-#include <cyassl/ctaocrypt/hmac.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/internal.h>
+#include <wolfssl/error-ssl.h>
+#include <wolfssl/wolfcrypt/hmac.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #include <wolfcrypt/src/misc.c>
+#endif
 
 
 
 #ifndef NO_TLS
 
 
-#ifndef min
+#ifndef WOLFSSL_HAVE_MIN
+#define WOLFSSL_HAVE_MIN
 
     static INLINE word32 min(word32 a, word32 b)
     {
         return a > b ? b : a;
     }
 
-#endif /* min */
+#endif /* WOLFSSL_HAVE_MIN */
 
 
-#ifdef CYASSL_SHA384
-    #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
+#ifdef WOLFSSL_SHA384
+    #define P_HASH_MAX_SIZE SHA384_DIGEST_SIZE
 #else
-    #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
+    #define P_HASH_MAX_SIZE SHA256_DIGEST_SIZE
 #endif
 
 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
 static int p_hash(byte* result, word32 resLen, const byte* secret,
                    word32 secLen, const byte* seed, word32 seedLen, int hash)
 {
-    word32   len = PHASH_MAX_DIGEST_SIZE;
-    word32   times;
-    word32   lastLen;
-    word32   lastTime;
-    word32   i;
-    word32   idx = 0;
-    int      ret;
-    byte     previous[PHASH_MAX_DIGEST_SIZE];  /* max size */
-    byte     current[PHASH_MAX_DIGEST_SIZE];   /* max size */
+    word32 len = P_HASH_MAX_SIZE;
+    word32 times;
+    word32 lastLen;
+    word32 lastTime;
+    word32 i;
+    word32 idx = 0;
+    int    ret = 0;
+#ifdef WOLFSSL_SMALL_STACK
+    byte*  previous;
+    byte*  current;
+    Hmac*  hmac;
+#else
+    byte   previous[P_HASH_MAX_SIZE];  /* max size */
+    byte   current[P_HASH_MAX_SIZE];   /* max size */
+    Hmac   hmac[1];
+#endif
 
-    Hmac hmac;
+#ifdef WOLFSSL_SMALL_STACK
+    previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (previous == NULL || current == NULL || hmac == NULL) {
+        if (previous) XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (current)  XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (hmac)     XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
 
     switch (hash) {
         #ifndef NO_MD5
-        case md5_mac:
-        {
-            len = MD5_DIGEST_SIZE;
-            hash = MD5;
-        }
-        break;
+            case md5_mac:
+                hash = MD5;
+                len  = MD5_DIGEST_SIZE;
+            break;
         #endif
+
         #ifndef NO_SHA256
-        case sha256_mac:
-        {
-            len = SHA256_DIGEST_SIZE;
-            hash = SHA256;
-        }
-        break;
+            case sha256_mac:
+                hash = SHA256;
+                len  = SHA256_DIGEST_SIZE;
+            break;
         #endif
-        #ifdef CYASSL_SHA384
-        case sha384_mac:
-        {
-            len = SHA384_DIGEST_SIZE;
-            hash = SHA384;
-        }
-        break;
+
+        #ifdef WOLFSSL_SHA384
+            case sha384_mac:
+                hash = SHA384;
+                len  = SHA384_DIGEST_SIZE;
+            break;
+        #endif
+
+        #ifndef NO_SHA
+            case sha_mac:
+            default:
+                hash = SHA;
+                len  = SHA_DIGEST_SIZE;
+            break;
         #endif
-#ifndef NO_SHA
-        case sha_mac:
-        default:
-        {
-            len = SHA_DIGEST_SIZE;
-            hash = SHA;
-        }
-        break;
-#endif
     }
 
-    times = resLen / len;
+    times   = resLen / len;
     lastLen = resLen % len;
-    if (lastLen) times += 1;
-    lastTime = times - 1;
 
-    ret = HmacSetKey(&hmac, hash, secret, secLen);
-    if (ret != 0)
-        return ret;
-    ret = HmacUpdate(&hmac, seed, seedLen);       /* A0 = seed */
-    if (ret != 0)
-        return ret;
-    ret = HmacFinal(&hmac, previous);             /* A1 */
-    if (ret != 0)
-        return ret;
+    if (lastLen)
+        times += 1;
 
-    for (i = 0; i < times; i++) {
-        ret = HmacUpdate(&hmac, previous, len);
-        if (ret != 0)
-            return ret;
-        ret = HmacUpdate(&hmac, seed, seedLen);
-        if (ret != 0)
-            return ret;
-        ret = HmacFinal(&hmac, current);
-        if (ret != 0)
-            return ret;
+    lastTime = times - 1;
 
-        if ( (i == lastTime) && lastLen)
-            XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
-        else {
-            XMEMCPY(&result[idx], current, len);
-            idx += len;
-            ret = HmacUpdate(&hmac, previous, len);
-            if (ret != 0)
-                return ret;
-            ret = HmacFinal(&hmac, previous);
-            if (ret != 0)
-                return ret;
+    if ((ret = wc_HmacSetKey(hmac, hash, secret, secLen)) == 0) {
+        if ((ret = wc_HmacUpdate(hmac, seed, seedLen)) == 0) { /* A0 = seed */
+            if ((ret = wc_HmacFinal(hmac, previous)) == 0) {   /* A1 */
+                for (i = 0; i < times; i++) {
+                    ret = wc_HmacUpdate(hmac, previous, len);
+                    if (ret != 0)
+                        break;
+                    ret = wc_HmacUpdate(hmac, seed, seedLen);
+                    if (ret != 0)
+                        break;
+                    ret = wc_HmacFinal(hmac, current);
+                    if (ret != 0)
+                        break;
+
+                    if ((i == lastTime) && lastLen)
+                        XMEMCPY(&result[idx], current,
+                                                 min(lastLen, P_HASH_MAX_SIZE));
+                    else {
+                        XMEMCPY(&result[idx], current, len);
+                        idx += len;
+                        ret = wc_HmacUpdate(hmac, previous, len);
+                        if (ret != 0)
+                            break;
+                        ret = wc_HmacFinal(hmac, previous);
+                        if (ret != 0)
+                            break;
+                    }
+                }
+            }
         }
     }
-    XMEMSET(previous, 0, sizeof previous);
-    XMEMSET(current, 0, sizeof current);
-    XMEMSET(&hmac, 0, sizeof hmac);
 
-    return 0;
+    ForceZero(previous,  P_HASH_MAX_SIZE);
+    ForceZero(current,   P_HASH_MAX_SIZE);
+    ForceZero(hmac,      sizeof(Hmac));
+
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(previous, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(current,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(hmac,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
 }
 
+#undef P_HASH_MAX_SIZE
 
 
 #ifndef NO_OLD_TLS
@@ -158,7 +187,7 @@ static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
 {
     word32 i;
 
-    for (i = 0; i < digLen; i++) 
+    for (i = 0; i < digLen; i++)
         digest[i] = md5[i] ^ sha[i];
 }
 
@@ -168,14 +197,22 @@ static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
                  const byte* label, word32 labLen, const byte* seed,
                  word32 seedLen)
 {
-    int    ret;
+    int    ret  = 0;
     word32 half = (secLen + 1) / 2;
 
-    byte md5_half[MAX_PRF_HALF];        /* half is real size */
-    byte sha_half[MAX_PRF_HALF];        /* half is real size */
-    byte labelSeed[MAX_PRF_LABSEED];    /* labLen + seedLen is real size */
-    byte md5_result[MAX_PRF_DIG];       /* digLen is real size */
-    byte sha_result[MAX_PRF_DIG];       /* digLen is real size */
+#ifdef WOLFSSL_SMALL_STACK
+    byte* md5_half;
+    byte* sha_half;
+    byte* labelSeed;
+    byte* md5_result;
+    byte* sha_result;
+#else
+    byte  md5_half[MAX_PRF_HALF];     /* half is real size */
+    byte  sha_half[MAX_PRF_HALF];     /* half is real size */
+    byte  labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
+    byte  md5_result[MAX_PRF_DIG];    /* digLen is real size */
+    byte  sha_result[MAX_PRF_DIG];    /* digLen is real size */
+#endif
 
     if (half > MAX_PRF_HALF)
         return BUFFER_E;
@@ -184,26 +221,51 @@ static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
     if (digLen > MAX_PRF_DIG)
         return BUFFER_E;
 
+#ifdef WOLFSSL_SMALL_STACK
+    md5_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha_half   = (byte*)XMALLOC(MAX_PRF_HALF,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    labelSeed  = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    md5_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    sha_result = (byte*)XMALLOC(MAX_PRF_DIG,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    if (md5_half == NULL || sha_half == NULL || labelSeed == NULL ||
+                                     md5_result == NULL || sha_result == NULL) {
+        if (md5_half)   XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha_half)   XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (labelSeed)  XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (md5_result) XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sha_result) XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+        return MEMORY_E;
+    }
+#endif
+
     XMEMSET(md5_result, 0, digLen);
     XMEMSET(sha_result, 0, digLen);
-    
+
     XMEMCPY(md5_half, secret, half);
     XMEMCPY(sha_half, secret + half - secLen % 2, half);
 
     XMEMCPY(labelSeed, label, labLen);
     XMEMCPY(labelSeed + labLen, seed, seedLen);
 
-    ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
-                 labLen + seedLen, md5_mac);
-    if (ret != 0)
-        return ret;
-    ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
-                 labLen + seedLen, sha_mac);
-    if (ret != 0)
-        return ret;
-    get_xor(digest, digLen, md5_result, sha_result);
+    if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
+                                             labLen + seedLen, md5_mac)) == 0) {
+        if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
+                                             labLen + seedLen, sha_mac)) == 0) {
+            get_xor(digest, digLen, md5_result, sha_result);
+        }
+    }
 
-    return 0;
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(md5_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha_half,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(labelSeed,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(md5_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(sha_result, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
 }
 
 #endif
@@ -218,11 +280,22 @@ static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
     int ret = 0;
 
     if (useAtLeastSha256) {
-        byte labelSeed[MAX_PRF_LABSEED];    /* labLen + seedLen is real size */
+#ifdef WOLFSSL_SMALL_STACK
+        byte* labelSeed;
+#else
+        byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
+#endif
 
         if (labLen + seedLen > MAX_PRF_LABSEED)
             return BUFFER_E;
 
+#ifdef WOLFSSL_SMALL_STACK
+        labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, NULL,
+                                                       DYNAMIC_TYPE_TMP_BUFFER);
+        if (labelSeed == NULL)
+           return MEMORY_E;
+#endif
+
         XMEMCPY(labelSeed, label, labLen);
         XMEMCPY(labelSeed + labLen, seed, seedLen);
 
@@ -232,6 +305,10 @@ static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
             hash_type = sha256_mac;
         ret = p_hash(digest, digLen, secret, secLen, labelSeed,
                      labLen + seedLen, hash_type);
+
+#ifdef WOLFSSL_SMALL_STACK
+        XFREE(labelSeed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
     }
 #ifndef NO_OLD_TLS
     else {
@@ -244,28 +321,28 @@ static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
 }
 
 
-#ifdef CYASSL_SHA384
+#ifdef WOLFSSL_SHA384
     #define HSHASH_SZ SHA384_DIGEST_SIZE
 #else
     #define HSHASH_SZ FINISHED_SZ
 #endif
 
 
-int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
+int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
 {
     const byte* side;
     byte        handshake_hash[HSHASH_SZ];
     word32      hashSz = FINISHED_SZ;
 
 #ifndef NO_OLD_TLS
-    Md5Final(&ssl->hashMd5, handshake_hash);
-    ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
+    wc_Md5GetHash(&ssl->hsHashes->hashMd5, handshake_hash);
+    wc_ShaGetHash(&ssl->hsHashes->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
 #endif
-    
+
     if (IsAtLeastTLSv1_2(ssl)) {
 #ifndef NO_SHA256
         if (ssl->specs.mac_algorithm <= sha256_mac) {
-            int ret = Sha256Final(&ssl->hashSha256, handshake_hash);
+            int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,handshake_hash);
 
             if (ret != 0)
                 return ret;
@@ -273,9 +350,9 @@ int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
             hashSz = SHA256_DIGEST_SIZE;
         }
 #endif
-#ifdef CYASSL_SHA384
+#ifdef WOLFSSL_SHA384
         if (ssl->specs.mac_algorithm == sha384_mac) {
-            int ret = Sha384Final(&ssl->hashSha384, handshake_hash);
+            int ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,handshake_hash);
 
             if (ret != 0)
                 return ret;
@@ -284,7 +361,7 @@ int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
         }
 #endif
     }
-   
+
     if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
         side = tls_client;
     else
@@ -334,76 +411,132 @@ static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
 static const byte key_label   [KEY_LABEL_SZ + 1]    = "key expansion";
 
 
-int DeriveTlsKeys(CYASSL* ssl)
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_DeriveTlsKeys(byte* key_data, word32 keyLen,
+                         const byte* ms, word32 msLen,
+                         const byte* sr, const byte* cr,
+                         int tls1_2, int hash_type)
 {
-    int ret;
-    int length = 2 * ssl->specs.hash_size + 
-                 2 * ssl->specs.key_size  +
-                 2 * ssl->specs.iv_size;
-    byte         seed[SEED_LEN];
-    byte         key_data[MAX_PRF_DIG];
+    byte  seed[SEED_LEN];
 
-    XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN);
-    XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN);
+    XMEMCPY(seed,           sr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
 
-    ret = PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN, 
-              key_label, KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
-              ssl->specs.mac_algorithm);
-    if (ret != 0)
-        return ret;
+    return PRF(key_data, keyLen, ms, msLen, key_label, KEY_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type);
+}
+
+
+int DeriveTlsKeys(WOLFSSL* ssl)
+{
+    int   ret;
+    int   length = 2 * ssl->specs.hash_size +
+                   2 * ssl->specs.key_size  +
+                   2 * ssl->specs.iv_size;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* key_data;
+#else
+    byte  key_data[MAX_PRF_DIG];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    key_data = (byte*)XMALLOC(MAX_PRF_DIG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (key_data == NULL) {
+        return MEMORY_E;
+    }
+#endif
+
+    ret = wolfSSL_DeriveTlsKeys(key_data, length,
+                           ssl->arrays->masterSecret, SECRET_LEN,
+                           ssl->arrays->serverRandom, ssl->arrays->clientRandom,
+                           IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+    if (ret == 0)
+        ret = StoreKeys(ssl, key_data);
 
-    return StoreKeys(ssl, key_data);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(key_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
+
+    return ret;
 }
 
 
-int MakeTlsMasterSecret(CYASSL* ssl)
+/* External facing wrapper so user can call as well, 0 on success */
+int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
+                               const byte* pms, word32 pmsLen,
+                               const byte* cr, const byte* sr,
+                               int tls1_2, int hash_type)
 {
-    int  ret;
-    byte seed[SEED_LEN];
-    
-    XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
-    XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
+    byte  seed[SEED_LEN];
+
+    XMEMCPY(seed,           cr, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
+
+    return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
+               seed, SEED_LEN, tls1_2, hash_type);
+}
 
-    ret = PRF(ssl->arrays->masterSecret, SECRET_LEN,
+
+int MakeTlsMasterSecret(WOLFSSL* ssl)
+{
+    int   ret;
+
+    ret = wolfSSL_MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
               ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
-              master_label, MASTER_LABEL_SZ, 
-              seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
-    if (ret != 0)
-        return ret;
+              ssl->arrays->clientRandom, ssl->arrays->serverRandom,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
 
-#ifdef SHOW_SECRETS
-    {
+    if (ret == 0) {
+    #ifdef SHOW_SECRETS
         int i;
+
         printf("master secret: ");
         for (i = 0; i < SECRET_LEN; i++)
             printf("%02x", ssl->arrays->masterSecret[i]);
         printf("\n");
+    #endif
+
+        ret = DeriveTlsKeys(ssl);
     }
-#endif
 
-    return DeriveTlsKeys(ssl);
+    return ret;
 }
 
 
 /* Used by EAP-TLS and EAP-TTLS to derive keying material from
  * the master_secret. */
-int CyaSSL_make_eap_keys(CYASSL* ssl, void* msk, unsigned int len,
+int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
                                                               const char* label)
 {
-    byte seed[SEED_LEN];
+    int   ret;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* seed;
+#else
+    byte  seed[SEED_LEN];
+#endif
+
+#ifdef WOLFSSL_SMALL_STACK
+    seed = (byte*)XMALLOC(SEED_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    if (seed == NULL)
+        return MEMORY_E;
+#endif
 
     /*
      * As per RFC-5281, the order of the client and server randoms is reversed
      * from that used by the TLS protocol to derive keys.
      */
-    XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
-    XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
+    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
+    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
+
+    ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
+              (const byte *)label, (word32)strlen(label), seed, SEED_LEN,
+              IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
 
-    return PRF((byte*)msk, len,
-               ssl->arrays->masterSecret, SECRET_LEN,
-               (const byte *)label, (word32)strlen(label),
-               seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
+#ifdef WOLFSSL_SMALL_STACK
+    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
 
+    return ret;
 }
 
 
@@ -442,9 +575,9 @@ static INLINE void c32toa(word32 u32, byte* c)
 }
 
 
-static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
+static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
 {
-#ifdef CYASSL_DTLS
+#ifdef WOLFSSL_DTLS
     if (ssl->options.dtls) {
         if (verify)
             return ssl->keys.dtls_state.curSeq; /* explicit from peer */
@@ -453,15 +586,15 @@ static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
     }
 #endif
     if (verify)
-        return ssl->keys.peer_sequence_number++; 
+        return ssl->keys.peer_sequence_number++;
     else
-        return ssl->keys.sequence_number++; 
+        return ssl->keys.sequence_number++;
 }
 
 
-#ifdef CYASSL_DTLS
+#ifdef WOLFSSL_DTLS
 
-static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
+static INLINE word32 GetEpoch(WOLFSSL* ssl, int verify)
 {
     if (verify)
         return ssl->keys.dtls_state.curEpoch;
@@ -469,14 +602,14 @@ static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
         return ssl->keys.dtls_epoch;
 }
 
-#endif /* CYASSL_DTLS */
+#endif /* WOLFSSL_DTLS */
 
 
 /*** end copy ***/
 
 
-/* return HMAC digest type in CyaSSL format */
-int CyaSSL_GetHmacType(CYASSL* ssl)
+/* return HMAC digest type in wolfSSL format */
+int wolfSSL_GetHmacType(WOLFSSL* ssl)
 {
     if (ssl == NULL)
         return BAD_FUNC_ARG;
@@ -494,7 +627,7 @@ int CyaSSL_GetHmacType(CYASSL* ssl)
             return SHA256;
         }
         #endif
-        #ifdef CYASSL_SHA384
+        #ifdef WOLFSSL_SHA384
         case sha384_mac:
         {
             return SHA384;
@@ -507,10 +640,10 @@ int CyaSSL_GetHmacType(CYASSL* ssl)
             return SHA;
         }
         #endif
-        #ifdef HAVE_BLAKE2 
+        #ifdef HAVE_BLAKE2
         case blake2b_mac:
         {
-            return BLAKE2B_ID; 
+            return BLAKE2B_ID;
         }
         #endif
         default:
@@ -521,20 +654,20 @@ int CyaSSL_GetHmacType(CYASSL* ssl)
 }
 
 
-int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content,
+int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
                            int verify)
 {
     if (ssl == NULL || inner == NULL)
         return BAD_FUNC_ARG;
 
-    XMEMSET(inner, 0, CYASSL_TLS_HMAC_INNER_SZ);
+    XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
 
-#ifdef CYASSL_DTLS
+#ifdef WOLFSSL_DTLS
     if (ssl->options.dtls)
         c16toa((word16)GetEpoch(ssl, verify), inner);
 #endif
     c32toa(GetSEQIncrement(ssl, verify), &inner[sizeof(word32)]);
-    inner[SEQ_SZ] = (byte)content;                          
+    inner[SEQ_SZ] = (byte)content;
     inner[SEQ_SZ + ENUM_LEN]            = ssl->version.major;
     inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
     c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
@@ -544,29 +677,34 @@ int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content,
 
 
 /* TLS type HMAC */
-int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
+int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
               int content, int verify)
 {
     Hmac hmac;
     int  ret;
-    byte myInner[CYASSL_TLS_HMAC_INNER_SZ];
+    byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
 
     if (ssl == NULL)
         return BAD_FUNC_ARG;
-    
-    CyaSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
 
-    ret = HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),
-                     CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
+#ifdef HAVE_FUZZER
+    if (ssl->fuzzerCb)
+        ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
+#endif
+
+    wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
+
+    ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
+                     wolfSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
     if (ret != 0)
         return ret;
-    ret = HmacUpdate(&hmac, myInner, sizeof(myInner));
+    ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
     if (ret != 0)
         return ret;
-    ret = HmacUpdate(&hmac, in, sz);                                /* content */
+    ret = wc_HmacUpdate(&hmac, in, sz);                                /* content */
     if (ret != 0)
         return ret;
-    ret = HmacFinal(&hmac, digest);
+    ret = wc_HmacFinal(&hmac, digest);
     if (ret != 0)
         return ret;
 
@@ -575,36 +713,80 @@ int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
 
 #ifdef HAVE_TLS_EXTENSIONS
 
+
+/** Supports up to 64 flags. Update as needed. */
+#define SEMAPHORE_SIZE 8
+
+
+static INLINE word16 TLSX_ToSemaphore(word16 type)
+{
+    switch (type) {
+        case SECURE_RENEGOTIATION:
+            return 63;
+
+        default:
+            if (type > 62) {
+                /* This message SHOULD only happens during the adding of
+                   new TLS extensions in which its IANA number overflows
+                   the current semaphore's range, or if its number already
+                   is assigned to be used by another extension.
+                   Use this check value for the new extension and decrement
+                   the check value by one. */
+                WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!");
+            }
+    }
+
+    return type;
+}
+
+
 #define IS_OFF(semaphore, light) \
     ((semaphore)[(light) / 8] ^  (byte) (0x01 << ((light) % 8)))
 
+
 #define TURN_ON(semaphore, light) \
     ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
 
-static int TLSX_Append(TLSX** list, TLSX_Type type)
+
+static int TLSX_Push(TLSX** list, TLSX_Type type, void* data)
 {
     TLSX* extension;
 
-    if (list == NULL) /* won't check type since this function is static */
-        return BAD_FUNC_ARG;
-
-    if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+    extension = (TLSX*)XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX);
+    if (extension == NULL)
         return MEMORY_E;
 
     extension->type = type;
-    extension->data = NULL;
+    extension->data = data;
     extension->resp = 0;
     extension->next = *list;
     *list = extension;
 
+    /* remove duplicated extensions, there should be only one of each type. */
+    do {
+        if (extension->next && extension->next->type == type) {
+            TLSX *next = extension->next;
+
+            extension->next = next->next;
+            next->next = NULL;
+
+            TLSX_FreeAll(next);
+
+            /* there is no way to occur more than */
+            /* two extensions of the same type.   */
+            break;
+        }
+    } while ((extension = extension->next));
+
     return 0;
 }
 
-#ifndef NO_CYASSL_SERVER
 
-void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type);
+#ifndef NO_WOLFSSL_SERVER
+
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
 
-void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type)
+void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
 {
     TLSX *ext = TLSX_Find(ssl->extensions, type);
 
@@ -622,7 +804,7 @@ static void TLSX_SNI_Free(SNI* sni)
 {
     if (sni) {
         switch (sni->type) {
-            case CYASSL_SNI_HOST_NAME:
+            case WOLFSSL_SNI_HOST_NAME:
                 XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
             break;
         }
@@ -652,11 +834,11 @@ static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
         return MEMORY_E;
 
     switch (type) {
-        case CYASSL_SNI_HOST_NAME: {
+        case WOLFSSL_SNI_HOST_NAME: {
             sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
 
             if (sni->data.host_name) {
-                XSTRNCPY(sni->data.host_name, (const char*) data, size);
+                XSTRNCPY(sni->data.host_name, (const char*)data, size);
                 sni->data.host_name[size] = 0;
             } else {
                 XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
@@ -673,9 +855,9 @@ static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
     sni->type = type;
     sni->next = *list;
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
     sni->options = 0;
-    sni->status  = CYASSL_SNI_NO_MATCH;
+    sni->status  = WOLFSSL_SNI_NO_MATCH;
 #endif
 
     *list = sni;
@@ -694,8 +876,8 @@ static word16 TLSX_SNI_GetSize(SNI* list)
         length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
 
         switch (sni->type) {
-            case CYASSL_SNI_HOST_NAME:
-                length += XSTRLEN((char*) sni->data.host_name);
+            case WOLFSSL_SNI_HOST_NAME:
+                length += XSTRLEN((char*)sni->data.host_name);
             break;
         }
     }
@@ -715,8 +897,8 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output)
         output[offset++] = sni->type; /* sni type */
 
         switch (sni->type) {
-            case CYASSL_SNI_HOST_NAME:
-                length = XSTRLEN((char*) sni->data.host_name);
+            case WOLFSSL_SNI_HOST_NAME:
+                length = XSTRLEN((char*)sni->data.host_name);
 
                 c16toa(length, output + offset); /* sni length */
                 offset += OPAQUE16_LEN;
@@ -743,7 +925,7 @@ static SNI* TLSX_SNI_Find(SNI *list, byte type)
     return sni;
 }
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
 {
     TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
@@ -751,7 +933,7 @@ static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
 
     if (sni) {
         sni->status = status;
-        CYASSL_MSG("SNI did match!");
+        WOLFSSL_MSG("SNI did match!");
     }
 }
 
@@ -767,10 +949,10 @@ byte TLSX_SNI_Status(TLSX* extensions, byte type)
 }
 #endif
 
-static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
+static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
                                                                  byte isRequest)
 {
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
     word16 size = 0;
     word16 offset = 0;
 #endif
@@ -788,7 +970,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
         return length ? BUFFER_ERROR : 0; /* SNI response must be empty!
                                              Nothing else to do. */
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 
     if (OPAQUE16_LEN > length)
         return BUFFER_ERROR;
@@ -813,26 +995,26 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
         if (offset + size > length)
             return BUFFER_ERROR;
 
-        if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
+        if (!(sni = TLSX_SNI_Find((SNI*)extension->data, type))) {
             continue; /* not using this SNI type */
         }
 
         switch(type) {
-            case CYASSL_SNI_HOST_NAME: {
+            case WOLFSSL_SNI_HOST_NAME: {
                 byte matched = (XSTRLEN(sni->data.host_name) == size)
                             && (XSTRNCMP(sni->data.host_name,
-                                     (const char *) input + offset, size) == 0);
+                                       (const char*)input + offset, size) == 0);
 
-                if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
+                if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
                     int r = TLSX_UseSNI(&ssl->extensions,
                                                     type, input + offset, size);
 
                     if (r != SSL_SUCCESS) return r; /* throw error */
 
                     TLSX_SNI_SetStatus(ssl->extensions, type,
-                      matched ? CYASSL_SNI_REAL_MATCH : CYASSL_SNI_FAKE_MATCH);
+                      matched ? WOLFSSL_SNI_REAL_MATCH : WOLFSSL_SNI_FAKE_MATCH);
 
-                } else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) {
+                } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
                     SendAlert(ssl, alert_fatal, unrecognized_name);
 
                     return UNKNOWN_SNI_HOST_NAME_E;
@@ -851,7 +1033,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
 
 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
 {
-    TLSX* extension = NULL;
+    TLSX* extension = TLSX_Find(*extensions, SERVER_NAME_INDICATION);
     SNI*  sni       = NULL;
     int   ret       = 0;
 
@@ -861,50 +1043,43 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
     if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
         return ret;
 
-    extension = *extensions;
-
-    /* find SNI extension if it already exists. */
-    while (extension && extension->type != SERVER_NAME_INDICATION)
-        extension = extension->next;
-
-    /* push new SNI extension if it doesn't exists. */
     if (!extension) {
-        if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
+        if ((ret = TLSX_Push(extensions, SERVER_NAME_INDICATION, (void*)sni))
+                                                                         != 0) {
             TLSX_SNI_Free(sni);
             return ret;
         }
-
-        extension = *extensions;
     }
+    else {
+        /* push new SNI object to extension data. */
+        sni->next = (SNI*)extension->data;
+        extension->data = (void*)sni;
 
-    /* push new SNI object to extension data. */
-    sni->next = (SNI*) extension->data;
-    extension->data = (void*) sni;
-
-    /* look for another server name of the same type to remove (replacement) */
-    do {
-        if (sni->next && sni->next->type == type) {
-            SNI *next = sni->next;
+        /* look for another server name of the same type to remove */
+        do {
+            if (sni->next && sni->next->type == type) {
+                SNI *next = sni->next;
 
-            sni->next = next->next;
-            TLSX_SNI_Free(next);
+                sni->next = next->next;
+                TLSX_SNI_Free(next);
 
-            break;
-        }
-    } while ((sni = sni->next));
+                break;
+            }
+        } while ((sni = sni->next));
+    }
 
     return SSL_SUCCESS;
 }
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
 {
     TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
     SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
 
-    if (sni && sni->status != CYASSL_SNI_NO_MATCH) {
+    if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
         switch (sni->type) {
-            case CYASSL_SNI_HOST_NAME:
+            case WOLFSSL_SNI_HOST_NAME:
                 *data = sni->data.host_name;
                 return XSTRLEN(*data);
         }
@@ -940,7 +1115,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
         return BUFFER_ERROR;
 
     if (clientHello[offset++] < TLSv1_MINOR)
-        return BUFFER_ERROR;
+        return SNI_UNSUPPORTED;
 
     ato16(clientHello + offset, &len16);
     offset += OPAQUE16_LEN;
@@ -1075,18 +1250,18 @@ static word16 TLSX_MFL_Write(byte* data, byte* output)
     return ENUM_LEN;
 }
 
-static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
+static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length,
                                                                  byte isRequest)
 {
     if (length != ENUM_LEN)
         return BUFFER_ERROR;
 
     switch (*input) {
-        case CYASSL_MFL_2_9 : ssl->max_fragment =  512; break;
-        case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break;
-        case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break;
-        case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break;
-        case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break;
+        case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
+        case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
+        case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
+        case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
+        case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
 
         default:
             SendAlert(ssl, alert_fatal, illegal_parameter);
@@ -1094,7 +1269,7 @@ static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
             return UNKNOWN_MAX_FRAG_LEN_E;
     }
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
     if (isRequest) {
         int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
 
@@ -1109,14 +1284,13 @@ static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
 
 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
 {
-    TLSX* extension = NULL;
-    byte* data      = NULL;
-    int   ret       = 0;
+    byte* data = NULL;
+    int   ret  = 0;
 
     if (extensions == NULL)
         return BAD_FUNC_ARG;
 
-    if (mfl < CYASSL_MFL_2_9 || CYASSL_MFL_2_13 < mfl)
+    if (mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl)
         return BAD_FUNC_ARG;
 
     if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL)
@@ -1125,29 +1299,11 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
     data[0] = mfl;
 
     /* push new MFL extension. */
-    if ((ret = TLSX_Append(extensions, MAX_FRAGMENT_LENGTH)) != 0) {
+    if ((ret = TLSX_Push(extensions, MAX_FRAGMENT_LENGTH, data)) != 0) {
         XFREE(data, 0, DYNAMIC_TYPE_TLSX);
         return ret;
     }
 
-    /* place new mfl to extension data. */
-    extension = *extensions;
-    extension->data = (void*) data;
-
-    /* remove duplicated extensions */
-    do {
-        if (extension->next && extension->next->type == MAX_FRAGMENT_LENGTH) {
-            TLSX *next = extension->next;
-
-            extension->next = next->next;
-            next->next = NULL;
-
-            TLSX_FreeAll(next);
-
-            break;
-        }
-    } while ((extension = extension->next));
-
     return SSL_SUCCESS;
 }
 
@@ -1168,27 +1324,13 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
 
 #ifdef HAVE_TRUNCATED_HMAC
 
-int TLSX_UseTruncatedHMAC(TLSX** extensions)
-{
-    int ret = 0;
-
-    if (extensions == NULL)
-        return BAD_FUNC_ARG;
-
-    if (!TLSX_Find(*extensions, TRUNCATED_HMAC))
-        if ((ret = TLSX_Append(extensions, TRUNCATED_HMAC)) != 0)
-            return ret;
-
-    return SSL_SUCCESS;
-}
-
-static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length,
+static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length,
                                                                  byte isRequest)
 {
     if (length != 0 || input == NULL)
         return BUFFER_ERROR;
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
     if (isRequest) {
         int r = TLSX_UseTruncatedHMAC(&ssl->extensions);
 
@@ -1203,6 +1345,19 @@ static int TLSX_THM_Parse(CYASSL* ssl, byte* input, word16 length,
     return 0;
 }
 
+int TLSX_UseTruncatedHMAC(TLSX** extensions)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    if ((ret = TLSX_Push(extensions, TRUNCATED_HMAC, NULL)) != 0)
+        return ret;
+
+    return SSL_SUCCESS;
+}
+
 #define THM_PARSE TLSX_THM_Parse
 
 #else
@@ -1246,9 +1401,9 @@ static int TLSX_EllipticCurve_Append(EllipticCurve** list, word16 name)
     return 0;
 }
 
-#ifndef NO_CYASSL_CLIENT
+#ifndef NO_WOLFSSL_CLIENT
 
-static void TLSX_EllipticCurve_ValidateRequest(CYASSL* ssl, byte* semaphore)
+static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
 {
     int i;
 
@@ -1257,7 +1412,7 @@ static void TLSX_EllipticCurve_ValidateRequest(CYASSL* ssl, byte* semaphore)
             return;
 
     /* No elliptic curve suite found */
-    TURN_ON(semaphore, ELLIPTIC_CURVES);
+    TURN_ON(semaphore, TLSX_ToSemaphore(ELLIPTIC_CURVES));
 }
 
 static word16 TLSX_EllipticCurve_GetSize(EllipticCurve* list)
@@ -1296,10 +1451,10 @@ static word16 TLSX_EllipticCurve_Write(EllipticCurve* list, byte* output)
     return OPAQUE16_LEN + length;
 }
 
-#endif /* NO_CYASSL_CLIENT */
-#ifndef NO_CYASSL_SERVER
+#endif /* NO_WOLFSSL_CLIENT */
+#ifndef NO_WOLFSSL_SERVER
 
-static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length,
+static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
                                                                  byte isRequest)
 {
     word16 offset;
@@ -1329,7 +1484,7 @@ static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length,
     return 0;
 }
 
-int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) {
+int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) {
     TLSX*          extension = (first == ECC_BYTE)
                              ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES)
                              : NULL;
@@ -1339,18 +1494,33 @@ int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) {
     int            sig       = 0; /* valitade signature */
     int            key       = 0; /* validate key       */
 
+    (void)oid;
+    (void)octets;
+
     if (!extension)
         return 1; /* no suite restriction */
 
     for (curve = extension->data; curve && !(sig && key); curve = curve->next) {
 
         switch (curve->name) {
-            case CYASSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break;
-            case CYASSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break;
-            case CYASSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break;
-            case CYASSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break;
-            case CYASSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break;
-            case CYASSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break;
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
+            case WOLFSSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
+            case WOLFSSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
+            case WOLFSSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
+            case WOLFSSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
+            case WOLFSSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break;
+#endif
+#if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
+            case WOLFSSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break;
+#endif
             default: continue; /* unsupported curve */
         }
 
@@ -1421,11 +1591,11 @@ int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) {
     return sig && key;
 }
 
-#endif /* NO_CYASSL_SERVER */
+#endif /* NO_WOLFSSL_SERVER */
 
 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
 {
-    TLSX*          extension = NULL;
+    TLSX*          extension = TLSX_Find(*extensions, ELLIPTIC_CURVES);
     EllipticCurve* curve     = NULL;
     int            ret       = 0;
 
@@ -1435,37 +1605,29 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
     if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
         return ret;
 
-    extension = *extensions;
-
-    /* find EllipticCurve extension if it already exists. */
-    while (extension && extension->type != ELLIPTIC_CURVES)
-        extension = extension->next;
-
-    /* push new EllipticCurve extension if it doesn't exists. */
     if (!extension) {
-        if ((ret = TLSX_Append(extensions, ELLIPTIC_CURVES)) != 0) {
+        if ((ret = TLSX_Push(extensions, ELLIPTIC_CURVES, curve)) != 0) {
             XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
             return ret;
         }
-
-        extension = *extensions;
     }
+    else {
+        /* push new EllipticCurve object to extension data. */
+        curve->next = (EllipticCurve*)extension->data;
+        extension->data = (void*)curve;
 
-    /* push new EllipticCurve object to extension data. */
-    curve->next = (EllipticCurve*) extension->data;
-    extension->data = (void*) curve;
+        /* look for another curve of the same name to remove (replacement) */
+        do {
+            if (curve->next && curve->next->name == name) {
+                EllipticCurve *next = curve->next;
 
-    /* look for another curve of the same name to remove (replacement) */
-    do {
-        if (curve->next && curve->next->name == name) {
-            EllipticCurve *next = curve->next;
+                curve->next = next->next;
+                XFREE(next, 0, DYNAMIC_TYPE_TLSX);
 
-            curve->next = next->next;
-            XFREE(next, 0, DYNAMIC_TYPE_TLSX);
-
-            break;
-        }
-    } while ((curve = curve->next));
+                break;
+            }
+        } while ((curve = curve->next));
+    }
 
     return SSL_SUCCESS;
 }
@@ -1473,7 +1635,7 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
 #define EC_FREE_ALL         TLSX_EllipticCurve_FreeAll
 #define EC_VALIDATE_REQUEST TLSX_EllipticCurve_ValidateRequest
 
-#ifndef NO_CYASSL_CLIENT
+#ifndef NO_WOLFSSL_CLIENT
 #define EC_GET_SIZE TLSX_EllipticCurve_GetSize
 #define EC_WRITE    TLSX_EllipticCurve_Write
 #else
@@ -1481,7 +1643,7 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
 #define EC_WRITE(a, b)            0
 #endif
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 #define EC_PARSE TLSX_EllipticCurve_Parse
 #else
 #define EC_PARSE(a, b, c, d)      0
@@ -1497,6 +1659,282 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
 
 #endif /* HAVE_SUPPORTED_CURVES */
 
+#ifdef HAVE_SECURE_RENEGOTIATION
+
+static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
+                                                                  int isRequest)
+{
+    byte length = OPAQUE8_LEN; /* empty info length */
+
+    if (data->enabled) {
+        /* client sends client_verify_data only */
+        length += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest)
+            length += TLS_FINISHED_SZ;
+    }
+
+    return length;
+}
+
+static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
+                                                    byte* output, int isRequest)
+{
+    word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
+
+    if (data->enabled) {
+        /* client sends client_verify_data only */
+        XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
+        offset += TLS_FINISHED_SZ;
+
+        /* server also sends server_verify_data */
+        if (!isRequest) {
+            XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
+            offset += TLS_FINISHED_SZ;
+        }
+    }
+
+    output[0] = offset - 1;  /* info length - self */
+
+    return offset;
+}
+
+static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
+                                                  word16 length, byte isRequest)
+{
+    int ret = SECURE_RENEGOTIATION_E;
+
+    if (length >= OPAQUE8_LEN) {
+        if (ssl->secure_renegotiation == NULL) {
+        #ifndef NO_WOLFSSL_SERVER
+            if (isRequest && *input == 0) {
+                ret = 0;  /* don't reply, user didn't enable */
+            }
+        #endif
+        }
+        else if (isRequest) {
+        #ifndef NO_WOLFSSL_SERVER
+            if (*input == TLS_FINISHED_SZ) {
+                /* TODO compare client_verify_data */
+                ret = 0;
+            }
+        #endif
+        }
+        else {
+        #ifndef NO_WOLFSSL_CLIENT
+            if (!ssl->secure_renegotiation->enabled) {
+                if (*input == 0) {
+                    ssl->secure_renegotiation->enabled = 1;
+                    ret = 0;
+                }
+            }
+            else if (*input == 2 * TLS_FINISHED_SZ) {
+                /* TODO compare client_verify_data and server_verify_data */
+                ret = 0;
+            }
+        #endif
+        }
+    }
+
+    if (ret != 0) {
+        /* TODO: turn on fatal error at ssl level too */
+        SendAlert(ssl, alert_fatal, handshake_failure);
+    }
+
+    return ret;
+}
+
+int TLSX_UseSecureRenegotiation(TLSX** extensions)
+{
+    int ret = 0;
+    SecureRenegotiation* data = NULL;
+
+    data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), NULL,
+                                                             DYNAMIC_TYPE_TLSX);
+    if (data == NULL)
+        return MEMORY_E;
+
+    XMEMSET(data, 0, sizeof(SecureRenegotiation));
+
+    ret = TLSX_Push(extensions, SECURE_RENEGOTIATION, data);
+    if (ret != 0) {
+        XFREE(data, 0, DYNAMIC_TYPE_TLSX);
+        return ret;
+    }
+
+    return SSL_SUCCESS;
+}
+
+
+#define SCR_FREE_ALL(data) XFREE(data, NULL, DYNAMIC_TYPE_TLSX)
+#define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
+#define SCR_WRITE          TLSX_SecureRenegotiation_Write
+#define SCR_PARSE          TLSX_SecureRenegotiation_Parse
+
+#else
+
+#define SCR_FREE_ALL(a)
+#define SCR_GET_SIZE(a, b)    0
+#define SCR_WRITE(a, b, c)    0
+#define SCR_PARSE(a, b, c, d) 0
+
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+#ifdef HAVE_SESSION_TICKET
+
+static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
+{
+    TLSX*          extension = TLSX_Find(ssl->extensions, SESSION_TICKET);
+    SessionTicket* ticket    = extension ? extension->data : NULL;
+
+    if (ticket) {
+        /* TODO validate ticket timeout here! */
+        if (ticket->lifetime == 0xfffffff) {
+            /* send empty ticket on timeout */
+            TLSX_UseSessionTicket(&ssl->extensions, NULL);
+        }
+    }
+}
+
+
+static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
+{
+    (void)isRequest;
+    return ticket ? ticket->size : 0;
+}
+
+static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
+                                                                  int isRequest)
+{
+    word16 offset = 0; /* empty ticket */
+
+    if (isRequest && ticket) {
+        XMEMCPY(output + offset, ticket->data, ticket->size);
+        offset += ticket->size;
+    }
+
+    return offset;
+}
+
+
+static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
+                                                                 byte isRequest)
+{
+    int ret = 0;
+
+    if (!isRequest) {
+        /* client side */
+        if (length != 0)
+            return BUFFER_ERROR;
+
+        ssl->expect_session_ticket = 1;
+    }
+#ifndef NO_WOLFSSL_SERVER
+    else {
+        /* server side */
+        if (ssl->ctx->ticketEncCb == NULL) {
+            WOLFSSL_MSG("Client sent session ticket, server has no callback");
+            return 0;
+        }
+
+        if (length == 0) {
+            /* blank ticket */
+            ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
+            if (ret == SSL_SUCCESS) {
+                ret = 0;
+                TLSX_SetResponse(ssl, SESSION_TICKET);  /* send blank ticket */
+                ssl->options.createTicket = 1;  /* will send ticket msg */
+                ssl->options.useTicket    = 1;
+            }
+        } else {
+            /* got actual ticket from client */
+            ret = DoClientTicket(ssl, input, length);
+            if (ret == WOLFSSL_TICKET_RET_OK) {    /* use ticket to resume */
+                WOLFSSL_MSG("Using exisitng client ticket");
+                ssl->options.useTicket = 1;
+                ssl->options.resuming  = 1;
+            } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
+                WOLFSSL_MSG("Using existing client ticket, creating new one");
+                ret = TLSX_UseSessionTicket(&ssl->extensions, NULL);
+                if (ret == SSL_SUCCESS) {
+                    ret = 0;
+                    TLSX_SetResponse(ssl, SESSION_TICKET);
+                                                    /* send blank ticket */
+                    ssl->options.createTicket = 1;  /* will send ticket msg */
+                    ssl->options.useTicket    = 1;
+                    ssl->options.resuming     = 1;
+                }
+            } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
+                WOLFSSL_MSG("Process client ticket rejected, not using");
+                ret = 0;  /* not fatal */
+            } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
+                WOLFSSL_MSG("Process client ticket fatal error, not using");
+            }
+        }
+    }
+#endif /* NO_WOLFSSL_SERVER */
+
+    return ret;
+}
+
+WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
+                                                       byte* data, word16 size)
+{
+    SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
+                                                       NULL, DYNAMIC_TYPE_TLSX);
+    if (ticket) {
+        ticket->data = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TLSX);
+        if (ticket->data == NULL) {
+            XFREE(ticket, NULL, DYNAMIC_TYPE_TLSX);
+            return NULL;
+        }
+
+        XMEMCPY(ticket->data, data, size);
+        ticket->size     = size;
+        ticket->lifetime = lifetime;
+    }
+
+    return ticket;
+}
+WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket)
+{
+    if (ticket) {
+        XFREE(ticket->data, NULL, DYNAMIC_TYPE_TLSX);
+        XFREE(ticket,       NULL, DYNAMIC_TYPE_TLSX);
+    }
+}
+
+int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket)
+{
+    int ret = 0;
+
+    if (extensions == NULL)
+        return BAD_FUNC_ARG;
+
+    /* If the ticket is NULL, the client will request a new ticket from the
+       server. Otherwise, the client will use it in the next client hello. */
+    if ((ret = TLSX_Push(extensions, SESSION_TICKET, (void*)ticket)) != 0)
+        return ret;
+
+    return SSL_SUCCESS;
+}
+
+#define STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
+#define STK_GET_SIZE         TLSX_SessionTicket_GetSize
+#define STK_WRITE            TLSX_SessionTicket_Write
+#define STK_PARSE            TLSX_SessionTicket_Parse
+
+#else
+
+#define STK_VALIDATE_REQUEST(a)
+#define STK_GET_SIZE(a, b)      0
+#define STK_WRITE(a, b, c)      0
+#define STK_PARSE(a, b, c, d)   0
+
+#endif /* HAVE_SESSION_TICKET */
+
+
 TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
 {
     TLSX* extension = list;
@@ -1516,7 +1954,7 @@ void TLSX_FreeAll(TLSX* list)
 
         switch (extension->type) {
             case SERVER_NAME_INDICATION:
-                SNI_FREE_ALL((SNI *) extension->data);
+                SNI_FREE_ALL((SNI*)extension->data);
                 break;
 
             case MAX_FRAGMENT_LENGTH:
@@ -1530,13 +1968,21 @@ void TLSX_FreeAll(TLSX* list)
             case ELLIPTIC_CURVES:
                 EC_FREE_ALL(extension->data);
                 break;
+
+            case SECURE_RENEGOTIATION:
+                SCR_FREE_ALL(extension->data);
+                break;
+
+            case SESSION_TICKET:
+                /* Nothing to do. */
+                break;
         }
 
         XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
     }
 }
 
-int TLSX_SupportExtensions(CYASSL* ssl) {
+int TLSX_SupportExtensions(WOLFSSL* ssl) {
     return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
 }
 
@@ -1551,30 +1997,39 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
         if (!isRequest && !extension->resp)
             continue; /* skip! */
 
-        if (IS_OFF(semaphore, extension->type)) {
-            /* type + data length */
-            length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
-
-            switch (extension->type) {
-                case SERVER_NAME_INDICATION:
-                    if (isRequest)
-                        length += SNI_GET_SIZE((SNI *) extension->data);
-                    break;
-                case MAX_FRAGMENT_LENGTH:
-                    length += MFL_GET_SIZE(extension->data);
-                    break;
-
-                case TRUNCATED_HMAC:
-                    /* empty extension. */
-                    break;
-
-                case ELLIPTIC_CURVES:
-                    length += EC_GET_SIZE((EllipticCurve *) extension->data);
-                    break;
-            }
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
+
+        /* type + data length */
+        length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+
+        switch (extension->type) {
+            case SERVER_NAME_INDICATION:
+                if (isRequest)
+                    length += SNI_GET_SIZE(extension->data);
+                break;
+            case MAX_FRAGMENT_LENGTH:
+                length += MFL_GET_SIZE(extension->data);
+                break;
+
+            case TRUNCATED_HMAC:
+                /* empty extension. */
+                break;
 
-            TURN_ON(semaphore, extension->type);
+            case ELLIPTIC_CURVES:
+                length += EC_GET_SIZE(extension->data);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                length += SCR_GET_SIZE(extension->data, isRequest);
+                break;
+
+            case SESSION_TICKET:
+                length += STK_GET_SIZE(extension->data, isRequest);
+                break;
         }
+
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
     }
 
     return length;
@@ -1593,56 +2048,64 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
         if (!isRequest && !extension->resp)
             continue; /* skip! */
 
-        if (IS_OFF(semaphore, extension->type)) {
-            /* extension type */
-            c16toa(extension->type, output + offset);
-            offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
-            length_offset = offset;
-
-            /* extension data should be written internally */
-            switch (extension->type) {
-                case SERVER_NAME_INDICATION:
-                    if (isRequest)
-                        offset += SNI_WRITE((SNI *) extension->data,
-                                                               output + offset);
-                    break;
-
-                case MAX_FRAGMENT_LENGTH:
-                    offset += MFL_WRITE((byte *) extension->data,
-                                                               output + offset);
-                    break;
-
-                case TRUNCATED_HMAC:
-                    /* empty extension. */
-                    break;
-
-                case ELLIPTIC_CURVES:
-                    offset += EC_WRITE((EllipticCurve *) extension->data,
-                                                               output + offset);
-                    break;
-            }
+        if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
+            continue; /* skip! */
 
-            /* writing extension data length */
-            c16toa(offset - length_offset,
-                                         output + length_offset - OPAQUE16_LEN);
+        /* extension type */
+        c16toa(extension->type, output + offset);
+        offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+        length_offset = offset;
 
-            TURN_ON(semaphore, extension->type);
+        /* extension data should be written internally */
+        switch (extension->type) {
+            case SERVER_NAME_INDICATION:
+                if (isRequest)
+                    offset += SNI_WRITE(extension->data, output + offset);
+                break;
+
+            case MAX_FRAGMENT_LENGTH:
+                offset += MFL_WRITE(extension->data, output + offset);
+                break;
+
+            case TRUNCATED_HMAC:
+                /* empty extension. */
+                break;
+
+            case ELLIPTIC_CURVES:
+                offset += EC_WRITE(extension->data, output + offset);
+                break;
+
+            case SECURE_RENEGOTIATION:
+                offset += SCR_WRITE(extension->data, output + offset,
+                                                                     isRequest);
+                break;
+
+            case SESSION_TICKET:
+                offset += STK_WRITE(extension->data, output + offset,
+                                                                     isRequest);
+                break;
         }
+
+        /* writing extension data length */
+        c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
+
+        TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
     }
 
     return offset;
 }
 
-#ifndef NO_CYASSL_CLIENT
+#ifndef NO_WOLFSSL_CLIENT
 
-word16 TLSX_GetRequestSize(CYASSL* ssl)
+word16 TLSX_GetRequestSize(WOLFSSL* ssl)
 {
     word16 length = 0;
 
     if (TLSX_SupportExtensions(ssl)) {
-        byte semaphore[16] = {0};
+        byte semaphore[SEMAPHORE_SIZE] = {0};
 
         EC_VALIDATE_REQUEST(ssl, semaphore);
+        STK_VALIDATE_REQUEST(ssl);
 
         if (ssl->extensions)
             length += TLSX_GetSize(ssl->extensions, semaphore, 1);
@@ -1660,12 +2123,12 @@ word16 TLSX_GetRequestSize(CYASSL* ssl)
     return length;
 }
 
-word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
+word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
 {
     word16 offset = 0;
 
     if (TLSX_SupportExtensions(ssl) && output) {
-        byte semaphore[16] = {0};
+        byte semaphore[SEMAPHORE_SIZE] = {0};
 
         offset += OPAQUE16_LEN; /* extensions length */
 
@@ -1706,14 +2169,14 @@ word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
     return offset;
 }
 
-#endif /* NO_CYASSL_CLIENT */
+#endif /* NO_WOLFSSL_CLIENT */
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 
-word16 TLSX_GetResponseSize(CYASSL* ssl)
+word16 TLSX_GetResponseSize(WOLFSSL* ssl)
 {
     word16 length = 0;
-    byte semaphore[16] = {0};
+    byte semaphore[SEMAPHORE_SIZE] = {0};
 
     if (TLSX_SupportExtensions(ssl))
         length += TLSX_GetSize(ssl->extensions, semaphore, 0);
@@ -1726,12 +2189,12 @@ word16 TLSX_GetResponseSize(CYASSL* ssl)
     return length;
 }
 
-word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
+word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output)
 {
     word16 offset = 0;
 
     if (TLSX_SupportExtensions(ssl) && output) {
-        byte semaphore[16] = {0};
+        byte semaphore[SEMAPHORE_SIZE] = {0};
 
         offset += OPAQUE16_LEN; /* extensions length */
 
@@ -1744,15 +2207,15 @@ word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
     return offset;
 }
 
-#endif /* NO_CYASSL_SERVER */
+#endif /* NO_WOLFSSL_SERVER */
 
-int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
+int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest,
                                                                  Suites *suites)
 {
     int ret = 0;
     word16 offset = 0;
 
-    if (!ssl || !input || !suites)
+    if (!ssl || !input || (isRequest && !suites))
         return BAD_FUNC_ARG;
 
     while (ret == 0 && offset < length) {
@@ -1773,29 +2236,41 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 
         switch (type) {
             case SERVER_NAME_INDICATION:
-                CYASSL_MSG("SNI extension received");
+                WOLFSSL_MSG("SNI extension received");
 
                 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
                 break;
 
             case MAX_FRAGMENT_LENGTH:
-                CYASSL_MSG("Max Fragment Length extension received");
+                WOLFSSL_MSG("Max Fragment Length extension received");
 
                 ret = MFL_PARSE(ssl, input + offset, size, isRequest);
                 break;
 
             case TRUNCATED_HMAC:
-                CYASSL_MSG("Truncated HMAC extension received");
+                WOLFSSL_MSG("Truncated HMAC extension received");
 
                 ret = THM_PARSE(ssl, input + offset, size, isRequest);
                 break;
 
             case ELLIPTIC_CURVES:
-                CYASSL_MSG("Elliptic Curves extension received");
+                WOLFSSL_MSG("Elliptic Curves extension received");
 
                 ret = EC_PARSE(ssl, input + offset, size, isRequest);
                 break;
 
+            case SECURE_RENEGOTIATION:
+                WOLFSSL_MSG("Secure Renegotiation extension received");
+
+                ret = SCR_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
+            case SESSION_TICKET:
+                WOLFSSL_MSG("Session Ticket extension received");
+
+                ret = STK_PARSE(ssl, input + offset, size, isRequest);
+                break;
+
             case HELLO_EXT_SIG_ALGO:
                 if (isRequest) {
                     /* do not mess with offset inside the switch! */
@@ -1811,7 +2286,7 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
                                                         HELLO_EXT_SIGALGO_MAX));
                     }
                 } else {
-                    CYASSL_MSG("Servers MUST NOT send SIG ALGO extension.");
+                    WOLFSSL_MSG("Servers MUST NOT send SIG ALGO extension.");
                 }
 
                 break;
@@ -1827,25 +2302,19 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 /* undefining semaphore macros */
 #undef IS_OFF
 #undef TURN_ON
+#undef SEMAPHORE_SIZE
 
-#elif defined(HAVE_SNI)             \
-   || defined(HAVE_MAX_FRAGMENT)    \
-   || defined(HAVE_TRUNCATED_HMAC)  \
-   || defined(HAVE_SUPPORTED_CURVES)
-
-#error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined.
-
-#endif /* HAVE_TLS_EXTENSIONS */
+#endif
 
 
-#ifndef NO_CYASSL_CLIENT
+#ifndef NO_WOLFSSL_CLIENT
 
 #ifndef NO_OLD_TLS
 
-    CYASSL_METHOD* CyaTLSv1_client_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_client_method(void)
     {
-        CYASSL_METHOD* method =
-                             (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                             (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                       DYNAMIC_TYPE_METHOD);
         if (method)
             InitSSL_Method(method, MakeTLSv1());
@@ -1853,10 +2322,10 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
     }
 
 
-    CYASSL_METHOD* CyaTLSv1_1_client_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method)
             InitSSL_Method(method, MakeTLSv1_1());
@@ -1867,10 +2336,10 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 
 #ifndef NO_SHA256   /* can't use without SHA256 */
 
-    CYASSL_METHOD* CyaTLSv1_2_client_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method)
             InitSSL_Method(method, MakeTLSv1_2());
@@ -1880,10 +2349,10 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 #endif
 
 
-    CYASSL_METHOD* CyaSSLv23_client_method(void)
+    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method) {
 #ifndef NO_SHA256         /* 1.2 requires SHA256 */
@@ -1893,41 +2362,41 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 #endif
 #ifndef NO_OLD_TLS
             method->downgrade = 1;
-#endif 
+#endif
         }
         return method;
     }
 
 
-#endif /* NO_CYASSL_CLIENT */
+#endif /* NO_WOLFSSL_CLIENT */
 
 
 
-#ifndef NO_CYASSL_SERVER
+#ifndef NO_WOLFSSL_SERVER
 
 #ifndef NO_OLD_TLS
 
-    CYASSL_METHOD* CyaTLSv1_server_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_server_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method) {
             InitSSL_Method(method, MakeTLSv1());
-            method->side = CYASSL_SERVER_END;
+            method->side = WOLFSSL_SERVER_END;
         }
         return method;
     }
 
 
-    CYASSL_METHOD* CyaTLSv1_1_server_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method) {
             InitSSL_Method(method, MakeTLSv1_1());
-            method->side = CYASSL_SERVER_END;
+            method->side = WOLFSSL_SERVER_END;
         }
         return method;
     }
@@ -1936,14 +2405,14 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 
 #ifndef NO_SHA256   /* can't use without SHA256 */
 
-    CYASSL_METHOD* CyaTLSv1_2_server_method(void)
+    WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method) {
             InitSSL_Method(method, MakeTLSv1_2());
-            method->side = CYASSL_SERVER_END;
+            method->side = WOLFSSL_SERVER_END;
         }
         return method;
     }
@@ -1951,10 +2420,10 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 #endif
 
 
-    CYASSL_METHOD* CyaSSLv23_server_method(void)
+    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
     {
-        CYASSL_METHOD* method =
-                              (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
+        WOLFSSL_METHOD* method =
+                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD), 0,
                                                        DYNAMIC_TYPE_METHOD);
         if (method) {
 #ifndef NO_SHA256         /* 1.2 requires SHA256 */
@@ -1962,7 +2431,7 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 #else
             InitSSL_Method(method, MakeTLSv1_1());
 #endif
-            method->side      = CYASSL_SERVER_END;
+            method->side      = WOLFSSL_SERVER_END;
 #ifndef NO_OLD_TLS
             method->downgrade = 1;
 #endif /* !NO_OLD_TLS */
@@ -1972,6 +2441,6 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
 
 
 
-#endif /* NO_CYASSL_SERVER */
+#endif /* NO_WOLFSSL_SERVER */
 #endif /* NO_TLS */