wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls.c Source File

tls.c

00001 /* tls.c
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 
00024 #ifdef HAVE_CONFIG_H
00025     #include <config.h>
00026 #endif
00027 
00028 #include <wolfcrypt/settings.h>
00029 
00030 #ifndef WOLFCRYPT_ONLY
00031 
00032 #include <wolfssl/ssl.h>
00033 #include <wolfssl/internal.h>
00034 #include <wolfssl/error-ssl.h>
00035 #include <wolfcrypt/hmac.h>
00036 #ifdef NO_INLINE
00037     #include <wolfcrypt/misc.h>
00038 #else
00039     #define WOLFSSL_MISC_INCLUDED
00040     #include <wolfcrypt/src/misc.c>
00041 #endif
00042 
00043 #ifdef HAVE_CURVE25519
00044     #include <wolfcrypt/curve25519.h>
00045 #endif
00046 
00047 #ifdef HAVE_NTRU
00048     #include "libntruencrypt/ntru_crypto.h"
00049     #include <wolfcrypt/random.h>
00050 #endif
00051 
00052 #ifdef HAVE_QSH
00053     static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
00054     static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name);
00055 #if defined(HAVE_NTRU)
00056     static int TLSX_CreateNtruKey(WOLFSSL* ssl, int type);
00057 #endif
00058 #endif /* HAVE_QSH */
00059 
00060 #if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
00061         !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
00062     (defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES))
00063 static int TLSX_KeyShare_IsSupported(int namedGroup);
00064 #endif
00065 
00066 #if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
00067         !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
00068     (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \
00069         !defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \
00070     ((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
00071         defined(HAVE_SUPPORTED_CURVES))
00072 static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
00073 #endif
00074 
00075 
00076 #ifndef NO_TLS
00077 
00078 /* Digest enable checks */
00079 #ifdef NO_OLD_TLS /* TLS 1.2 only */
00080     #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \
00081             !defined(WOLFSSL_SHA512)
00082         #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
00083     #endif
00084 #else  /* TLS 1.1 or older */
00085     #if defined(NO_MD5) && defined(NO_SHA)
00086         #error Must have SHA1 and MD5 enabled for old TLS
00087     #endif
00088 #endif
00089 
00090 #define HAVE_FFDHE_2048
00091 
00092 #ifdef WOLFSSL_TLS13
00093     #if !defined(NO_DH) && \
00094         !defined(HAVE_FFDHE_2048) && !defined(HAVE_FFDHE_3072) && \
00095         !defined(HAVE_FFDHE_4096) && !defined(HAVE_FFDHE_6144) && \
00096         !defined(HAVE_FFDHE_8192)
00097         #error Please configure your TLS 1.3 DH key size using either: HAVE_FFDHE_2048, HAVE_FFDHE_3072, HAVE_FFDHE_4096, HAVE_FFDHE_6144 or HAVE_FFDHE_8192
00098     #endif
00099     #if !defined(NO_RSA) && !defined(WC_RSA_PSS)
00100         #error The build option WC_RSA_PSS is required for TLS 1.3 with RSA
00101     #endif
00102 #endif
00103 
00104 
00105 #ifndef WOLFSSL_NO_TLS12
00106 
00107 #ifdef WOLFSSL_SHA384
00108     #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
00109 #else
00110     #define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE
00111 #endif
00112 
00113 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
00114 static int p_hash(byte* result, word32 resLen, const byte* secret,
00115                   word32 secLen, const byte* seed, word32 seedLen, int hash,
00116                   void* heap, int devId)
00117 {
00118     word32 len = P_HASH_MAX_SIZE;
00119     word32 times;
00120     word32 lastLen;
00121     word32 lastTime;
00122     word32 i;
00123     word32 idx = 0;
00124     int    ret = 0;
00125 #ifdef WOLFSSL_SMALL_STACK
00126     byte*  previous;
00127     byte*  current;
00128     Hmac*  hmac;
00129 #else
00130     byte   previous[P_HASH_MAX_SIZE];  /* max size */
00131     byte   current[P_HASH_MAX_SIZE];   /* max size */
00132     Hmac   hmac[1];
00133 #endif
00134 
00135 #ifdef WOLFSSL_SMALL_STACK
00136     previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
00137     current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
00138     hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    heap, DYNAMIC_TYPE_HMAC);
00139 
00140     if (previous == NULL || current == NULL || hmac == NULL) {
00141         if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
00142         if (current)  XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);
00143         if (hmac)     XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);
00144 
00145         return MEMORY_E;
00146     }
00147 #endif
00148 
00149     switch (hash) {
00150         #ifndef NO_MD5
00151             case md5_mac:
00152                 hash = WC_MD5;
00153                 len  = WC_MD5_DIGEST_SIZE;
00154             break;
00155         #endif
00156 
00157         #ifndef NO_SHA256
00158             case sha256_mac:
00159                 hash = WC_SHA256;
00160                 len  = WC_SHA256_DIGEST_SIZE;
00161             break;
00162         #endif
00163 
00164         #ifdef WOLFSSL_SHA384
00165             case sha384_mac:
00166                 hash = WC_SHA384;
00167                 len  = WC_SHA384_DIGEST_SIZE;
00168             break;
00169         #endif
00170 
00171         #ifndef NO_SHA
00172             case sha_mac:
00173             default:
00174                 hash = WC_SHA;
00175                 len  = WC_SHA_DIGEST_SIZE;
00176             break;
00177         #endif
00178     }
00179 
00180     times   = resLen / len;
00181     lastLen = resLen % len;
00182 
00183     if (lastLen)
00184         times += 1;
00185 
00186     lastTime = times - 1;
00187 
00188     ret = wc_HmacInit(hmac, heap, devId);
00189     if (ret == 0) {
00190         ret = wc_HmacSetKey(hmac, hash, secret, secLen);
00191         if (ret == 0)
00192             ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
00193         if (ret == 0)
00194             ret = wc_HmacFinal(hmac, previous);       /* A1 */
00195         if (ret == 0) {
00196             for (i = 0; i < times; i++) {
00197                 ret = wc_HmacUpdate(hmac, previous, len);
00198                 if (ret != 0)
00199                     break;
00200                 ret = wc_HmacUpdate(hmac, seed, seedLen);
00201                 if (ret != 0)
00202                     break;
00203                 ret = wc_HmacFinal(hmac, current);
00204                 if (ret != 0)
00205                     break;
00206 
00207                 if ((i == lastTime) && lastLen)
00208                     XMEMCPY(&result[idx], current,
00209                                              min(lastLen, P_HASH_MAX_SIZE));
00210                 else {
00211                     XMEMCPY(&result[idx], current, len);
00212                     idx += len;
00213                     ret = wc_HmacUpdate(hmac, previous, len);
00214                     if (ret != 0)
00215                         break;
00216                     ret = wc_HmacFinal(hmac, previous);
00217                     if (ret != 0)
00218                         break;
00219                 }
00220             }
00221         }
00222         wc_HmacFree(hmac);
00223     }
00224 
00225     ForceZero(previous,  P_HASH_MAX_SIZE);
00226     ForceZero(current,   P_HASH_MAX_SIZE);
00227     ForceZero(hmac,      sizeof(Hmac));
00228 
00229 #ifdef WOLFSSL_SMALL_STACK
00230     XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
00231     XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);
00232     XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);
00233 #endif
00234 
00235     return ret;
00236 }
00237 
00238 #undef P_HASH_MAX_SIZE
00239 
00240 #endif /* !WOLFSSL_NO_TLS12 */
00241 
00242 
00243 #ifndef NO_OLD_TLS
00244 
00245 /* calculate XOR for TLSv1 PRF */
00246 static WC_INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
00247 {
00248     word32 i;
00249 
00250     for (i = 0; i < digLen; i++)
00251         digest[i] = md5[i] ^ sha[i];
00252 }
00253 
00254 
00255 /* compute TLSv1 PRF (pseudo random function using HMAC) */
00256 static int doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
00257                  const byte* label, word32 labLen, const byte* seed,
00258                  word32 seedLen, void* heap, int devId)
00259 {
00260     int    ret  = 0;
00261     word32 half = (secLen + 1) / 2;
00262 
00263 #ifdef WOLFSSL_SMALL_STACK
00264     byte* md5_half;
00265     byte* sha_half;
00266     byte* md5_result;
00267     byte* sha_result;
00268 #else
00269     byte  md5_half[MAX_PRF_HALF];     /* half is real size */
00270     byte  sha_half[MAX_PRF_HALF];     /* half is real size */
00271     byte  md5_result[MAX_PRF_DIG];    /* digLen is real size */
00272     byte  sha_result[MAX_PRF_DIG];    /* digLen is real size */
00273 #endif
00274     DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
00275 
00276     if (half > MAX_PRF_HALF)
00277         return BUFFER_E;
00278     if (labLen + seedLen > MAX_PRF_LABSEED)
00279         return BUFFER_E;
00280     if (digLen > MAX_PRF_DIG)
00281         return BUFFER_E;
00282 
00283 #ifdef WOLFSSL_SMALL_STACK
00284     md5_half   = (byte*)XMALLOC(MAX_PRF_HALF,    heap, DYNAMIC_TYPE_DIGEST);
00285     sha_half   = (byte*)XMALLOC(MAX_PRF_HALF,    heap, DYNAMIC_TYPE_DIGEST);
00286     md5_result = (byte*)XMALLOC(MAX_PRF_DIG,     heap, DYNAMIC_TYPE_DIGEST);
00287     sha_result = (byte*)XMALLOC(MAX_PRF_DIG,     heap, DYNAMIC_TYPE_DIGEST);
00288 
00289     if (md5_half == NULL || sha_half == NULL || md5_result == NULL ||
00290                                                            sha_result == NULL) {
00291         if (md5_half)   XFREE(md5_half,   heap, DYNAMIC_TYPE_DIGEST);
00292         if (sha_half)   XFREE(sha_half,   heap, DYNAMIC_TYPE_DIGEST);
00293         if (md5_result) XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
00294         if (sha_result) XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
00295         FREE_VAR(labelSeed, heap);
00296 
00297         return MEMORY_E;
00298     }
00299 #endif
00300 
00301     XMEMSET(md5_result, 0, digLen);
00302     XMEMSET(sha_result, 0, digLen);
00303 
00304     XMEMCPY(md5_half, secret, half);
00305     XMEMCPY(sha_half, secret + half - secLen % 2, half);
00306 
00307     XMEMCPY(labelSeed, label, labLen);
00308     XMEMCPY(labelSeed + labLen, seed, seedLen);
00309 
00310     if ((ret = p_hash(md5_result, digLen, md5_half, half, labelSeed,
00311                                 labLen + seedLen, md5_mac, heap, devId)) == 0) {
00312         if ((ret = p_hash(sha_result, digLen, sha_half, half, labelSeed,
00313                                 labLen + seedLen, sha_mac, heap, devId)) == 0) {
00314             get_xor(digest, digLen, md5_result, sha_result);
00315         }
00316     }
00317 
00318 #ifdef WOLFSSL_SMALL_STACK
00319     XFREE(md5_half,   heap, DYNAMIC_TYPE_DIGEST);
00320     XFREE(sha_half,   heap, DYNAMIC_TYPE_DIGEST);
00321     XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);
00322     XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
00323 #endif
00324 
00325     FREE_VAR(labelSeed, heap);
00326 
00327     return ret;
00328 }
00329 
00330 #endif
00331 
00332 
00333 #ifndef WOLFSSL_NO_TLS12
00334 
00335 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
00336    use */
00337 static int PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
00338             const byte* label, word32 labLen, const byte* seed, word32 seedLen,
00339             int useAtLeastSha256, int hash_type, void* heap, int devId)
00340 {
00341     int ret = 0;
00342 
00343     if (useAtLeastSha256) {
00344         DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
00345 
00346         if (labLen + seedLen > MAX_PRF_LABSEED)
00347             return BUFFER_E;
00348 
00349         XMEMCPY(labelSeed, label, labLen);
00350         XMEMCPY(labelSeed + labLen, seed, seedLen);
00351 
00352         /* If a cipher suite wants an algorithm better than sha256, it
00353          * should use better. */
00354         if (hash_type < sha256_mac || hash_type == blake2b_mac)
00355             hash_type = sha256_mac;
00356         ret = p_hash(digest, digLen, secret, secLen, labelSeed,
00357                      labLen + seedLen, hash_type, heap, devId);
00358 
00359         FREE_VAR(labelSeed, heap);
00360     }
00361 #ifndef NO_OLD_TLS
00362     else {
00363         ret = doPRF(digest, digLen, secret, secLen, label, labLen, seed,
00364                     seedLen, heap, devId);
00365     }
00366 #endif
00367 
00368     return ret;
00369 }
00370 
00371 #ifdef WOLFSSL_SHA384
00372     #define HSHASH_SZ WC_SHA384_DIGEST_SIZE
00373 #else
00374     #define HSHASH_SZ FINISHED_SZ
00375 #endif
00376 
00377 
00378 int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
00379 {
00380     word32 hashSz = FINISHED_SZ;
00381 
00382     if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ)
00383         return BAD_FUNC_ARG;
00384 
00385 #ifndef NO_OLD_TLS
00386     wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash);
00387     wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[WC_MD5_DIGEST_SIZE]);
00388 #endif
00389 
00390     if (IsAtLeastTLSv1_2(ssl)) {
00391 #ifndef NO_SHA256
00392         if (ssl->specs.mac_algorithm <= sha256_mac ||
00393             ssl->specs.mac_algorithm == blake2b_mac) {
00394             int ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
00395 
00396             if (ret != 0)
00397                 return ret;
00398 
00399             hashSz = WC_SHA256_DIGEST_SIZE;
00400         }
00401 #endif
00402 #ifdef WOLFSSL_SHA384
00403         if (ssl->specs.mac_algorithm == sha384_mac) {
00404             int ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
00405 
00406             if (ret != 0)
00407                 return ret;
00408 
00409             hashSz = WC_SHA384_DIGEST_SIZE;
00410         }
00411 #endif
00412     }
00413 
00414     *hashLen = hashSz;
00415 
00416     return 0;
00417 }
00418 
00419 
00420 int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
00421 {
00422     int         ret;
00423     const byte* side;
00424     byte*       handshake_hash;
00425     word32      hashSz = HSHASH_SZ;
00426 
00427     /* using allocate here to allow async hardware to use buffer directly */
00428     handshake_hash = (byte*)XMALLOC(hashSz, ssl->heap, DYNAMIC_TYPE_DIGEST);
00429     if (handshake_hash == NULL)
00430         return MEMORY_E;
00431 
00432     ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
00433     if (ret == 0) {
00434         if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
00435             side = tls_client;
00436         else
00437             side = tls_server;
00438 
00439         ret = PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret,
00440                    SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz,
00441                    IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
00442                    ssl->heap, ssl->devId);
00443     }
00444 
00445     XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
00446 
00447     return ret;
00448 }
00449 
00450 #endif /* !WOLFSSL_NO_TLS12 */
00451 
00452 #ifndef NO_OLD_TLS
00453 
00454 #ifdef WOLFSSL_ALLOW_TLSV10
00455 ProtocolVersion MakeTLSv1(void)
00456 {
00457     ProtocolVersion pv;
00458     pv.major = SSLv3_MAJOR;
00459     pv.minor = TLSv1_MINOR;
00460 
00461     return pv;
00462 }
00463 #endif /* WOLFSSL_ALLOW_TLSV10 */
00464 
00465 
00466 ProtocolVersion MakeTLSv1_1(void)
00467 {
00468     ProtocolVersion pv;
00469     pv.major = SSLv3_MAJOR;
00470     pv.minor = TLSv1_1_MINOR;
00471 
00472     return pv;
00473 }
00474 
00475 #endif /* !NO_OLD_TLS */
00476 
00477 
00478 #ifndef WOLFSSL_NO_TLS12
00479 
00480 ProtocolVersion MakeTLSv1_2(void)
00481 {
00482     ProtocolVersion pv;
00483     pv.major = SSLv3_MAJOR;
00484     pv.minor = TLSv1_2_MINOR;
00485 
00486     return pv;
00487 }
00488 
00489 #endif /* !WOLFSSL_NO_TLS12 */
00490 
00491 #ifdef WOLFSSL_TLS13
00492 /* The TLS v1.3 protocol version.
00493  *
00494  * returns the protocol version data for TLS v1.3.
00495  */
00496 ProtocolVersion MakeTLSv1_3(void)
00497 {
00498     ProtocolVersion pv;
00499     pv.major = SSLv3_MAJOR;
00500     pv.minor = TLSv1_3_MINOR;
00501 
00502     return pv;
00503 }
00504 #endif
00505 
00506 #ifndef WOLFSSL_NO_TLS12
00507 
00508 #ifdef HAVE_EXTENDED_MASTER
00509 static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] =
00510                                                       "extended master secret";
00511 #endif
00512 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
00513 static const byte key_label   [KEY_LABEL_SZ + 1]    = "key expansion";
00514 
00515 static int _DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
00516                          const byte* ms, word32 msLen,
00517                          const byte* sr, const byte* cr,
00518                          int tls1_2, int hash_type,
00519                          void* heap, int devId)
00520 {
00521     int ret;
00522     DECLARE_VAR(seed, byte, SEED_LEN, heap);
00523 
00524     XMEMCPY(seed,           sr, RAN_LEN);
00525     XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
00526 
00527     ret = PRF(key_dig, key_dig_len, ms, msLen, key_label, KEY_LABEL_SZ,
00528                seed, SEED_LEN, tls1_2, hash_type, heap, devId);
00529 
00530     FREE_VAR(seed, heap);
00531 
00532     return ret;
00533 }
00534 
00535 /* External facing wrapper so user can call as well, 0 on success */
00536 int wolfSSL_DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
00537                          const byte* ms, word32 msLen,
00538                          const byte* sr, const byte* cr,
00539                          int tls1_2, int hash_type)
00540 {
00541     return _DeriveTlsKeys(key_dig, key_dig_len, ms, msLen, sr, cr, tls1_2,
00542         hash_type, NULL, INVALID_DEVID);
00543 }
00544 
00545 
00546 int DeriveTlsKeys(WOLFSSL* ssl)
00547 {
00548     int   ret;
00549     int   key_dig_len = 2 * ssl->specs.hash_size +
00550                         2 * ssl->specs.key_size  +
00551                         2 * ssl->specs.iv_size;
00552 #ifdef WOLFSSL_SMALL_STACK
00553     byte* key_dig;
00554 #else
00555     byte  key_dig[MAX_PRF_DIG];
00556 #endif
00557 
00558 #ifdef WOLFSSL_SMALL_STACK
00559     key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST);
00560     if (key_dig == NULL) {
00561         return MEMORY_E;
00562     }
00563 #endif
00564 
00565     ret = _DeriveTlsKeys(key_dig, key_dig_len,
00566                          ssl->arrays->masterSecret, SECRET_LEN,
00567                          ssl->arrays->serverRandom, ssl->arrays->clientRandom,
00568                          IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
00569                          ssl->heap, ssl->devId);
00570     if (ret == 0)
00571         ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER);
00572 
00573 #ifdef WOLFSSL_SMALL_STACK
00574     XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
00575 #endif
00576 
00577     return ret;
00578 }
00579 
00580 static int _MakeTlsMasterSecret(byte* ms, word32 msLen,
00581                                const byte* pms, word32 pmsLen,
00582                                const byte* cr, const byte* sr,
00583                                int tls1_2, int hash_type,
00584                                void* heap, int devId)
00585 {
00586     byte  seed[SEED_LEN];
00587 
00588     XMEMCPY(seed,           cr, RAN_LEN);
00589     XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
00590 
00591     return PRF(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
00592                seed, SEED_LEN, tls1_2, hash_type, heap, devId);
00593 }
00594 
00595 /* External facing wrapper so user can call as well, 0 on success */
00596 int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
00597                                const byte* pms, word32 pmsLen,
00598                                const byte* cr, const byte* sr,
00599                                int tls1_2, int hash_type)
00600 {
00601     return _MakeTlsMasterSecret(ms, msLen, pms, pmsLen, cr, sr, tls1_2,
00602         hash_type, NULL, INVALID_DEVID);
00603 }
00604 
00605 
00606 #ifdef HAVE_EXTENDED_MASTER
00607 
00608 static int _MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
00609                                         const byte* pms, word32 pmsLen,
00610                                         const byte* sHash, word32 sHashLen,
00611                                         int tls1_2, int hash_type,
00612                                         void* heap, int devId)
00613 {
00614     return PRF(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ,
00615                sHash, sHashLen, tls1_2, hash_type, heap, devId);
00616 }
00617 
00618 /* External facing wrapper so user can call as well, 0 on success */
00619 int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
00620                                         const byte* pms, word32 pmsLen,
00621                                         const byte* sHash, word32 sHashLen,
00622                                         int tls1_2, int hash_type)
00623 {
00624     return _MakeTlsExtendedMasterSecret(ms, msLen, pms, pmsLen, sHash, sHashLen,
00625         tls1_2, hash_type, NULL, INVALID_DEVID);
00626 }
00627 
00628 #endif /* HAVE_EXTENDED_MASTER */
00629 
00630 
00631 int MakeTlsMasterSecret(WOLFSSL* ssl)
00632 {
00633     int    ret;
00634 #ifdef HAVE_EXTENDED_MASTER
00635     if (ssl->options.haveEMS) {
00636         byte*  handshake_hash;
00637         word32 hashSz = HSHASH_SZ;
00638 
00639         handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap,
00640                                         DYNAMIC_TYPE_DIGEST);
00641         if (handshake_hash == NULL)
00642             return MEMORY_E;
00643 
00644         ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
00645         if (ret < 0) {
00646             XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
00647             return ret;
00648         }
00649 
00650         ret = _MakeTlsExtendedMasterSecret(
00651                 ssl->arrays->masterSecret, SECRET_LEN,
00652                 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
00653                 handshake_hash, hashSz,
00654                 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
00655                 ssl->heap, ssl->devId);
00656 
00657         XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
00658     } else
00659 #endif
00660     ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret, SECRET_LEN,
00661               ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
00662               ssl->arrays->clientRandom, ssl->arrays->serverRandom,
00663               IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
00664               ssl->heap, ssl->devId);
00665 
00666     if (ret == 0) {
00667     #ifdef SHOW_SECRETS
00668         int i;
00669 
00670         printf("master secret: ");
00671         for (i = 0; i < SECRET_LEN; i++)
00672             printf("%02x", ssl->arrays->masterSecret[i]);
00673         printf("\n");
00674     #endif
00675 
00676         ret = DeriveTlsKeys(ssl);
00677     }
00678 
00679     return ret;
00680 }
00681 
00682 
00683 /* Used by EAP-TLS and EAP-TTLS to derive keying material from
00684  * the master_secret. */
00685 int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* msk, unsigned int len,
00686                                                               const char* label)
00687 {
00688     int   ret;
00689 #ifdef WOLFSSL_SMALL_STACK
00690     byte* seed;
00691 #else
00692     byte  seed[SEED_LEN];
00693 #endif
00694 
00695 #ifdef WOLFSSL_SMALL_STACK
00696     seed = (byte*)XMALLOC(SEED_LEN, ssl->heap, DYNAMIC_TYPE_SEED);
00697     if (seed == NULL)
00698         return MEMORY_E;
00699 #endif
00700 
00701     /*
00702      * As per RFC-5281, the order of the client and server randoms is reversed
00703      * from that used by the TLS protocol to derive keys.
00704      */
00705     XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
00706     XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
00707 
00708     ret = PRF((byte*)msk, len, ssl->arrays->masterSecret, SECRET_LEN,
00709               (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN,
00710               IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
00711               ssl->heap, ssl->devId);
00712 
00713 #ifdef WOLFSSL_SMALL_STACK
00714     XFREE(seed, ssl->heap, DYNAMIC_TYPE_SEED);
00715 #endif
00716 
00717     return ret;
00718 }
00719 
00720 
00721 static WC_INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2])
00722 {
00723     if (verify) {
00724         seq[0] = ssl->keys.peer_sequence_number_hi;
00725         seq[1] = ssl->keys.peer_sequence_number_lo++;
00726         if (seq[1] > ssl->keys.peer_sequence_number_lo) {
00727             /* handle rollover */
00728             ssl->keys.peer_sequence_number_hi++;
00729         }
00730     }
00731     else {
00732         seq[0] = ssl->keys.sequence_number_hi;
00733         seq[1] = ssl->keys.sequence_number_lo++;
00734         if (seq[1] > ssl->keys.sequence_number_lo) {
00735             /* handle rollover */
00736             ssl->keys.sequence_number_hi++;
00737         }
00738     }
00739 }
00740 
00741 
00742 #ifdef WOLFSSL_DTLS
00743 static WC_INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2])
00744 {
00745     if (order == PREV_ORDER) {
00746         /* Previous epoch case */
00747         seq[0] = ((ssl->keys.dtls_epoch - 1) << 16) |
00748                  (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF);
00749         seq[1] = ssl->keys.dtls_prev_sequence_number_lo;
00750     }
00751     else if (order == PEER_ORDER) {
00752         seq[0] = (ssl->keys.curEpoch << 16) |
00753                  (ssl->keys.curSeq_hi & 0xFFFF);
00754         seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */
00755     }
00756     else {
00757         seq[0] = (ssl->keys.dtls_epoch << 16) |
00758                  (ssl->keys.dtls_sequence_number_hi & 0xFFFF);
00759         seq[1] = ssl->keys.dtls_sequence_number_lo;
00760     }
00761 }
00762 #endif /* WOLFSSL_DTLS */
00763 
00764 
00765 static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
00766 {
00767     word32 seq[2] = {0, 0};
00768 
00769     if (!ssl->options.dtls) {
00770         GetSEQIncrement(ssl, verifyOrder, seq);
00771     }
00772     else {
00773 #ifdef WOLFSSL_DTLS
00774         DtlsGetSEQ(ssl, verifyOrder, seq);
00775 #endif
00776     }
00777 
00778     c32toa(seq[0], out);
00779     c32toa(seq[1], out + OPAQUE32_LEN);
00780 }
00781 
00782 
00783 /*** end copy ***/
00784 
00785 
00786 /* return HMAC digest type in wolfSSL format */
00787 int wolfSSL_GetHmacType(WOLFSSL* ssl)
00788 {
00789     if (ssl == NULL)
00790         return BAD_FUNC_ARG;
00791 
00792     switch (ssl->specs.mac_algorithm) {
00793         #ifndef NO_MD5
00794         case md5_mac:
00795         {
00796             return WC_MD5;
00797         }
00798         #endif
00799         #ifndef NO_SHA256
00800         case sha256_mac:
00801         {
00802             return WC_SHA256;
00803         }
00804         #endif
00805         #ifdef WOLFSSL_SHA384
00806         case sha384_mac:
00807         {
00808             return WC_SHA384;
00809         }
00810 
00811         #endif
00812         #ifndef NO_SHA
00813         case sha_mac:
00814         {
00815             return WC_SHA;
00816         }
00817         #endif
00818         #ifdef HAVE_BLAKE2
00819         case blake2b_mac:
00820         {
00821             return BLAKE2B_ID;
00822         }
00823         #endif
00824         default:
00825         {
00826             return WOLFSSL_FATAL_ERROR;
00827         }
00828     }
00829 }
00830 
00831 
00832 int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
00833                            int verify)
00834 {
00835     if (ssl == NULL || inner == NULL)
00836         return BAD_FUNC_ARG;
00837 
00838     XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
00839 
00840     WriteSEQ(ssl, verify, inner);
00841     inner[SEQ_SZ] = (byte)content;
00842     inner[SEQ_SZ + ENUM_LEN]            = ssl->version.major;
00843     inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
00844     c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
00845 
00846     return 0;
00847 }
00848 
00849 
00850 #if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
00851     !defined(HAVE_SELFTEST)
00852 
00853 /* Update the hash in the HMAC.
00854  *
00855  * hmac  HMAC object.
00856  * data  Data to be hashed.
00857  * sz    Size of data to hash.
00858  * returns 0 on success, otherwise failure.
00859  */
00860 static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz)
00861 {
00862     int ret = BAD_FUNC_ARG;
00863 
00864     switch (hmac->macType) {
00865     #ifndef NO_SHA
00866         case WC_SHA:
00867             ret = wc_ShaUpdate(&hmac->hash.sha, data, sz);
00868             break;
00869     #endif /* !NO_SHA */
00870 
00871     #ifndef NO_SHA256
00872         case WC_SHA256:
00873             ret = wc_Sha256Update(&hmac->hash.sha256, data, sz);
00874             break;
00875     #endif /* !NO_SHA256 */
00876 
00877     #ifdef WOLFSSL_SHA384
00878         case WC_SHA384:
00879             ret = wc_Sha384Update(&hmac->hash.sha384, data, sz);
00880             break;
00881     #endif /* WOLFSSL_SHA384 */
00882 
00883     #ifdef WOLFSSL_SHA512
00884         case WC_SHA512:
00885             ret = wc_Sha512Update(&hmac->hash.sha512, data, sz);
00886             break;
00887     #endif /* WOLFSSL_SHA512 */
00888     }
00889 
00890     return ret;
00891 }
00892 
00893 /* Finalize the hash but don't put the EOC, padding or length in.
00894  *
00895  * hmac  HMAC object.
00896  * hash  Hash result.
00897  * returns 0 on success, otherwise failure.
00898  */
00899 static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash)
00900 {
00901     int ret = BAD_FUNC_ARG;
00902 
00903     switch (hmac->macType) {
00904     #ifndef NO_SHA
00905         case WC_SHA:
00906             ret = wc_ShaFinalRaw(&hmac->hash.sha, hash);
00907             break;
00908     #endif /* !NO_SHA */
00909 
00910     #ifndef NO_SHA256
00911         case WC_SHA256:
00912             ret = wc_Sha256FinalRaw(&hmac->hash.sha256, hash);
00913             break;
00914     #endif /* !NO_SHA256 */
00915 
00916     #ifdef WOLFSSL_SHA384
00917         case WC_SHA384:
00918             ret = wc_Sha384FinalRaw(&hmac->hash.sha384, hash);
00919             break;
00920     #endif /* WOLFSSL_SHA384 */
00921 
00922     #ifdef WOLFSSL_SHA512
00923         case WC_SHA512:
00924             ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash);
00925             break;
00926     #endif /* WOLFSSL_SHA512 */
00927     }
00928 
00929     return ret;
00930 }
00931 
00932 /* Finalize the HMAC by performing outer hash.
00933  *
00934  * hmac  HMAC object.
00935  * mac   MAC result.
00936  * returns 0 on success, otherwise failure.
00937  */
00938 static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
00939 {
00940     int ret = BAD_FUNC_ARG;
00941 
00942     switch (hmac->macType) {
00943     #ifndef NO_SHA
00944         case WC_SHA:
00945             ret = wc_InitSha(&hmac->hash.sha);
00946             if (ret == 0)
00947                 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
00948                                                              WC_SHA_BLOCK_SIZE);
00949             if (ret == 0)
00950                 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
00951                                                             WC_SHA_DIGEST_SIZE);
00952             if (ret == 0)
00953                 ret = wc_ShaFinal(&hmac->hash.sha, mac);
00954             break;
00955     #endif /* !NO_SHA */
00956 
00957     #ifndef NO_SHA256
00958         case WC_SHA256:
00959             ret = wc_InitSha256(&hmac->hash.sha256);
00960             if (ret == 0)
00961                 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
00962                                                           WC_SHA256_BLOCK_SIZE);
00963             if (ret == 0)
00964                 ret = wc_Sha256Update(&hmac->hash.sha256,
00965                                                          (byte*)hmac->innerHash,
00966                                                          WC_SHA256_DIGEST_SIZE);
00967             if (ret == 0)
00968                 ret = wc_Sha256Final(&hmac->hash.sha256, mac);
00969             break;
00970     #endif /* !NO_SHA256 */
00971 
00972     #ifdef WOLFSSL_SHA384
00973         case WC_SHA384:
00974             ret = wc_InitSha384(&hmac->hash.sha384);
00975             if (ret == 0)
00976                 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
00977                                                           WC_SHA384_BLOCK_SIZE);
00978             if (ret == 0)
00979                 ret = wc_Sha384Update(&hmac->hash.sha384,
00980                                                          (byte*)hmac->innerHash,
00981                                                          WC_SHA384_DIGEST_SIZE);
00982             if (ret == 0)
00983                 ret = wc_Sha384Final(&hmac->hash.sha384, mac);
00984             break;
00985     #endif /* WOLFSSL_SHA384 */
00986 
00987     #ifdef WOLFSSL_SHA512
00988         case WC_SHA512:
00989             ret = wc_InitSha512(&hmac->hash.sha512);
00990             if (ret == 0)
00991                 ret = wc_Sha512Update(&hmac->hash.sha512,(byte*)hmac->opad,
00992                                                           WC_SHA512_BLOCK_SIZE);
00993             if (ret == 0)
00994                 ret = wc_Sha512Update(&hmac->hash.sha512,
00995                                                          (byte*)hmac->innerHash,
00996                                                          WC_SHA512_DIGEST_SIZE);
00997             if (ret == 0)
00998                 ret = wc_Sha512Final(&hmac->hash.sha512, mac);
00999             break;
01000     #endif /* WOLFSSL_SHA512 */
01001     }
01002 
01003     return ret;
01004 }
01005 
01006 /* Calculate the HMAC of the header + message data.
01007  * Constant time implementation using wc_Sha*FinalRaw().
01008  *
01009  * hmac    HMAC object.
01010  * digest  MAC result.
01011  * in      Message data.
01012  * sz      Size of the message data.
01013  * header  Constructed record header with length of handshake data.
01014  * returns 0 on success, otherwise failure.
01015  */
01016 static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
01017                                word32 sz, byte* header)
01018 {
01019     byte lenBytes[8];
01020     int  i, j, k;
01021     int  blockBits, blockMask;
01022     int  realLen, lastBlockLen, macLen, extraLen, eocIndex;
01023     int  blocks, safeBlocks, lenBlock, eocBlock;
01024     int  maxLen;
01025     int  blockSz, padSz;
01026     int  ret;
01027     byte extraBlock;
01028 
01029     switch (hmac->macType) {
01030     #ifndef NO_SHA
01031         case WC_SHA:
01032             blockSz = WC_SHA_BLOCK_SIZE;
01033             blockBits = 6;
01034             macLen = WC_SHA_DIGEST_SIZE;
01035             padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
01036             break;
01037     #endif /* !NO_SHA */
01038 
01039     #ifndef NO_SHA256
01040         case WC_SHA256:
01041             blockSz = WC_SHA256_BLOCK_SIZE;
01042             blockBits = 6;
01043             macLen = WC_SHA256_DIGEST_SIZE;
01044             padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
01045             break;
01046     #endif /* !NO_SHA256 */
01047 
01048     #ifdef WOLFSSL_SHA384
01049         case WC_SHA384:
01050             blockSz = WC_SHA384_BLOCK_SIZE;
01051             blockBits = 7;
01052             macLen = WC_SHA384_DIGEST_SIZE;
01053             padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
01054             break;
01055     #endif /* WOLFSSL_SHA384 */
01056 
01057     #ifdef WOLFSSL_SHA512
01058         case WC_SHA512:
01059             blockSz = WC_SHA512_BLOCK_SIZE;
01060             blockBits = 7;
01061             macLen = WC_SHA512_DIGEST_SIZE;
01062             padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
01063             break;
01064     #endif /* WOLFSSL_SHA512 */
01065 
01066         default:
01067             return BAD_FUNC_ARG;
01068     }
01069     blockMask = blockSz - 1;
01070 
01071     /* Size of data to HMAC if padding length byte is zero. */
01072     maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - macLen;
01073     /* Complete data (including padding) has block for EOC and/or length. */
01074     extraBlock = ctSetLTE((maxLen + padSz) & blockMask, padSz);
01075     /* Total number of blocks for data including padding. */
01076     blocks = ((maxLen + blockSz - 1) >> blockBits) + extraBlock;
01077     /* Up to last 6 blocks can be hashed safely. */
01078     safeBlocks = blocks - 6;
01079 
01080     /* Length of message data. */
01081     realLen = maxLen - in[sz - 1];
01082     /* Number of message bytes in last block. */
01083     lastBlockLen = realLen & blockMask;
01084     /* Number of padding bytes in last block. */
01085     extraLen = ((blockSz * 2 - padSz - lastBlockLen) & blockMask) + 1;
01086     /* Number of blocks to create for hash. */
01087     lenBlock = (realLen + extraLen) >> blockBits;
01088     /* Block containing EOC byte. */
01089     eocBlock = realLen >> blockBits;
01090     /* Index of EOC byte in block. */
01091     eocIndex = realLen & blockMask;
01092 
01093     /* Add length of hmac's ipad to total length. */
01094     realLen += blockSz;
01095     /* Length as bits - 8 bytes bigendian. */
01096     c32toa(realLen >> ((sizeof(word32) * 8) - 3), lenBytes);
01097     c32toa(realLen << 3, lenBytes + sizeof(word32));
01098 
01099     ret = Hmac_HashUpdate(hmac, (unsigned char*)hmac->ipad, blockSz);
01100     if (ret != 0)
01101         return ret;
01102 
01103     XMEMSET(hmac->innerHash, 0, macLen);
01104 
01105     if (safeBlocks > 0) {
01106         ret = Hmac_HashUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
01107         if (ret != 0)
01108             return ret;
01109         ret = Hmac_HashUpdate(hmac, in, safeBlocks * blockSz -
01110                                                      WOLFSSL_TLS_HMAC_INNER_SZ);
01111         if (ret != 0)
01112             return ret;
01113     }
01114     else
01115         safeBlocks = 0;
01116 
01117     XMEMSET(digest, 0, macLen);
01118     k = safeBlocks * blockSz;
01119     for (i = safeBlocks; i < blocks; i++) {
01120         unsigned char hashBlock[WC_MAX_BLOCK_SIZE];
01121         unsigned char isEocBlock = ctMaskEq(i, eocBlock);
01122         unsigned char isOutBlock = ctMaskEq(i, lenBlock);
01123 
01124         for (j = 0; j < blockSz; j++, k++) {
01125             unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock;
01126             unsigned char pastEoc = ctMaskGT(j, eocIndex) & isEocBlock;
01127             unsigned char b = 0;
01128 
01129             if (k < WOLFSSL_TLS_HMAC_INNER_SZ)
01130                 b = header[k];
01131             else if (k < maxLen)
01132                 b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
01133 
01134             b = ctMaskSel(atEoc, b, 0x80);
01135             b &= (unsigned char)~(word32)pastEoc;
01136             b &= ((unsigned char)~(word32)isOutBlock) | isEocBlock;
01137 
01138             if (j >= blockSz - 8) {
01139                 b = ctMaskSel(isOutBlock, b, lenBytes[j - (blockSz - 8)]);
01140             }
01141 
01142             hashBlock[j] = b;
01143         }
01144 
01145         ret = Hmac_HashUpdate(hmac, hashBlock, blockSz);
01146         if (ret != 0)
01147             return ret;
01148         ret = Hmac_HashFinalRaw(hmac, hashBlock);
01149         if (ret != 0)
01150             return ret;
01151         for (j = 0; j < macLen; j++)
01152             ((unsigned char*)hmac->innerHash)[j] |= hashBlock[j] & isOutBlock;
01153     }
01154 
01155     ret = Hmac_OuterHash(hmac, digest);
01156 
01157     return ret;
01158 }
01159 
01160 #endif
01161 
01162 #if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || \
01163     defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2)
01164 
01165 /* Calculate the HMAC of the header + message data.
01166  * Constant time implementation using normal hashing operations.
01167  * Update-Final need to be constant time.
01168  *
01169  * hmac    HMAC object.
01170  * digest  MAC result.
01171  * in      Message data.
01172  * sz      Size of the message data.
01173  * header  Constructed record header with length of handshake data.
01174  * returns 0 on success, otherwise failure.
01175  */
01176 static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
01177                             word32 sz, byte* header)
01178 {
01179     byte       dummy[WC_MAX_BLOCK_SIZE] = {0};
01180     int        ret;
01181     word32     msgSz, blockSz, macSz, padSz, maxSz, realSz;
01182     word32     currSz, offset;
01183     int        msgBlocks, blocks, blockBits;
01184     int        i;
01185 
01186     switch (hmac->macType) {
01187     #ifndef NO_SHA
01188         case WC_SHA:
01189             blockSz = WC_SHA_BLOCK_SIZE;
01190             blockBits = 6;
01191             macSz = WC_SHA_DIGEST_SIZE;
01192             padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
01193             break;
01194     #endif /* !NO_SHA */
01195 
01196     #ifndef NO_SHA256
01197         case WC_SHA256:
01198             blockSz = WC_SHA256_BLOCK_SIZE;
01199             blockBits = 6;
01200             macSz = WC_SHA256_DIGEST_SIZE;
01201             padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
01202             break;
01203     #endif /* !NO_SHA256 */
01204 
01205     #ifdef WOLFSSL_SHA384
01206         case WC_SHA384:
01207             blockSz = WC_SHA384_BLOCK_SIZE;
01208             blockBits = 7;
01209             macSz = WC_SHA384_DIGEST_SIZE;
01210             padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
01211             break;
01212     #endif /* WOLFSSL_SHA384 */
01213 
01214     #ifdef WOLFSSL_SHA512
01215         case WC_SHA512:
01216             blockSz = WC_SHA512_BLOCK_SIZE;
01217             blockBits = 7;
01218             macSz = WC_SHA512_DIGEST_SIZE;
01219             padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
01220             break;
01221     #endif /* WOLFSSL_SHA512 */
01222 
01223     #ifdef HAVE_BLAKE2
01224         case WC_HASH_TYPE_BLAKE2B:
01225             blockSz = BLAKE2B_BLOCKBYTES;
01226             blockBits = 7;
01227             macSz = BLAKE2B_256;
01228             padSz = 0;
01229             break;
01230     #endif /* HAVE_BLAK2 */
01231 
01232         default:
01233             return BAD_FUNC_ARG;
01234     }
01235 
01236     msgSz = sz - (1 + in[sz - 1] + macSz);
01237     /* Make negative result 0 */
01238     msgSz &= ~(0 - (msgSz >> 31));
01239     realSz = WOLFSSL_TLS_HMAC_INNER_SZ + msgSz;
01240     maxSz = WOLFSSL_TLS_HMAC_INNER_SZ + (sz - 1) - macSz;
01241 
01242     /* Calculate #blocks processed in HMAC for max and real data. */
01243     blocks      = maxSz >> blockBits;
01244     blocks     += ((maxSz + padSz) % blockSz) < padSz;
01245     msgBlocks   = realSz >> blockBits;
01246     /* #Extra blocks to process. */
01247     blocks -= msgBlocks + (((realSz + padSz) % blockSz) < padSz);
01248     /* Calculate whole blocks. */
01249     msgBlocks--;
01250 
01251     ret = wc_HmacUpdate(hmac, header, WOLFSSL_TLS_HMAC_INNER_SZ);
01252     if (ret == 0) {
01253         /* Fill the rest of the block with any available data. */
01254         currSz = ctMaskLT(msgSz, blockSz) & msgSz;
01255         currSz |= ctMaskGTE(msgSz, blockSz) & blockSz;
01256         currSz -= WOLFSSL_TLS_HMAC_INNER_SZ;
01257         currSz &= ~(0 - (currSz >> 31));
01258         ret = wc_HmacUpdate(hmac, in, currSz);
01259         offset = currSz;
01260     }
01261     if (ret == 0) {
01262         /* Do the hash operations on a block basis. */
01263         for (i = 0; i < msgBlocks; i++, offset += blockSz) {
01264             ret = wc_HmacUpdate(hmac, in + offset, blockSz);
01265             if (ret != 0)
01266                 break;
01267         }
01268     }
01269     if (ret == 0)
01270         ret = wc_HmacUpdate(hmac, in + offset, msgSz - offset);
01271     if (ret == 0)
01272         ret = wc_HmacFinal(hmac, digest);
01273     if (ret == 0) {
01274         /* Do the dummy hash operations. Do at least one. */
01275         for (i = 0; i < blocks + 1; i++) {
01276             ret = wc_HmacUpdate(hmac, dummy, blockSz);
01277             if (ret != 0)
01278                 break;
01279         }
01280     }
01281 
01282     return ret;
01283 }
01284 
01285 #endif
01286 
01287 int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
01288              int content, int verify)
01289 {
01290     Hmac   hmac;
01291     byte   myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
01292     int    ret = 0;
01293 
01294     if (ssl == NULL)
01295         return BAD_FUNC_ARG;
01296 
01297 #ifdef HAVE_FUZZER
01298     /* Fuzz "in" buffer with sz to be used in HMAC algorithm */
01299     if (ssl->fuzzerCb) {
01300         if (verify && padSz >= 0) {
01301             ssl->fuzzerCb(ssl, in, sz + ssl->specs.hash_size + padSz + 1,
01302                 FUZZ_HMAC, ssl->fuzzerCtx);
01303         }
01304         else {
01305             ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
01306         }
01307     }
01308 #endif
01309 
01310     wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
01311 
01312     ret = wc_HmacInit(&hmac, ssl->heap, ssl->devId);
01313     if (ret != 0)
01314         return ret;
01315 
01316     ret = wc_HmacSetKey(&hmac, wolfSSL_GetHmacType(ssl),
01317                                               wolfSSL_GetMacSecret(ssl, verify),
01318                                               ssl->specs.hash_size);
01319     if (ret == 0) {
01320         /* Constant time verification required. */
01321         if (verify && padSz >= 0) {
01322 #if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
01323     !defined(HAVE_SELFTEST)
01324     #ifdef HAVE_BLAKE2
01325             if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
01326                 ret = Hmac_UpdateFinal(&hmac, digest, in, sz +
01327                                                ssl->specs.hash_size + padSz + 1,
01328                                                myInner);
01329             }
01330             else
01331     #endif
01332             {
01333                 ret = Hmac_UpdateFinal_CT(&hmac, digest, in, sz +
01334                                                ssl->specs.hash_size + padSz + 1,
01335                                                myInner);
01336             }
01337 #else
01338             ret = Hmac_UpdateFinal(&hmac, digest, in, sz +
01339                                                ssl->specs.hash_size + padSz + 1,
01340                                                myInner);
01341 #endif
01342         }
01343         else {
01344             ret = wc_HmacUpdate(&hmac, myInner, sizeof(myInner));
01345             if (ret == 0)
01346                 ret = wc_HmacUpdate(&hmac, in, sz);                /* content */
01347             if (ret == 0)
01348                 ret = wc_HmacFinal(&hmac, digest);
01349         }
01350     }
01351 
01352     wc_HmacFree(&hmac);
01353 
01354     return ret;
01355 }
01356 
01357 #endif /* !WOLFSSL_NO_TLS12 */
01358 
01359 #ifdef HAVE_TLS_EXTENSIONS
01360 
01361 /**
01362  * The TLSX semaphore is used to calculate the size of the extensions to be sent
01363  * from one peer to another.
01364  */
01365 
01366 /** Supports up to 64 flags. Increase as needed. */
01367 #define SEMAPHORE_SIZE 8
01368 
01369 /**
01370  * Converts the extension type (id) to an index in the semaphore.
01371  *
01372  * Oficial reference for TLS extension types:
01373  *   http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
01374  *
01375  * Motivation:
01376  *   Previously, we used the extension type itself as the index of that
01377  *   extension in the semaphore as the extension types were declared
01378  *   sequentially, but maintain a semaphore as big as the number of available
01379  *   extensions is no longer an option since the release of renegotiation_info.
01380  *
01381  * How to update:
01382  *   Assign extension types that extrapolate the number of available semaphores
01383  *   to the first available index going backwards in the semaphore array.
01384  *   When adding a new extension type that don't extrapolate the number of
01385  *   available semaphores, check for a possible collision with with a
01386  *   'remapped' extension type.
01387  */
01388 static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
01389 {
01390     switch (type) {
01391 
01392         case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */
01393             return 63;
01394 
01395         default:
01396             if (type > 62) {
01397                 /* This message SHOULD only happens during the adding of
01398                    new TLS extensions in which its IANA number overflows
01399                    the current semaphore's range, or if its number already
01400                    is assigned to be used by another extension.
01401                    Use this check value for the new extension and decrement
01402                    the check value by one. */
01403                 WOLFSSL_MSG("### TLSX semaphore colision or overflow detected!");
01404             }
01405     }
01406 
01407     return type;
01408 }
01409 
01410 /** Checks if a specific light (tls extension) is not set in the semaphore. */
01411 #define IS_OFF(semaphore, light) \
01412     (!(((semaphore)[(light) / 8] &  (byte) (0x01 << ((light) % 8)))))
01413 
01414 /** Turn on a specific light (tls extension) in the semaphore. */
01415 /* the semaphore marks the extensions already written to the message */
01416 #define TURN_ON(semaphore, light) \
01417     ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
01418 
01419 /** Turn off a specific light (tls extension) in the semaphore. */
01420 #define TURN_OFF(semaphore, light) \
01421     ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8)))
01422 
01423 /** Creates a new extension. */
01424 static TLSX* TLSX_New(TLSX_Type type, void* data, void* heap)
01425 {
01426     TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX);
01427 
01428     (void)heap;
01429 
01430     if (extension) {
01431         extension->type = type;
01432         extension->data = data;
01433         extension->resp = 0;
01434         extension->next = NULL;
01435     }
01436 
01437     return extension;
01438 }
01439 
01440 /**
01441  * Creates a new extension and pushes it to the provided list.
01442  * Checks for duplicate extensions, keeps the newest.
01443  */
01444 static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap)
01445 {
01446     TLSX* extension = TLSX_New(type, data, heap);
01447 
01448     if (extension == NULL)
01449         return MEMORY_E;
01450 
01451     /* pushes the new extension on the list. */
01452     extension->next = *list;
01453     *list = extension;
01454 
01455     /* remove duplicate extensions, there should be only one of each type. */
01456     do {
01457         if (extension->next && extension->next->type == type) {
01458             TLSX *next = extension->next;
01459 
01460             extension->next = next->next;
01461             next->next = NULL;
01462 
01463             TLSX_FreeAll(next, heap);
01464 
01465             /* there is no way to occur more than
01466              * two extensions of the same type.
01467              */
01468             break;
01469         }
01470     } while ((extension = extension->next));
01471 
01472     return 0;
01473 }
01474 
01475 #ifndef NO_WOLFSSL_CLIENT
01476 
01477 int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type);
01478 
01479 int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type)
01480 {
01481     TLSX *extension = TLSX_Find(ssl->extensions, type);
01482 
01483     if (!extension)
01484         extension = TLSX_Find(ssl->ctx->extensions, type);
01485 
01486     return extension == NULL;
01487 }
01488 
01489 int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl);
01490 
01491 int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl)
01492 {
01493     SendAlert(ssl, alert_fatal, unsupported_extension);
01494     return UNSUPPORTED_EXTENSION;
01495 }
01496 
01497 #else
01498 
01499 #define TLSX_CheckUnsupportedExtension(ssl, type) 0
01500 #define TLSX_HandleUnsupportedExtension(ssl) 0
01501 
01502 #endif
01503 
01504 /** Mark an extension to be sent back to the client. */
01505 void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
01506 
01507 void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
01508 {
01509     TLSX *extension = TLSX_Find(ssl->extensions, type);
01510 
01511     if (extension)
01512         extension->resp = 1;
01513 }
01514 
01515 /******************************************************************************/
01516 /* Application-Layer Protocol Negotiation                                     */
01517 /******************************************************************************/
01518 
01519 #ifdef HAVE_ALPN
01520 /** Creates a new ALPN object, providing protocol name to use. */
01521 static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz,
01522                                                                      void* heap)
01523 {
01524     ALPN *alpn;
01525 
01526     WOLFSSL_ENTER("TLSX_ALPN_New");
01527 
01528     if (protocol_name == NULL ||
01529         protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
01530         WOLFSSL_MSG("Invalid arguments");
01531         return NULL;
01532     }
01533 
01534     alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX);
01535     if (alpn == NULL) {
01536         WOLFSSL_MSG("Memory failure");
01537         return NULL;
01538     }
01539 
01540     alpn->next = NULL;
01541     alpn->negotiated = 0;
01542     alpn->options = 0;
01543 
01544     alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1,
01545                                          heap, DYNAMIC_TYPE_TLSX);
01546     if (alpn->protocol_name == NULL) {
01547         WOLFSSL_MSG("Memory failure");
01548         XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
01549         return NULL;
01550     }
01551 
01552     XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
01553     alpn->protocol_name[protocol_nameSz] = 0;
01554 
01555     return alpn;
01556 }
01557 
01558 /** Releases an ALPN object. */
01559 static void TLSX_ALPN_Free(ALPN *alpn, void* heap)
01560 {
01561     (void)heap;
01562 
01563     if (alpn == NULL)
01564         return;
01565 
01566     XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX);
01567     XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
01568 }
01569 
01570 /** Releases all ALPN objects in the provided list. */
01571 static void TLSX_ALPN_FreeAll(ALPN *list, void* heap)
01572 {
01573     ALPN* alpn;
01574 
01575     while ((alpn = list)) {
01576         list = alpn->next;
01577         TLSX_ALPN_Free(alpn, heap);
01578     }
01579 }
01580 
01581 /** Tells the buffered size of the ALPN objects in a list. */
01582 static word16 TLSX_ALPN_GetSize(ALPN *list)
01583 {
01584     ALPN* alpn;
01585     word16 length = OPAQUE16_LEN; /* list length */
01586 
01587     while ((alpn = list)) {
01588         list = alpn->next;
01589 
01590         length++; /* protocol name length is on one byte */
01591         length += (word16)XSTRLEN(alpn->protocol_name);
01592     }
01593 
01594     return length;
01595 }
01596 
01597 /** Writes the ALPN objects of a list in a buffer. */
01598 static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
01599 {
01600     ALPN* alpn;
01601     word16 length = 0;
01602     word16 offset = OPAQUE16_LEN; /* list length offset */
01603 
01604     while ((alpn = list)) {
01605         list = alpn->next;
01606 
01607         length = (word16)XSTRLEN(alpn->protocol_name);
01608 
01609         /* protocol name length */
01610         output[offset++] = (byte)length;
01611 
01612         /* protocol name value */
01613         XMEMCPY(output + offset, alpn->protocol_name, length);
01614 
01615         offset += length;
01616     }
01617 
01618     /* writing list length */
01619     c16toa(offset - OPAQUE16_LEN, output);
01620 
01621     return offset;
01622 }
01623 
01624 /** Finds a protocol name in the provided ALPN list */
01625 static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
01626 {
01627     ALPN *alpn;
01628 
01629     if (list == NULL || protocol_name == NULL)
01630         return NULL;
01631 
01632     alpn = list;
01633     while (alpn != NULL && (
01634            (word16)XSTRLEN(alpn->protocol_name) != size ||
01635            XSTRNCMP(alpn->protocol_name, protocol_name, size)))
01636         alpn = alpn->next;
01637 
01638     return alpn;
01639 }
01640 
01641 /** Set the ALPN matching client and server requirements */
01642 static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size,
01643                                                                      void* heap)
01644 {
01645     ALPN *alpn;
01646     int  ret;
01647 
01648     if (extensions == NULL || data == NULL)
01649         return BAD_FUNC_ARG;
01650 
01651     alpn = TLSX_ALPN_New((char *)data, size, heap);
01652     if (alpn == NULL) {
01653         WOLFSSL_MSG("Memory failure");
01654         return MEMORY_E;
01655     }
01656 
01657     alpn->negotiated = 1;
01658 
01659     ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn,
01660                                                                           heap);
01661     if (ret != 0) {
01662         TLSX_ALPN_Free(alpn, heap);
01663         return ret;
01664     }
01665 
01666     return WOLFSSL_SUCCESS;
01667 }
01668 
01669 /** Parses a buffer of ALPN extensions and set the first one matching
01670  * client and server requirements */
01671 static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
01672                                  byte isRequest)
01673 {
01674     word16  size = 0, offset = 0, idx = 0;
01675     int     r = BUFFER_ERROR;
01676     byte    match = 0;
01677     TLSX    *extension;
01678     ALPN    *alpn = NULL, *list;
01679 
01680     if (OPAQUE16_LEN > length)
01681         return BUFFER_ERROR;
01682 
01683     ato16(input, &size);
01684     offset += OPAQUE16_LEN;
01685 
01686     extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01687     if (extension == NULL)
01688         extension = TLSX_Find(ssl->ctx->extensions,
01689                                                TLSX_APPLICATION_LAYER_PROTOCOL);
01690 
01691 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
01692     if (ssl->alpnSelect != NULL) {
01693         const byte* out;
01694         unsigned char outLen;
01695 
01696         if (ssl->alpnSelect(ssl, &out, &outLen, input + offset, size,
01697                             ssl->alpnSelectArg) == 0) {
01698             WOLFSSL_MSG("ALPN protocol match");
01699             if (TLSX_UseALPN(&ssl->extensions, (char*)out, outLen, 0, ssl->heap)
01700                                                            == WOLFSSL_SUCCESS) {
01701                 if (extension == NULL) {
01702                     extension = TLSX_Find(ssl->extensions,
01703                                           TLSX_APPLICATION_LAYER_PROTOCOL);
01704                 }
01705             }
01706         }
01707     }
01708 #endif
01709 
01710     if (extension == NULL || extension->data == NULL) {
01711         return isRequest ? 0
01712                          : TLSX_HandleUnsupportedExtension(ssl);
01713     }
01714 
01715     /* validating alpn list length */
01716     if (length != OPAQUE16_LEN + size)
01717         return BUFFER_ERROR;
01718 
01719     list = (ALPN*)extension->data;
01720 
01721     /* keep the list sent by client */
01722     if (isRequest) {
01723         if (ssl->alpn_client_list != NULL)
01724             XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_ALPN);
01725 
01726         ssl->alpn_client_list = (char *)XMALLOC(size, ssl->heap,
01727                                                 DYNAMIC_TYPE_ALPN);
01728         if (ssl->alpn_client_list == NULL)
01729             return MEMORY_ERROR;
01730     }
01731 
01732     for (size = 0; offset < length; offset += size) {
01733 
01734         size = input[offset++];
01735         if (offset + size > length)
01736             return BUFFER_ERROR;
01737 
01738         if (isRequest) {
01739             XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size);
01740             idx += size;
01741             ssl->alpn_client_list[idx++] = ',';
01742         }
01743 
01744         if (!match) {
01745             alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
01746             if (alpn != NULL) {
01747                 WOLFSSL_MSG("ALPN protocol match");
01748                 match = 1;
01749 
01750                 /* skip reading other values if not required */
01751                 if (!isRequest)
01752                     break;
01753             }
01754         }
01755     }
01756 
01757     if (isRequest)
01758         ssl->alpn_client_list[idx-1] = 0;
01759 
01760     if (!match) {
01761         WOLFSSL_MSG("No ALPN protocol match");
01762 
01763         /* do nothing if no protocol match between client and server and option
01764          is set to continue (like OpenSSL) */
01765         if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
01766             WOLFSSL_MSG("Continue on mismatch");
01767             return 0;
01768         }
01769 
01770         SendAlert(ssl, alert_fatal, no_application_protocol);
01771         return UNKNOWN_ALPN_PROTOCOL_NAME_E;
01772     }
01773 
01774     /* set the matching negotiated protocol */
01775     r = TLSX_SetALPN(&ssl->extensions,
01776                      alpn->protocol_name,
01777                      (word16)XSTRLEN(alpn->protocol_name),
01778                      ssl->heap);
01779     if (r != WOLFSSL_SUCCESS) {
01780         WOLFSSL_MSG("TLSX_UseALPN failed");
01781         return BUFFER_ERROR;
01782     }
01783 
01784     /* reply to ALPN extension sent from client */
01785     if (isRequest) {
01786 #ifndef NO_WOLFSSL_SERVER
01787         TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL);
01788 #endif
01789     }
01790 
01791     return 0;
01792 }
01793 
01794 /** Add a protocol name to the list of accepted usable ones */
01795 int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options,
01796                                                                      void* heap)
01797 {
01798     ALPN *alpn;
01799     TLSX *extension;
01800     int  ret;
01801 
01802     if (extensions == NULL || data == NULL)
01803         return BAD_FUNC_ARG;
01804 
01805     alpn = TLSX_ALPN_New((char *)data, size, heap);
01806     if (alpn == NULL) {
01807         WOLFSSL_MSG("Memory failure");
01808         return MEMORY_E;
01809     }
01810 
01811     /* Set Options of ALPN */
01812     alpn->options = options;
01813 
01814     extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01815     if (extension == NULL) {
01816         ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
01817                                                              (void*)alpn, heap);
01818         if (ret != 0) {
01819             TLSX_ALPN_Free(alpn, heap);
01820             return ret;
01821         }
01822     }
01823     else {
01824         /* push new ALPN object to extension data. */
01825         alpn->next = (ALPN*)extension->data;
01826         extension->data = (void*)alpn;
01827     }
01828 
01829     return WOLFSSL_SUCCESS;
01830 }
01831 
01832 /** Get the protocol name set by the server */
01833 int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
01834 {
01835     TLSX *extension;
01836     ALPN *alpn;
01837 
01838     if (extensions == NULL || data == NULL || dataSz == NULL)
01839         return BAD_FUNC_ARG;
01840 
01841     extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
01842     if (extension == NULL) {
01843         WOLFSSL_MSG("TLS extension not found");
01844         return WOLFSSL_ALPN_NOT_FOUND;
01845     }
01846 
01847     alpn = (ALPN *)extension->data;
01848     if (alpn == NULL) {
01849         WOLFSSL_MSG("ALPN extension not found");
01850         *data = NULL;
01851         *dataSz = 0;
01852         return WOLFSSL_FATAL_ERROR;
01853     }
01854 
01855     if (alpn->negotiated != 1) {
01856 
01857         /* consider as an error */
01858         if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
01859             WOLFSSL_MSG("No protocol match with peer -> Failed");
01860             return WOLFSSL_FATAL_ERROR;
01861         }
01862 
01863         /* continue without negotiated protocol */
01864         WOLFSSL_MSG("No protocol match with peer -> Continue");
01865         return WOLFSSL_ALPN_NOT_FOUND;
01866     }
01867 
01868     if (alpn->next != NULL) {
01869         WOLFSSL_MSG("Only one protocol name must be accepted");
01870         return WOLFSSL_FATAL_ERROR;
01871     }
01872 
01873     *data = alpn->protocol_name;
01874     *dataSz = (word16)XSTRLEN((char*)*data);
01875 
01876     return WOLFSSL_SUCCESS;
01877 }
01878 
01879 #define ALPN_FREE_ALL     TLSX_ALPN_FreeAll
01880 #define ALPN_GET_SIZE     TLSX_ALPN_GetSize
01881 #define ALPN_WRITE        TLSX_ALPN_Write
01882 #define ALPN_PARSE        TLSX_ALPN_ParseAndSet
01883 
01884 #else /* HAVE_ALPN */
01885 
01886 #define ALPN_FREE_ALL(list, heap)
01887 #define ALPN_GET_SIZE(list)     0
01888 #define ALPN_WRITE(a, b)        0
01889 #define ALPN_PARSE(a, b, c, d)  0
01890 
01891 #endif /* HAVE_ALPN */
01892 
01893 /******************************************************************************/
01894 /* Server Name Indication                                                     */
01895 /******************************************************************************/
01896 
01897 #ifdef HAVE_SNI
01898 
01899 /** Creates a new SNI object. */
01900 static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
01901 {
01902     SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX);
01903 
01904     if (sni) {
01905         sni->type = type;
01906         sni->next = NULL;
01907 
01908     #ifndef NO_WOLFSSL_SERVER
01909         sni->options = 0;
01910         sni->status  = WOLFSSL_SNI_NO_MATCH;
01911     #endif
01912 
01913         switch (sni->type) {
01914             case WOLFSSL_SNI_HOST_NAME:
01915                 sni->data.host_name = (char*)XMALLOC(size + 1, heap,
01916                                                      DYNAMIC_TYPE_TLSX);
01917                 if (sni->data.host_name) {
01918                     XSTRNCPY(sni->data.host_name, (const char*)data, size);
01919                     sni->data.host_name[size] = '\0';
01920                 } else {
01921                     XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
01922                     sni = NULL;
01923                 }
01924             break;
01925 
01926             default: /* invalid type */
01927                 XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
01928                 sni = NULL;
01929         }
01930     }
01931 
01932     return sni;
01933 }
01934 
01935 /** Releases a SNI object. */
01936 static void TLSX_SNI_Free(SNI* sni, void* heap)
01937 {
01938     if (sni) {
01939         switch (sni->type) {
01940             case WOLFSSL_SNI_HOST_NAME:
01941                 XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
01942             break;
01943         }
01944 
01945         XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
01946     }
01947     (void)heap;
01948 }
01949 
01950 /** Releases all SNI objects in the provided list. */
01951 static void TLSX_SNI_FreeAll(SNI* list, void* heap)
01952 {
01953     SNI* sni;
01954 
01955     while ((sni = list)) {
01956         list = sni->next;
01957         TLSX_SNI_Free(sni, heap);
01958     }
01959 }
01960 
01961 /** Tells the buffered size of the SNI objects in a list. */
01962 static word16 TLSX_SNI_GetSize(SNI* list)
01963 {
01964     SNI* sni;
01965     word16 length = OPAQUE16_LEN; /* list length */
01966 
01967     while ((sni = list)) {
01968         list = sni->next;
01969 
01970         length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
01971 
01972         switch (sni->type) {
01973             case WOLFSSL_SNI_HOST_NAME:
01974                 length += (word16)XSTRLEN((char*)sni->data.host_name);
01975             break;
01976         }
01977     }
01978 
01979     return length;
01980 }
01981 
01982 /** Writes the SNI objects of a list in a buffer. */
01983 static word16 TLSX_SNI_Write(SNI* list, byte* output)
01984 {
01985     SNI* sni;
01986     word16 length = 0;
01987     word16 offset = OPAQUE16_LEN; /* list length offset */
01988 
01989     while ((sni = list)) {
01990         list = sni->next;
01991 
01992         output[offset++] = sni->type; /* sni type */
01993 
01994         switch (sni->type) {
01995             case WOLFSSL_SNI_HOST_NAME:
01996                 length = (word16)XSTRLEN((char*)sni->data.host_name);
01997 
01998                 c16toa(length, output + offset); /* sni length */
01999                 offset += OPAQUE16_LEN;
02000 
02001                 XMEMCPY(output + offset, sni->data.host_name, length);
02002 
02003                 offset += length;
02004             break;
02005         }
02006     }
02007 
02008     c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
02009 
02010     return offset;
02011 }
02012 
02013 /** Finds a SNI object in the provided list. */
02014 static SNI* TLSX_SNI_Find(SNI *list, byte type)
02015 {
02016     SNI* sni = list;
02017 
02018     while (sni && sni->type != type)
02019         sni = sni->next;
02020 
02021     return sni;
02022 }
02023 
02024 /** Sets the status of a SNI object. */
02025 static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
02026 {
02027     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
02028     SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
02029 
02030     if (sni)
02031         sni->status = status;
02032 }
02033 
02034 /** Gets the status of a SNI object. */
02035 byte TLSX_SNI_Status(TLSX* extensions, byte type)
02036 {
02037     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
02038     SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
02039 
02040     if (sni)
02041         return sni->status;
02042 
02043     return 0;
02044 }
02045 
02046 /** Parses a buffer of SNI extensions. */
02047 static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
02048                                                                  byte isRequest)
02049 {
02050 #ifndef NO_WOLFSSL_SERVER
02051     word16 size = 0;
02052     word16 offset = 0;
02053     int cacheOnly = 0;
02054 #endif
02055 
02056     TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
02057 
02058     if (!extension)
02059         extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
02060 
02061     if (!isRequest) {
02062         #ifndef NO_WOLFSSL_CLIENT
02063             if (!extension || !extension->data)
02064                 return TLSX_HandleUnsupportedExtension(ssl);
02065 
02066             if (length > 0)
02067                 return BUFFER_ERROR; /* SNI response MUST be empty. */
02068 
02069             /* This call enables wolfSSL_SNI_GetRequest() to be called in the
02070              * client side to fetch the used SNI. It will only work if the SNI
02071              * was set at the SSL object level. Right now we only support one
02072              * name type, WOLFSSL_SNI_HOST_NAME, but in the future, the
02073              * inclusion of other name types will turn this method inaccurate,
02074              * as the extension response doesn't contains information of which
02075              * name was accepted.
02076              */
02077             TLSX_SNI_SetStatus(ssl->extensions, WOLFSSL_SNI_HOST_NAME,
02078                                                         WOLFSSL_SNI_REAL_MATCH);
02079 
02080             return 0;
02081         #endif
02082     }
02083 
02084 #ifndef NO_WOLFSSL_SERVER
02085     if (!extension || !extension->data) {
02086         #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER)
02087             /* This will keep SNI even though TLSX_UseSNI has not been called.
02088             * Enable it so that the received sni is available to functions
02089             * that use a custom callback when SNI is received.
02090             */
02091 
02092             cacheOnly = 1;
02093             WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
02094         #else
02095             /* Skipping, SNI not enabled at server side. */
02096             return 0;
02097         #endif
02098     }
02099 
02100     if (OPAQUE16_LEN > length)
02101         return BUFFER_ERROR;
02102 
02103     ato16(input, &size);
02104     offset += OPAQUE16_LEN;
02105 
02106     /* validating sni list length */
02107     if (length != OPAQUE16_LEN + size)
02108         return BUFFER_ERROR;
02109 
02110     for (size = 0; offset < length; offset += size) {
02111         SNI *sni = NULL;
02112         byte type = input[offset++];
02113 
02114         if (offset + OPAQUE16_LEN > length)
02115             return BUFFER_ERROR;
02116 
02117         ato16(input + offset, &size);
02118         offset += OPAQUE16_LEN;
02119 
02120         if (offset + size > length)
02121             return BUFFER_ERROR;
02122 
02123         if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
02124             continue; /* not using this type of SNI. */
02125 
02126         switch(type) {
02127             case WOLFSSL_SNI_HOST_NAME: {
02128                 int matchStat;
02129                 byte matched;
02130 
02131 #ifdef WOLFSSL_TLS13
02132                 /* Don't process the second ClientHello SNI extension if there
02133                  * was problems with the first.
02134                  */
02135                 if (!cacheOnly && sni->status != 0)
02136                     break;
02137 #endif
02138                 matched = cacheOnly ||
02139                     ((XSTRLEN(sni->data.host_name) == size) &&
02140                     (XSTRNCMP(sni->data.host_name,
02141                                       (const char*)input + offset, size) == 0));
02142 
02143                 if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
02144                     int r = TLSX_UseSNI(&ssl->extensions,
02145                                          type, input + offset, size, ssl->heap);
02146 
02147                     if (r != WOLFSSL_SUCCESS)
02148                         return r; /* throws error. */
02149 
02150                     if(cacheOnly) {
02151                         WOLFSSL_MSG("Forcing storage of SNI, Fake match");
02152                         matchStat = WOLFSSL_SNI_FORCE_KEEP;
02153                     } else if(matched) {
02154                         WOLFSSL_MSG("SNI did match!");
02155                         matchStat = WOLFSSL_SNI_REAL_MATCH;
02156                     } else {
02157                         WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
02158                         matchStat = WOLFSSL_SNI_FAKE_MATCH;
02159                     }
02160 
02161                     TLSX_SNI_SetStatus(ssl->extensions, type, (byte)matchStat);
02162 
02163                     if(!cacheOnly)
02164                         TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
02165 
02166                 } else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
02167                     SendAlert(ssl, alert_fatal, unrecognized_name);
02168 
02169                     return UNKNOWN_SNI_HOST_NAME_E;
02170                 }
02171                 break;
02172             }
02173         }
02174     }
02175 #else
02176     (void)input;
02177 #endif
02178 
02179     return 0;
02180 }
02181 
02182 static int TLSX_SNI_VerifyParse(WOLFSSL* ssl,  byte isRequest)
02183 {
02184     (void)ssl;
02185 
02186     if (isRequest) {
02187     #ifndef NO_WOLFSSL_SERVER
02188         TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
02189         TLSX* ssl_ext = TLSX_Find(ssl->extensions,      TLSX_SERVER_NAME);
02190         SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL;
02191         SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL;
02192         SNI* sni = NULL;
02193 
02194         for (; ctx_sni; ctx_sni = ctx_sni->next) {
02195             if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
02196                 sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
02197 
02198                 if (sni) {
02199                     if (sni->status != WOLFSSL_SNI_NO_MATCH)
02200                         continue;
02201 
02202                     /* if ssl level overrides ctx level, it is ok. */
02203                     if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
02204                         continue;
02205                 }
02206 
02207                 SendAlert(ssl, alert_fatal, handshake_failure);
02208                 return SNI_ABSENT_ERROR;
02209             }
02210         }
02211 
02212         for (; ssl_sni; ssl_sni = ssl_sni->next) {
02213             if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
02214                 if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
02215                     continue;
02216 
02217                 SendAlert(ssl, alert_fatal, handshake_failure);
02218                 return SNI_ABSENT_ERROR;
02219             }
02220         }
02221     #endif /* NO_WOLFSSL_SERVER */
02222     }
02223 
02224     return 0;
02225 }
02226 
02227 int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
02228                                                                      void* heap)
02229 {
02230     TLSX* extension;
02231     SNI* sni = NULL;
02232 
02233     if (extensions == NULL || data == NULL)
02234         return BAD_FUNC_ARG;
02235 
02236     if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL)
02237         return MEMORY_E;
02238 
02239     extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
02240     if (!extension) {
02241         int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap);
02242 
02243         if (ret != 0) {
02244             TLSX_SNI_Free(sni, heap);
02245             return ret;
02246         }
02247     }
02248     else {
02249         /* push new SNI object to extension data. */
02250         sni->next = (SNI*)extension->data;
02251         extension->data = (void*)sni;
02252 
02253         /* remove duplicate SNI, there should be only one of each type. */
02254         do {
02255             if (sni->next && sni->next->type == type) {
02256                 SNI* next = sni->next;
02257 
02258                 sni->next = next->next;
02259                 TLSX_SNI_Free(next, heap);
02260 
02261                 /* there is no way to occur more than
02262                  * two SNIs of the same type.
02263                  */
02264                 break;
02265             }
02266         } while ((sni = sni->next));
02267     }
02268 
02269     return WOLFSSL_SUCCESS;
02270 }
02271 
02272 #ifndef NO_WOLFSSL_SERVER
02273 
02274 /** Tells the SNI requested by the client. */
02275 word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
02276 {
02277     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
02278     SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
02279 
02280     if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) {
02281         switch (sni->type) {
02282             case WOLFSSL_SNI_HOST_NAME:
02283                 if (data) {
02284                     *data = sni->data.host_name;
02285                     return (word16)XSTRLEN((char*)*data);
02286                 }
02287         }
02288     }
02289 
02290     return 0;
02291 }
02292 
02293 /** Sets the options for a SNI object. */
02294 void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
02295 {
02296     TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
02297     SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
02298 
02299     if (sni)
02300         sni->options = options;
02301 }
02302 
02303 /** Retrieves a SNI request from a client hello buffer. */
02304 int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
02305                            byte type, byte* sni, word32* inOutSz)
02306 {
02307     word32 offset = 0;
02308     word32 len32 = 0;
02309     word16 len16 = 0;
02310 
02311     if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
02312         return INCOMPLETE_DATA;
02313 
02314     /* TLS record header */
02315     if ((enum ContentType) clientHello[offset++] != handshake) {
02316 
02317         /* checking for SSLv2.0 client hello according to: */
02318         /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
02319         if ((enum HandShakeType) clientHello[++offset] == client_hello) {
02320             offset += ENUM_LEN + VERSION_SZ; /* skip version */
02321 
02322             ato16(clientHello + offset, &len16);
02323             offset += OPAQUE16_LEN;
02324 
02325             if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
02326                 return BUFFER_ERROR;
02327 
02328             ato16(clientHello + offset, &len16);
02329             /* Returning SNI_UNSUPPORTED do not increment offset here */
02330 
02331             if (len16 != 0) /* session_id_length must be 0 */
02332                 return BUFFER_ERROR;
02333 
02334             return SNI_UNSUPPORTED;
02335         }
02336 
02337         return BUFFER_ERROR;
02338     }
02339 
02340     if (clientHello[offset++] != SSLv3_MAJOR)
02341         return BUFFER_ERROR;
02342 
02343     if (clientHello[offset++] < TLSv1_MINOR)
02344         return SNI_UNSUPPORTED;
02345 
02346     ato16(clientHello + offset, &len16);
02347     offset += OPAQUE16_LEN;
02348 
02349     if (offset + len16 > helloSz)
02350         return INCOMPLETE_DATA;
02351 
02352     /* Handshake header */
02353     if ((enum HandShakeType) clientHello[offset] != client_hello)
02354         return BUFFER_ERROR;
02355 
02356     c24to32(clientHello + offset + 1, &len32);
02357     offset += HANDSHAKE_HEADER_SZ;
02358 
02359     if (offset + len32 > helloSz)
02360         return BUFFER_ERROR;
02361 
02362     /* client hello */
02363     offset += VERSION_SZ + RAN_LEN; /* version, random */
02364 
02365     if (helloSz < offset + clientHello[offset])
02366         return BUFFER_ERROR;
02367 
02368     offset += ENUM_LEN + clientHello[offset]; /* skip session id */
02369 
02370     /* cypher suites */
02371     if (helloSz < offset + OPAQUE16_LEN)
02372         return BUFFER_ERROR;
02373 
02374     ato16(clientHello + offset, &len16);
02375     offset += OPAQUE16_LEN;
02376 
02377     if (helloSz < offset + len16)
02378         return BUFFER_ERROR;
02379 
02380     offset += len16; /* skip cypher suites */
02381 
02382     /* compression methods */
02383     if (helloSz < offset + 1)
02384         return BUFFER_ERROR;
02385 
02386     if (helloSz < offset + clientHello[offset])
02387         return BUFFER_ERROR;
02388 
02389     offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
02390 
02391     /* extensions */
02392     if (helloSz < offset + OPAQUE16_LEN)
02393         return 0; /* no extensions in client hello. */
02394 
02395     ato16(clientHello + offset, &len16);
02396     offset += OPAQUE16_LEN;
02397 
02398     if (helloSz < offset + len16)
02399         return BUFFER_ERROR;
02400 
02401     while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
02402         word16 extType;
02403         word16 extLen;
02404 
02405         ato16(clientHello + offset, &extType);
02406         offset += OPAQUE16_LEN;
02407 
02408         ato16(clientHello + offset, &extLen);
02409         offset += OPAQUE16_LEN;
02410 
02411         if (helloSz < offset + extLen)
02412             return BUFFER_ERROR;
02413 
02414         if (extType != TLSX_SERVER_NAME) {
02415             offset += extLen; /* skip extension */
02416         } else {
02417             word16 listLen;
02418 
02419             ato16(clientHello + offset, &listLen);
02420             offset += OPAQUE16_LEN;
02421 
02422             if (helloSz < offset + listLen)
02423                 return BUFFER_ERROR;
02424 
02425             while (listLen > ENUM_LEN + OPAQUE16_LEN) {
02426                 byte   sniType = clientHello[offset++];
02427                 word16 sniLen;
02428 
02429                 ato16(clientHello + offset, &sniLen);
02430                 offset += OPAQUE16_LEN;
02431 
02432                 if (helloSz < offset + sniLen)
02433                     return BUFFER_ERROR;
02434 
02435                 if (sniType != type) {
02436                     offset  += sniLen;
02437                     listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
02438                     continue;
02439                 }
02440 
02441                 *inOutSz = min(sniLen, *inOutSz);
02442                 XMEMCPY(sni, clientHello + offset, *inOutSz);
02443 
02444                 return WOLFSSL_SUCCESS;
02445             }
02446         }
02447 
02448         len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
02449     }
02450 
02451     return len16 ? BUFFER_ERROR : 0;
02452 }
02453 
02454 #endif
02455 
02456 #define SNI_FREE_ALL     TLSX_SNI_FreeAll
02457 #define SNI_GET_SIZE     TLSX_SNI_GetSize
02458 #define SNI_WRITE        TLSX_SNI_Write
02459 #define SNI_PARSE        TLSX_SNI_Parse
02460 #define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
02461 
02462 #else
02463 
02464 #define SNI_FREE_ALL(list, heap)
02465 #define SNI_GET_SIZE(list)     0
02466 #define SNI_WRITE(a, b)        0
02467 #define SNI_PARSE(a, b, c, d)  0
02468 #define SNI_VERIFY_PARSE(a, b) 0
02469 
02470 #endif /* HAVE_SNI */
02471 
02472 /******************************************************************************/
02473 /* Max Fragment Length Negotiation                                            */
02474 /******************************************************************************/
02475 
02476 #ifdef HAVE_MAX_FRAGMENT
02477 
02478 static word16 TLSX_MFL_Write(byte* data, byte* output)
02479 {
02480     output[0] = data[0];
02481 
02482     return ENUM_LEN;
02483 }
02484 
02485 static int TLSX_MFL_Parse(WOLFSSL* ssl, byte* input, word16 length,
02486                                                                  byte isRequest)
02487 {
02488     if (length != ENUM_LEN)
02489         return BUFFER_ERROR;
02490 
02491 #ifdef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
02492     (void) isRequest;
02493 #else
02494     if (!isRequest)
02495         if (TLSX_CheckUnsupportedExtension(ssl, TLSX_MAX_FRAGMENT_LENGTH))
02496             return TLSX_HandleUnsupportedExtension(ssl);
02497 #endif
02498 
02499     switch (*input) {
02500         case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
02501         case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
02502         case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
02503         case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
02504         case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
02505 
02506         default:
02507             SendAlert(ssl, alert_fatal, illegal_parameter);
02508 
02509             return UNKNOWN_MAX_FRAG_LEN_E;
02510     }
02511 
02512 #ifndef NO_WOLFSSL_SERVER
02513     if (isRequest) {
02514         int ret = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap);
02515 
02516         if (ret != WOLFSSL_SUCCESS)
02517             return ret; /* throw error */
02518 
02519         TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH);
02520     }
02521 #endif
02522 
02523     return 0;
02524 }
02525 
02526 int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap)
02527 {
02528     byte* data = NULL;
02529     int ret = 0;
02530 
02531     if (extensions == NULL || mfl < WOLFSSL_MFL_2_9 || WOLFSSL_MFL_2_13 < mfl)
02532         return BAD_FUNC_ARG;
02533 
02534     data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX);
02535     if (data == NULL)
02536         return MEMORY_E;
02537 
02538     data[0] = mfl;
02539 
02540     ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap);
02541     if (ret != 0) {
02542         XFREE(data, heap, DYNAMIC_TYPE_TLSX);
02543         return ret;
02544     }
02545 
02546     return WOLFSSL_SUCCESS;
02547 }
02548 
02549 
02550 #define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
02551 #define MFL_GET_SIZE(data) ENUM_LEN
02552 #define MFL_WRITE          TLSX_MFL_Write
02553 #define MFL_PARSE          TLSX_MFL_Parse
02554 
02555 #else
02556 
02557 #define MFL_FREE_ALL(a, b)
02558 #define MFL_GET_SIZE(a)       0
02559 #define MFL_WRITE(a, b)       0
02560 #define MFL_PARSE(a, b, c, d) 0
02561 
02562 #endif /* HAVE_MAX_FRAGMENT */
02563 
02564 /******************************************************************************/
02565 /* Truncated HMAC                                                             */
02566 /******************************************************************************/
02567 
02568 #ifdef HAVE_TRUNCATED_HMAC
02569 
02570 static int TLSX_THM_Parse(WOLFSSL* ssl, byte* input, word16 length,
02571                                                                  byte isRequest)
02572 {
02573     if (length != 0 || input == NULL)
02574         return BUFFER_ERROR;
02575 
02576     if (!isRequest) {
02577     #ifndef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
02578         if (TLSX_CheckUnsupportedExtension(ssl, TLSX_TRUNCATED_HMAC))
02579             return TLSX_HandleUnsupportedExtension(ssl);
02580     #endif
02581     }
02582     else {
02583         #ifndef NO_WOLFSSL_SERVER
02584             int ret = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
02585 
02586             if (ret != WOLFSSL_SUCCESS)
02587                 return ret; /* throw error */
02588 
02589             TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC);
02590         #endif
02591     }
02592 
02593     ssl->truncated_hmac = 1;
02594 
02595     return 0;
02596 }
02597 
02598 int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap)
02599 {
02600     int ret = 0;
02601 
02602     if (extensions == NULL)
02603         return BAD_FUNC_ARG;
02604 
02605     ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap);
02606     if (ret != 0)
02607         return ret;
02608 
02609     return WOLFSSL_SUCCESS;
02610 }
02611 
02612 #define THM_PARSE TLSX_THM_Parse
02613 
02614 #else
02615 
02616 #define THM_PARSE(a, b, c, d) 0
02617 
02618 #endif /* HAVE_TRUNCATED_HMAC */
02619 
02620 /******************************************************************************/
02621 /* Certificate Status Request                                                 */
02622 /******************************************************************************/
02623 
02624 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
02625 
02626 static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
02627 {
02628     switch (csr->status_type) {
02629         case WOLFSSL_CSR_OCSP:
02630             FreeOcspRequest(&csr->request.ocsp);
02631         break;
02632     }
02633 
02634     XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
02635     (void)heap;
02636 }
02637 
02638 static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
02639 {
02640     word16 size = 0;
02641 
02642     /* shut up compiler warnings */
02643     (void) csr; (void) isRequest;
02644 
02645 #ifndef NO_WOLFSSL_CLIENT
02646     if (isRequest) {
02647         switch (csr->status_type) {
02648             case WOLFSSL_CSR_OCSP:
02649                 size += ENUM_LEN + 2 * OPAQUE16_LEN;
02650 
02651                 if (csr->request.ocsp.nonceSz)
02652                     size += OCSP_NONCE_EXT_SZ;
02653             break;
02654         }
02655     }
02656 #endif
02657 #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
02658     if (!isRequest && csr->ssl->options.tls1_3) {
02659         if (csr->response.buffer == NULL) {
02660             OcspRequest* request = &csr->request.ocsp;
02661             int ret = CreateOcspResponse(csr->ssl, &request, &csr->response);
02662             if (ret < 0)
02663                 return ret;
02664         }
02665         return OPAQUE8_LEN + OPAQUE24_LEN + csr->response.length;
02666     }
02667 #endif
02668 
02669     return size;
02670 }
02671 
02672 static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
02673                                                                  byte isRequest)
02674 {
02675     /* shut up compiler warnings */
02676     (void) csr; (void) output; (void) isRequest;
02677 
02678 #ifndef NO_WOLFSSL_CLIENT
02679     if (isRequest) {
02680         word16 offset = 0;
02681         word16 length = 0;
02682 
02683         /* type */
02684         output[offset++] = csr->status_type;
02685 
02686         switch (csr->status_type) {
02687             case WOLFSSL_CSR_OCSP:
02688                 /* responder id list */
02689                 c16toa(0, output + offset);
02690                 offset += OPAQUE16_LEN;
02691 
02692                 /* request extensions */
02693                 if (csr->request.ocsp.nonceSz)
02694                     length = (word16)EncodeOcspRequestExtensions(
02695                                                  &csr->request.ocsp,
02696                                                  output + offset + OPAQUE16_LEN,
02697                                                  OCSP_NONCE_EXT_SZ);
02698 
02699                 c16toa(length, output + offset);
02700                 offset += OPAQUE16_LEN + length;
02701 
02702             break;
02703         }
02704 
02705         return offset;
02706     }
02707 #endif
02708 #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
02709     if (!isRequest && csr->ssl->options.tls1_3) {
02710         word16 offset = 0;
02711         output[offset++] = csr->status_type;
02712         c32to24(csr->response.length, output + offset);
02713         offset += OPAQUE24_LEN;
02714         XMEMCPY(output + offset, csr->response.buffer, csr->response.length);
02715         offset += csr->response.length;
02716         return offset;
02717     }
02718 #endif
02719 
02720     return 0;
02721 }
02722 
02723 static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
02724                                                                  byte isRequest)
02725 {
02726     int ret;
02727 
02728     /* shut up compiler warnings */
02729     (void) ssl; (void) input;
02730 
02731     if (!isRequest) {
02732 #ifndef NO_WOLFSSL_CLIENT
02733         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
02734         CertificateStatusRequest* csr = extension ?
02735                               (CertificateStatusRequest*)extension->data : NULL;
02736 
02737         if (!csr) {
02738             /* look at context level */
02739             extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
02740             csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
02741 
02742             if (!csr) /* unexpected extension */
02743                 return TLSX_HandleUnsupportedExtension(ssl);
02744 
02745             /* enable extension at ssl level */
02746             ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
02747                                      csr->status_type, csr->options, ssl,
02748                                      ssl->heap, ssl->devId);
02749             if (ret != WOLFSSL_SUCCESS)
02750                 return ret;
02751 
02752             switch (csr->status_type) {
02753                 case WOLFSSL_CSR_OCSP:
02754                     /* propagate nonce */
02755                     if (csr->request.ocsp.nonceSz) {
02756                         OcspRequest* request =
02757                              (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
02758 
02759                         if (request) {
02760                             XMEMCPY(request->nonce, csr->request.ocsp.nonce,
02761                                                     csr->request.ocsp.nonceSz);
02762                             request->nonceSz = csr->request.ocsp.nonceSz;
02763                         }
02764                     }
02765                 break;
02766             }
02767         }
02768 
02769         ssl->status_request = 1;
02770 
02771     #ifdef WOLFSSL_TLS13
02772         if (ssl->options.tls1_3) {
02773             word32       resp_length;
02774             word32       offset = 0;
02775             ret = 0;
02776             if (OPAQUE8_LEN + OPAQUE24_LEN > length)
02777                 ret = BUFFER_ERROR;
02778             if (ret == 0 && input[offset++] != WOLFSSL_CSR_OCSP)
02779                 ret = BAD_CERTIFICATE_STATUS_ERROR;
02780             if (ret == 0) {
02781                 c24to32(input + offset, &resp_length);
02782                 offset += OPAQUE24_LEN;
02783                 if (offset + resp_length != length)
02784                     ret = BUFFER_ERROR;
02785             }
02786             if (ret == 0) {
02787                 csr->response.buffer = input + offset;
02788                 csr->response.length = resp_length;
02789             }
02790 
02791             return ret;
02792         }
02793         else
02794     #endif
02795         {
02796             /* extension_data MUST be empty. */
02797             return length ? BUFFER_ERROR : 0;
02798         }
02799 #endif
02800     }
02801     else {
02802 #ifndef NO_WOLFSSL_SERVER
02803         byte   status_type;
02804         word16 offset = 0;
02805         word16 size = 0;
02806 
02807         if (length < ENUM_LEN)
02808             return BUFFER_ERROR;
02809 
02810         status_type = input[offset++];
02811 
02812         switch (status_type) {
02813             case WOLFSSL_CSR_OCSP: {
02814 
02815                 /* skip responder_id_list */
02816                 if (length - offset < OPAQUE16_LEN)
02817                     return BUFFER_ERROR;
02818 
02819                 ato16(input + offset, &size);
02820                 offset += OPAQUE16_LEN + size;
02821 
02822                 /* skip request_extensions */
02823                 if (length - offset < OPAQUE16_LEN)
02824                     return BUFFER_ERROR;
02825 
02826                 ato16(input + offset, &size);
02827                 offset += OPAQUE16_LEN + size;
02828 
02829                 if (offset > length)
02830                     return BUFFER_ERROR;
02831 
02832                 /* is able to send OCSP response? */
02833                 if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled)
02834                     return 0;
02835             }
02836             break;
02837 
02838             /* unknown status type */
02839             default:
02840                 return 0;
02841         }
02842 
02843         /* if using status_request and already sending it, skip this one */
02844         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
02845         if (ssl->status_request_v2)
02846             return 0;
02847         #endif
02848 
02849         /* accept the first good status_type and return */
02850         ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
02851                                                  0, ssl, ssl->heap, ssl->devId);
02852         if (ret != WOLFSSL_SUCCESS)
02853             return ret; /* throw error */
02854 
02855         TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
02856         ssl->status_request = status_type;
02857 #endif
02858     }
02859 
02860     return 0;
02861 }
02862 
02863 int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap)
02864 {
02865     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
02866     CertificateStatusRequest* csr = extension ?
02867         (CertificateStatusRequest*)extension->data : NULL;
02868     int ret = 0;
02869 
02870     if (csr) {
02871         switch (csr->status_type) {
02872             case WOLFSSL_CSR_OCSP: {
02873                 byte nonce[MAX_OCSP_NONCE_SZ];
02874                 int  nonceSz = csr->request.ocsp.nonceSz;
02875 
02876                 /* preserve nonce */
02877                 XMEMCPY(nonce, csr->request.ocsp.nonce, nonceSz);
02878 
02879                 if ((ret = InitOcspRequest(&csr->request.ocsp, cert, 0, heap))
02880                                                                            != 0)
02881                     return ret;
02882 
02883                 /* restore nonce */
02884                 XMEMCPY(csr->request.ocsp.nonce, nonce, nonceSz);
02885                 csr->request.ocsp.nonceSz = nonceSz;
02886             }
02887             break;
02888         }
02889     }
02890 
02891     return ret;
02892 }
02893 
02894 void* TLSX_CSR_GetRequest(TLSX* extensions)
02895 {
02896     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
02897     CertificateStatusRequest* csr = extension ?
02898                               (CertificateStatusRequest*)extension->data : NULL;
02899 
02900     if (csr) {
02901         switch (csr->status_type) {
02902             case WOLFSSL_CSR_OCSP:
02903                 return &csr->request.ocsp;
02904             break;
02905         }
02906     }
02907 
02908     return NULL;
02909 }
02910 
02911 int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
02912 {
02913     TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
02914     CertificateStatusRequest* csr = extension ?
02915                               (CertificateStatusRequest*)extension->data : NULL;
02916 
02917     if (csr) {
02918         switch (csr->status_type) {
02919             case WOLFSSL_CSR_OCSP:
02920                 if (ssl->ctx->cm->ocspEnabled) {
02921                     csr->request.ocsp.ssl = ssl;
02922                     return CheckOcspRequest(ssl->ctx->cm->ocsp,
02923                                                       &csr->request.ocsp, NULL);
02924                 }
02925                 else
02926                     return OCSP_LOOKUP_FAIL;
02927         }
02928     }
02929 
02930     return 0;
02931 }
02932 
02933 int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
02934                                          byte options, WOLFSSL* ssl, void* heap,
02935                                                                       int devId)
02936 {
02937     CertificateStatusRequest* csr = NULL;
02938     int ret = 0;
02939 
02940     if (!extensions || status_type != WOLFSSL_CSR_OCSP)
02941         return BAD_FUNC_ARG;
02942 
02943     csr = (CertificateStatusRequest*)
02944              XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX);
02945     if (!csr)
02946         return MEMORY_E;
02947 
02948     ForceZero(csr, sizeof(CertificateStatusRequest));
02949 
02950     csr->status_type = status_type;
02951     csr->options     = options;
02952     csr->ssl         = ssl;
02953 
02954     switch (csr->status_type) {
02955         case WOLFSSL_CSR_OCSP:
02956             if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
02957                 WC_RNG rng;
02958 
02959             #ifndef HAVE_FIPS
02960                 ret = wc_InitRng_ex(&rng, heap, devId);
02961             #else
02962                 ret = wc_InitRng(&rng);
02963                 (void)devId;
02964             #endif
02965                 if (ret == 0) {
02966                     if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp.nonce,
02967                                                         MAX_OCSP_NONCE_SZ) == 0)
02968                         csr->request.ocsp.nonceSz = MAX_OCSP_NONCE_SZ;
02969 
02970                     wc_FreeRng(&rng);
02971                 }
02972             }
02973         break;
02974     }
02975 
02976     if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) {
02977         XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
02978         return ret;
02979     }
02980 
02981     return WOLFSSL_SUCCESS;
02982 }
02983 
02984 #define CSR_FREE_ALL TLSX_CSR_Free
02985 #define CSR_GET_SIZE TLSX_CSR_GetSize
02986 #define CSR_WRITE    TLSX_CSR_Write
02987 #define CSR_PARSE    TLSX_CSR_Parse
02988 
02989 #else
02990 
02991 #define CSR_FREE_ALL(data, heap)
02992 #define CSR_GET_SIZE(a, b)    0
02993 #define CSR_WRITE(a, b, c)    0
02994 #define CSR_PARSE(a, b, c, d) 0
02995 
02996 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
02997 
02998 /******************************************************************************/
02999 /* Certificate Status Request v2                                              */
03000 /******************************************************************************/
03001 
03002 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
03003 
03004 static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap)
03005 {
03006     CertificateStatusRequestItemV2* next;
03007 
03008     for (; csr2; csr2 = next) {
03009         next = csr2->next;
03010 
03011         switch (csr2->status_type) {
03012             case WOLFSSL_CSR2_OCSP:
03013             case WOLFSSL_CSR2_OCSP_MULTI:
03014                 while(csr2->requests--)
03015                     FreeOcspRequest(&csr2->request.ocsp[csr2->requests]);
03016             break;
03017         }
03018 
03019         XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
03020     }
03021     (void)heap;
03022 }
03023 
03024 static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
03025                                                                  byte isRequest)
03026 {
03027     word16 size = 0;
03028 
03029     /* shut up compiler warnings */
03030     (void) csr2; (void) isRequest;
03031 
03032 #ifndef NO_WOLFSSL_CLIENT
03033     if (isRequest) {
03034         CertificateStatusRequestItemV2* next;
03035 
03036         for (size = OPAQUE16_LEN; csr2; csr2 = next) {
03037             next = csr2->next;
03038 
03039             switch (csr2->status_type) {
03040                 case WOLFSSL_CSR2_OCSP:
03041                 case WOLFSSL_CSR2_OCSP_MULTI:
03042                     size += ENUM_LEN + 3 * OPAQUE16_LEN;
03043 
03044                     if (csr2->request.ocsp[0].nonceSz)
03045                         size += OCSP_NONCE_EXT_SZ;
03046                 break;
03047             }
03048         }
03049     }
03050 #endif
03051 
03052     return size;
03053 }
03054 
03055 static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
03056                                                    byte* output, byte isRequest)
03057 {
03058     /* shut up compiler warnings */
03059     (void) csr2; (void) output; (void) isRequest;
03060 
03061 #ifndef NO_WOLFSSL_CLIENT
03062     if (isRequest) {
03063         word16 offset;
03064         word16 length;
03065 
03066         for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
03067             /* status_type */
03068             output[offset++] = csr2->status_type;
03069 
03070             /* request */
03071             switch (csr2->status_type) {
03072                 case WOLFSSL_CSR2_OCSP:
03073                 case WOLFSSL_CSR2_OCSP_MULTI:
03074                     /* request_length */
03075                     length = 2 * OPAQUE16_LEN;
03076 
03077                     if (csr2->request.ocsp[0].nonceSz)
03078                         length += OCSP_NONCE_EXT_SZ;
03079 
03080                     c16toa(length, output + offset);
03081                     offset += OPAQUE16_LEN;
03082 
03083                     /* responder id list */
03084                     c16toa(0, output + offset);
03085                     offset += OPAQUE16_LEN;
03086 
03087                     /* request extensions */
03088                     length = 0;
03089 
03090                     if (csr2->request.ocsp[0].nonceSz)
03091                         length = (word16)EncodeOcspRequestExtensions(
03092                                                  &csr2->request.ocsp[0],
03093                                                  output + offset + OPAQUE16_LEN,
03094                                                  OCSP_NONCE_EXT_SZ);
03095 
03096                     c16toa(length, output + offset);
03097                     offset += OPAQUE16_LEN + length;
03098                 break;
03099             }
03100         }
03101 
03102         /* list size */
03103         c16toa(offset - OPAQUE16_LEN, output);
03104 
03105         return offset;
03106     }
03107 #endif
03108 
03109     return 0;
03110 }
03111 
03112 static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
03113                                                                  byte isRequest)
03114 {
03115     int ret;
03116 
03117     /* shut up compiler warnings */
03118     (void) ssl; (void) input;
03119 
03120     if (!isRequest) {
03121 #ifndef NO_WOLFSSL_CLIENT
03122         TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
03123         CertificateStatusRequestItemV2* csr2 = extension ?
03124                         (CertificateStatusRequestItemV2*)extension->data : NULL;
03125 
03126         if (!csr2) {
03127             /* look at context level */
03128             extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
03129             csr2 = extension ?
03130                         (CertificateStatusRequestItemV2*)extension->data : NULL;
03131 
03132             if (!csr2) /* unexpected extension */
03133                 return TLSX_HandleUnsupportedExtension(ssl);
03134 
03135             /* enable extension at ssl level */
03136             for (; csr2; csr2 = csr2->next) {
03137                 ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
03138                                     csr2->status_type, csr2->options, ssl->heap,
03139                                                                     ssl->devId);
03140                 if (ret != WOLFSSL_SUCCESS)
03141                     return ret;
03142 
03143                 switch (csr2->status_type) {
03144                     case WOLFSSL_CSR2_OCSP:
03145                         /* followed by */
03146                     case WOLFSSL_CSR2_OCSP_MULTI:
03147                         /* propagate nonce */
03148                         if (csr2->request.ocsp[0].nonceSz) {
03149                             OcspRequest* request =
03150                              (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions,
03151                                                           csr2->status_type, 0);
03152 
03153                             if (request) {
03154                                 XMEMCPY(request->nonce,
03155                                         csr2->request.ocsp[0].nonce,
03156                                         csr2->request.ocsp[0].nonceSz);
03157 
03158                                 request->nonceSz =
03159                                                   csr2->request.ocsp[0].nonceSz;
03160                             }
03161                         }
03162                     break;
03163                 }
03164             }
03165         }
03166 
03167         ssl->status_request_v2 = 1;
03168 
03169         return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
03170 #endif
03171     }
03172     else {
03173 #ifndef NO_WOLFSSL_SERVER
03174         byte   status_type;
03175         word16 request_length;
03176         word16 offset = 0;
03177         word16 size = 0;
03178 
03179         /* list size */
03180         if (offset + OPAQUE16_LEN >= length) {
03181             return BUFFER_E;
03182         }
03183 
03184         ato16(input + offset, &request_length);
03185         offset += OPAQUE16_LEN;
03186 
03187         if (length - OPAQUE16_LEN != request_length)
03188             return BUFFER_ERROR;
03189 
03190         while (length > offset) {
03191             if (length - offset < ENUM_LEN + OPAQUE16_LEN)
03192                 return BUFFER_ERROR;
03193 
03194             status_type = input[offset++];
03195 
03196             ato16(input + offset, &request_length);
03197             offset += OPAQUE16_LEN;
03198 
03199             if (length - offset < request_length)
03200                 return BUFFER_ERROR;
03201 
03202             switch (status_type) {
03203                 case WOLFSSL_CSR2_OCSP:
03204                 case WOLFSSL_CSR2_OCSP_MULTI:
03205                     /* skip responder_id_list */
03206                     if (length - offset < OPAQUE16_LEN)
03207                         return BUFFER_ERROR;
03208 
03209                     ato16(input + offset, &size);
03210                     offset += OPAQUE16_LEN + size;
03211 
03212                     /* skip request_extensions */
03213                     if (length - offset < OPAQUE16_LEN)
03214                         return BUFFER_ERROR;
03215 
03216                     ato16(input + offset, &size);
03217                     offset += OPAQUE16_LEN + size;
03218 
03219                     if (offset > length)
03220                         return BUFFER_ERROR;
03221 
03222                     /* is able to send OCSP response? */
03223                     if (ssl->ctx->cm == NULL
03224                     || !ssl->ctx->cm->ocspStaplingEnabled)
03225                         continue;
03226                 break;
03227 
03228                 default:
03229                     /* unknown status type, skipping! */
03230                     offset += request_length;
03231                     continue;
03232             }
03233 
03234             /* if using status_request and already sending it, skip this one */
03235             #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
03236             if (ssl->status_request)
03237                 return 0;
03238             #endif
03239 
03240             /* accept the first good status_type and return */
03241             ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
03242                                          status_type, 0, ssl->heap, ssl->devId);
03243             if (ret != WOLFSSL_SUCCESS)
03244                 return ret; /* throw error */
03245 
03246             TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
03247             ssl->status_request_v2 = status_type;
03248 
03249             return 0;
03250         }
03251 #endif
03252     }
03253 
03254     return 0;
03255 }
03256 
03257 int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer,
03258                                                                      void* heap)
03259 {
03260     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
03261     CertificateStatusRequestItemV2* csr2 = extension ?
03262         (CertificateStatusRequestItemV2*)extension->data : NULL;
03263     int ret = 0;
03264 
03265     for (; csr2; csr2 = csr2->next) {
03266         switch (csr2->status_type) {
03267             case WOLFSSL_CSR2_OCSP:
03268                 if (!isPeer || csr2->requests != 0)
03269                     break;
03270 
03271                 FALL_THROUGH; /* followed by */
03272 
03273             case WOLFSSL_CSR2_OCSP_MULTI: {
03274                 if (csr2->requests < 1 + MAX_CHAIN_DEPTH) {
03275                     byte nonce[MAX_OCSP_NONCE_SZ];
03276                     int  nonceSz = csr2->request.ocsp[0].nonceSz;
03277 
03278                     /* preserve nonce, replicating nonce of ocsp[0] */
03279                     XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz);
03280 
03281                     if ((ret = InitOcspRequest(
03282                                       &csr2->request.ocsp[csr2->requests], cert,
03283                                                                  0, heap)) != 0)
03284                         return ret;
03285 
03286                     /* restore nonce */
03287                     XMEMCPY(csr2->request.ocsp[csr2->requests].nonce,
03288                                                                 nonce, nonceSz);
03289                     csr2->request.ocsp[csr2->requests].nonceSz = nonceSz;
03290                     csr2->requests++;
03291                 }
03292             }
03293             break;
03294         }
03295     }
03296 
03297     (void)cert;
03298     return ret;
03299 }
03300 
03301 void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx)
03302 {
03303     TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
03304     CertificateStatusRequestItemV2* csr2 = extension ?
03305                         (CertificateStatusRequestItemV2*)extension->data : NULL;
03306 
03307     for (; csr2; csr2 = csr2->next) {
03308         if (csr2->status_type == status_type) {
03309             switch (csr2->status_type) {
03310                 case WOLFSSL_CSR2_OCSP:
03311                     /* followed by */
03312 
03313                 case WOLFSSL_CSR2_OCSP_MULTI:
03314                     /* requests are initialized in the reverse order */
03315                     return idx < csr2->requests
03316                          ? &csr2->request.ocsp[csr2->requests - idx - 1]
03317                          : NULL;
03318                 break;
03319             }
03320         }
03321     }
03322 
03323     return NULL;
03324 }
03325 
03326 int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
03327 {
03328     TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
03329     CertificateStatusRequestItemV2* csr2 = extension ?
03330                         (CertificateStatusRequestItemV2*)extension->data : NULL;
03331 
03332     /* forces only the first one */
03333     if (csr2) {
03334         switch (csr2->status_type) {
03335             case WOLFSSL_CSR2_OCSP:
03336                 /* followed by */
03337 
03338             case WOLFSSL_CSR2_OCSP_MULTI:
03339                 if (ssl->ctx->cm->ocspEnabled) {
03340                     csr2->request.ocsp[0].ssl = ssl;
03341                     return CheckOcspRequest(ssl->ctx->cm->ocsp,
03342                                                   &csr2->request.ocsp[0], NULL);
03343                 }
03344                 else
03345                     return OCSP_LOOKUP_FAIL;
03346         }
03347     }
03348 
03349     return 0;
03350 }
03351 
03352 int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
03353                                            byte options, void* heap, int devId)
03354 {
03355     TLSX* extension = NULL;
03356     CertificateStatusRequestItemV2* csr2 = NULL;
03357     int ret = 0;
03358 
03359     if (!extensions)
03360         return BAD_FUNC_ARG;
03361 
03362     if (status_type != WOLFSSL_CSR2_OCSP
03363     &&  status_type != WOLFSSL_CSR2_OCSP_MULTI)
03364         return BAD_FUNC_ARG;
03365 
03366     csr2 = (CertificateStatusRequestItemV2*)
03367        XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX);
03368     if (!csr2)
03369         return MEMORY_E;
03370 
03371     ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
03372 
03373     csr2->status_type = status_type;
03374     csr2->options     = options;
03375     csr2->next        = NULL;
03376 
03377     switch (csr2->status_type) {
03378         case WOLFSSL_CSR2_OCSP:
03379         case WOLFSSL_CSR2_OCSP_MULTI:
03380             if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
03381                 WC_RNG rng;
03382 
03383             #ifndef HAVE_FIPS
03384                 ret = wc_InitRng_ex(&rng, heap, devId);
03385             #else
03386                 ret = wc_InitRng(&rng);
03387                 (void)devId;
03388             #endif
03389                 if (ret == 0) {
03390                     if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce,
03391                                                         MAX_OCSP_NONCE_SZ) == 0)
03392                         csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
03393 
03394                     wc_FreeRng(&rng);
03395                 }
03396             }
03397         break;
03398     }
03399 
03400     /* append new item */
03401     if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
03402         CertificateStatusRequestItemV2* last =
03403                                (CertificateStatusRequestItemV2*)extension->data;
03404 
03405         for (; last->next; last = last->next);
03406 
03407         last->next = csr2;
03408     }
03409     else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) {
03410         XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
03411         return ret;
03412     }
03413 
03414     return WOLFSSL_SUCCESS;
03415 }
03416 
03417 #define CSR2_FREE_ALL TLSX_CSR2_FreeAll
03418 #define CSR2_GET_SIZE TLSX_CSR2_GetSize
03419 #define CSR2_WRITE    TLSX_CSR2_Write
03420 #define CSR2_PARSE    TLSX_CSR2_Parse
03421 
03422 #else
03423 
03424 #define CSR2_FREE_ALL(data, heap)
03425 #define CSR2_GET_SIZE(a, b)    0
03426 #define CSR2_WRITE(a, b, c)    0
03427 #define CSR2_PARSE(a, b, c, d) 0
03428 
03429 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
03430 
03431 /******************************************************************************/
03432 /* Supported Elliptic Curves                                                  */
03433 /******************************************************************************/
03434 
03435 #ifdef HAVE_SUPPORTED_CURVES
03436 
03437 #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(WOLFSSL_TLS13)
03438 #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
03439        Use --enable-ecc in the configure script or define HAVE_ECC.
03440 #endif
03441 
03442 static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
03443                                                                      void* heap)
03444 {
03445     if (curve == NULL)
03446         return BAD_FUNC_ARG;
03447 
03448     (void)heap;
03449 
03450     *curve = (SupportedCurve*)XMALLOC(sizeof(SupportedCurve), heap,
03451                                                              DYNAMIC_TYPE_TLSX);
03452     if (*curve == NULL)
03453         return MEMORY_E;
03454 
03455     (*curve)->name = name;
03456     (*curve)->next = NULL;
03457 
03458     return 0;
03459 }
03460 
03461 static int TLSX_PointFormat_New(PointFormat** point, byte format, void* heap)
03462 {
03463     if (point == NULL)
03464         return BAD_FUNC_ARG;
03465 
03466     (void)heap;
03467 
03468     *point = (PointFormat*)XMALLOC(sizeof(PointFormat), heap,
03469                                                              DYNAMIC_TYPE_TLSX);
03470     if (*point == NULL)
03471         return MEMORY_E;
03472 
03473     (*point)->format = format;
03474     (*point)->next = NULL;
03475 
03476     return 0;
03477 }
03478 
03479 static void TLSX_SupportedCurve_FreeAll(SupportedCurve* list, void* heap)
03480 {
03481     SupportedCurve* curve;
03482 
03483     while ((curve = list)) {
03484         list = curve->next;
03485         XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
03486     }
03487     (void)heap;
03488 }
03489 
03490 static void TLSX_PointFormat_FreeAll(PointFormat* list, void* heap)
03491 {
03492     PointFormat* point;
03493 
03494     while ((point = list)) {
03495         list = point->next;
03496         XFREE(point, heap, DYNAMIC_TYPE_TLSX);
03497     }
03498     (void)heap;
03499 }
03500 
03501 static int TLSX_SupportedCurve_Append(SupportedCurve* list, word16 name,
03502                                                                      void* heap)
03503 {
03504     int ret = BAD_FUNC_ARG;
03505 
03506     while (list) {
03507         if (list->name == name) {
03508             ret = 0; /* curve alreay in use */
03509             break;
03510         }
03511 
03512         if (list->next == NULL) {
03513             ret = TLSX_SupportedCurve_New(&list->next, name, heap);
03514             break;
03515         }
03516 
03517         list = list->next;
03518     }
03519 
03520     return ret;
03521 }
03522 
03523 static int TLSX_PointFormat_Append(PointFormat* list, byte format, void* heap)
03524 {
03525     int ret = BAD_FUNC_ARG;
03526 
03527     while (list) {
03528         if (list->format == format) {
03529             ret = 0; /* format already in use */
03530             break;
03531         }
03532 
03533         if (list->next == NULL) {
03534             ret = TLSX_PointFormat_New(&list->next, format, heap);
03535             break;
03536         }
03537 
03538         list = list->next;
03539     }
03540 
03541     return ret;
03542 }
03543 
03544 #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
03545 
03546 static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
03547 {
03548     int i;
03549 
03550     for (i = 0; i < ssl->suites->suiteSz; i+= 2)
03551         if (ssl->suites->suites[i] == ECC_BYTE ||
03552                 ssl->suites->suites[i] == CHACHA_BYTE ||
03553                 ssl->suites->suites[i] == TLS13_BYTE)
03554             return;
03555 
03556     /* turns semaphore on to avoid sending this extension. */
03557     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
03558 }
03559 
03560 static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
03561 {
03562     int i;
03563 
03564     for (i = 0; i < ssl->suites->suiteSz; i+= 2)
03565         if (ssl->suites->suites[i] == ECC_BYTE ||
03566                 ssl->suites->suites[i] == CHACHA_BYTE ||
03567                 ssl->suites->suites[i] == TLS13_BYTE)
03568             return;
03569 
03570     /* turns semaphore on to avoid sending this extension. */
03571     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
03572 }
03573 
03574 #endif
03575 
03576 #ifndef NO_WOLFSSL_SERVER
03577 
03578 static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
03579 {
03580     if (ssl->options.cipherSuite0 == ECC_BYTE ||
03581         ssl->options.cipherSuite0 == CHACHA_BYTE ||
03582         ssl->options.cipherSuite0 == TLS13_BYTE)
03583         return;
03584 
03585     /* turns semaphore on to avoid sending this extension. */
03586     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
03587 }
03588 
03589 #endif
03590 #ifndef NO_WOLFSSL_CLIENT
03591 
03592 static word16 TLSX_SupportedCurve_GetSize(SupportedCurve* list)
03593 {
03594     SupportedCurve* curve;
03595     word16 length = OPAQUE16_LEN; /* list length */
03596 
03597     while ((curve = list)) {
03598         list = curve->next;
03599         length += OPAQUE16_LEN; /* curve length */
03600     }
03601 
03602     return length;
03603 }
03604 
03605 #endif
03606 
03607 static word16 TLSX_PointFormat_GetSize(PointFormat* list)
03608 {
03609     PointFormat* point;
03610     word16 length = ENUM_LEN; /* list length */
03611 
03612     while ((point = list)) {
03613         list = point->next;
03614         length += ENUM_LEN; /* format length */
03615     }
03616 
03617     return length;
03618 }
03619 
03620 #ifndef NO_WOLFSSL_CLIENT
03621 
03622 static word16 TLSX_SupportedCurve_Write(SupportedCurve* list, byte* output)
03623 {
03624     word16 offset = OPAQUE16_LEN;
03625 
03626     while (list) {
03627         c16toa(list->name, output + offset);
03628         offset += OPAQUE16_LEN;
03629         list = list->next;
03630     }
03631 
03632     c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
03633 
03634     return offset;
03635 }
03636 
03637 #endif
03638 
03639 static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output)
03640 {
03641     word16 offset = ENUM_LEN;
03642 
03643     while (list) {
03644         output[offset++] = list->format;
03645         list = list->next;
03646     }
03647 
03648     output[0] = (byte)(offset - ENUM_LEN);
03649 
03650     return offset;
03651 }
03652 
03653 #if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
03654                                          !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
03655 
03656 static int TLSX_SupportedCurve_Parse(WOLFSSL* ssl, byte* input, word16 length,
03657                                                                  byte isRequest)
03658 {
03659     word16 offset;
03660     word16 name;
03661     int ret;
03662 
03663     if(!isRequest && !IsAtLeastTLSv1_3(ssl->version))
03664         return BUFFER_ERROR; /* servers doesn't send this extension. */
03665 
03666     if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
03667         return BUFFER_ERROR;
03668 
03669     ato16(input, &offset);
03670 
03671     /* validating curve list length */
03672     if (length != OPAQUE16_LEN + offset)
03673         return BUFFER_ERROR;
03674 
03675     offset = OPAQUE16_LEN;
03676     if (offset == length)
03677         return 0;
03678 
03679 #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
03680     if (!isRequest) {
03681         TLSX* extension;
03682         SupportedCurve* curve;
03683 
03684         extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
03685         if (extension != NULL) {
03686             /* Replace client list with server list of supported groups. */
03687             curve = (SupportedCurve*)extension->data;
03688             extension->data = NULL;
03689             TLSX_SupportedCurve_FreeAll(curve, ssl->heap);
03690 
03691             ato16(input + offset, &name);
03692             offset += OPAQUE16_LEN;
03693 
03694             ret = TLSX_SupportedCurve_New(&curve, name, ssl->heap);
03695             if (ret != 0)
03696                 return ret; /* throw error */
03697             extension->data = (void*)curve;
03698         }
03699     }
03700 #endif
03701 
03702     for (; offset < length; offset += OPAQUE16_LEN) {
03703         ato16(input + offset, &name);
03704 
03705         ret = TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
03706         if (ret != WOLFSSL_SUCCESS)
03707             return ret; /* throw error */
03708     }
03709 
03710     return 0;
03711 }
03712 
03713 #endif
03714 
03715 #if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
03716                                           !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
03717 
03718 /* Checks the priority of the groups on the server and set the supported groups
03719  * response if there is a group not advertised by the client that is preferred.
03720  *
03721  * ssl  SSL/TLS object.
03722  * returns 0 on success, otherwise an error.
03723  */
03724 int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl)
03725 {
03726     int ret;
03727     TLSX* extension;
03728     TLSX* priority = NULL;
03729     TLSX* ext = NULL;
03730     word16 name;
03731     SupportedCurve* curve;
03732 
03733     extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
03734     /* May be doing PSK with no key exchange. */
03735     if (extension == NULL)
03736         return 0;
03737 
03738     if ((ret = TLSX_PopulateSupportedGroups(ssl, &priority)) != WOLFSSL_SUCCESS)
03739         return ret;
03740 
03741     ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
03742     curve = (SupportedCurve*)ext->data;
03743     name = curve->name;
03744 
03745     curve = (SupportedCurve*)extension->data;
03746     while (curve != NULL) {
03747         if (curve->name == name)
03748             break;
03749         curve = curve->next;
03750     }
03751 
03752     if (curve == NULL) {
03753         /* Couldn't find the preferred group in client list. */
03754         extension->resp = 1;
03755 
03756         /* Send server list back and free client list. */
03757         curve = (SupportedCurve*)extension->data;
03758         extension->data = ext->data;
03759         ext->data = curve;
03760     }
03761 
03762     TLSX_FreeAll(priority, ssl->heap);
03763 
03764     return 0;
03765 }
03766 
03767 #endif
03768 
03769 #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
03770 /* Return the preferred group.
03771  *
03772  * ssl             SSL/TLS object.
03773  * checkSupported  Whether to check for the first supported group.
03774  * returns BAD_FUNC_ARG if no group found, otherwise the group.
03775  */
03776 int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported)
03777 {
03778     TLSX* extension;
03779     SupportedCurve* curve;
03780 
03781     extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
03782     if (extension == NULL)
03783         return BAD_FUNC_ARG;
03784 
03785     curve = (SupportedCurve*)extension->data;
03786     while (curve != NULL) {
03787         if (!checkSupported || TLSX_KeyShare_IsSupported(curve->name))
03788             return curve->name;
03789         curve = curve->next;
03790     }
03791 
03792     return BAD_FUNC_ARG;
03793 }
03794 
03795 #endif
03796 
03797 #ifndef NO_WOLFSSL_SERVER
03798 
03799 static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length,
03800                                                                  byte isRequest)
03801 {
03802     int ret;
03803 
03804     /* validating formats list length */
03805     if (ENUM_LEN > length || length != ENUM_LEN + input[0])
03806         return BUFFER_ERROR;
03807 
03808     if (isRequest) {
03809         /* adding uncompressed point format to response */
03810         ret = TLSX_UsePointFormat(&ssl->extensions, WOLFSSL_EC_PF_UNCOMPRESSED,
03811                                                                      ssl->heap);
03812         if (ret != WOLFSSL_SUCCESS)
03813             return ret; /* throw error */
03814 
03815         TLSX_SetResponse(ssl, TLSX_EC_POINT_FORMATS);
03816     }
03817 
03818     return 0;
03819 }
03820 
03821 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
03822 int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
03823     TLSX*          extension = (first == ECC_BYTE || first == CHACHA_BYTE)
03824                              ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS)
03825                              : NULL;
03826     SupportedCurve* curve     = NULL;
03827     word32         oid       = 0;
03828     word32         pkOid     = 0;
03829     word32         defOid    = 0;
03830     word32         defSz     = 80; /* Maximum known curve size is 66. */
03831     word32         nextOid   = 0;
03832     word32         nextSz    = 80; /* Maximum known curve size is 66. */
03833     word32         currOid   = ssl->ecdhCurveOID;
03834     int            ephmSuite = 0;
03835     word16         octets    = 0; /* according to 'ecc_set_type ecc_sets[];' */
03836     int            sig       = 0; /* validate signature */
03837     int            key       = 0; /* validate key       */
03838 
03839     (void)oid;
03840 
03841     if (!extension)
03842         return 1; /* no suite restriction */
03843 
03844     for (curve = (SupportedCurve*)extension->data;
03845          curve && !(sig && key);
03846          curve = curve->next) {
03847 
03848     #ifdef OPENSSL_EXTRA
03849         if (ssl->ctx->disabledCurves & (1 << curve->name))
03850             continue;
03851     #endif
03852 
03853         /* find supported curve */
03854         switch (curve->name) {
03855 #ifdef HAVE_ECC
03856     #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
03857         #ifndef NO_ECC_SECP
03858             case WOLFSSL_ECC_SECP160R1:
03859                 pkOid = oid = ECC_SECP160R1_OID;
03860                 octets = 20;
03861                 break;
03862         #endif /* !NO_ECC_SECP */
03863         #ifdef HAVE_ECC_SECPR2
03864             case WOLFSSL_ECC_SECP160R2:
03865                 pkOid = oid = ECC_SECP160R2_OID;
03866                 octets = 20;
03867                 break;
03868         #endif /* HAVE_ECC_SECPR2 */
03869         #ifdef HAVE_ECC_KOBLITZ
03870             case WOLFSSL_ECC_SECP160K1:
03871                 pkOid = oid = ECC_SECP160K1_OID;
03872                 octets = 20;
03873                 break;
03874         #endif /* HAVE_ECC_KOBLITZ */
03875     #endif
03876     #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
03877         #ifndef NO_ECC_SECP
03878             case WOLFSSL_ECC_SECP192R1:
03879                 pkOid = oid = ECC_SECP192R1_OID;
03880                 octets = 24;
03881                 break;
03882         #endif /* !NO_ECC_SECP */
03883         #ifdef HAVE_ECC_KOBLITZ
03884             case WOLFSSL_ECC_SECP192K1:
03885                 pkOid = oid = ECC_SECP192K1_OID;
03886                 octets = 24;
03887                 break;
03888         #endif /* HAVE_ECC_KOBLITZ */
03889     #endif
03890     #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
03891         #ifndef NO_ECC_SECP
03892             case WOLFSSL_ECC_SECP224R1:
03893                 pkOid = oid = ECC_SECP224R1_OID;
03894                 octets = 28;
03895                 break;
03896         #endif /* !NO_ECC_SECP */
03897         #ifdef HAVE_ECC_KOBLITZ
03898             case WOLFSSL_ECC_SECP224K1:
03899                 pkOid = oid = ECC_SECP224K1_OID;
03900                 octets = 28;
03901                 break;
03902         #endif /* HAVE_ECC_KOBLITZ */
03903     #endif
03904     #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
03905         #ifndef NO_ECC_SECP
03906             case WOLFSSL_ECC_SECP256R1:
03907                 pkOid = oid = ECC_SECP256R1_OID;
03908                 octets = 32;
03909                 break;
03910         #endif /* !NO_ECC_SECP */
03911     #endif /* !NO_ECC256 || HAVE_ALL_CURVES */
03912 #endif
03913         #ifdef HAVE_CURVE25519
03914             case WOLFSSL_ECC_X25519:
03915                 oid = ECC_X25519_OID;
03916             #ifdef HAVE_ED25519
03917                 pkOid = ECC_ED25519_OID;
03918             #else
03919                 pkOid = ECC_X25519_OID;
03920             #endif
03921                 octets = 32;
03922                 break;
03923         #endif /* HAVE_CURVE25519 */
03924 #ifdef HAVE_ECC
03925     #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
03926         #ifdef HAVE_ECC_KOBLITZ
03927             case WOLFSSL_ECC_SECP256K1:
03928                 pkOid = oid = ECC_SECP256K1_OID;
03929                 octets = 32;
03930                 break;
03931         #endif /* HAVE_ECC_KOBLITZ */
03932         #ifdef HAVE_ECC_BRAINPOOL
03933             case WOLFSSL_ECC_BRAINPOOLP256R1:
03934                 pkOid = oid = ECC_BRAINPOOLP256R1_OID;
03935                 octets = 32;
03936                 break;
03937         #endif /* HAVE_ECC_BRAINPOOL */
03938     #endif
03939     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
03940         #ifndef NO_ECC_SECP
03941             case WOLFSSL_ECC_SECP384R1:
03942                 pkOid = oid = ECC_SECP384R1_OID;
03943                 octets = 48;
03944                 break;
03945         #endif /* !NO_ECC_SECP */
03946         #ifdef HAVE_ECC_BRAINPOOL
03947             case WOLFSSL_ECC_BRAINPOOLP384R1:
03948                 pkOid = oid = ECC_BRAINPOOLP384R1_OID;
03949                 octets = 48;
03950                 break;
03951         #endif /* HAVE_ECC_BRAINPOOL */
03952     #endif
03953     #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
03954         #ifdef HAVE_ECC_BRAINPOOL
03955             case WOLFSSL_ECC_BRAINPOOLP512R1:
03956                 pkOid = oid = ECC_BRAINPOOLP512R1_OID;
03957                 octets = 64;
03958                 break;
03959         #endif /* HAVE_ECC_BRAINPOOL */
03960     #endif
03961     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
03962         #ifndef NO_ECC_SECP
03963             case WOLFSSL_ECC_SECP521R1:
03964                 pkOid = oid = ECC_SECP521R1_OID;
03965                 octets = 66;
03966                 break;
03967         #endif /* !NO_ECC_SECP */
03968     #endif
03969 #endif
03970             default: continue; /* unsupported curve */
03971         }
03972 
03973     #ifdef HAVE_ECC
03974         /* Set default Oid */
03975         if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) {
03976             defOid = oid;
03977             defSz = octets;
03978         }
03979 
03980         if (currOid == 0 && ssl->eccTempKeySz == octets)
03981             currOid = oid;
03982         if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) {
03983             nextOid = oid;
03984             nextSz  = octets;
03985         }
03986     #else
03987         if (defOid == 0 && defSz > octets) {
03988             defOid = oid;
03989             defSz = octets;
03990         }
03991 
03992         if (currOid == 0)
03993             currOid = oid;
03994         if (nextOid == 0 || nextSz > octets) {
03995             nextOid = oid;
03996             nextSz  = octets;
03997         }
03998     #endif
03999 
04000         if (first == ECC_BYTE) {
04001             switch (second) {
04002                 /* ECDHE_ECDSA */
04003                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
04004                 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
04005                 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
04006                 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
04007                 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
04008                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
04009                 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
04010                 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
04011                 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
04012                 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
04013                     sig |= ssl->pkCurveOID == pkOid;
04014                     key |= ssl->ecdhCurveOID == oid;
04015                     ephmSuite = 1;
04016                 break;
04017 
04018 #ifdef WOLFSSL_STATIC_DH
04019                 /* ECDH_ECDSA */
04020                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
04021                 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
04022                 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
04023                 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
04024                 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
04025                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
04026                 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
04027                 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
04028                     if (oid == ECC_X25519_OID && defOid == oid) {
04029                         defOid = 0;
04030                         defSz = 80;
04031                     }
04032                     sig |= ssl->pkCurveOID == pkOid;
04033                     key |= ssl->pkCurveOID == oid;
04034                 break;
04035 #endif /* WOLFSSL_STATIC_DH */
04036 #ifndef NO_RSA
04037                 /* ECDHE_RSA */
04038                 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
04039                 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
04040                 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
04041                 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
04042                 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
04043                 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
04044                 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
04045                 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
04046                     sig = 1;
04047                     key |= ssl->ecdhCurveOID == oid;
04048                     ephmSuite = 1;
04049                 break;
04050 
04051 #ifdef WOLFSSL_STATIC_DH
04052                 /* ECDH_RSA */
04053                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
04054                 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
04055                 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
04056                 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
04057                 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
04058                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
04059                 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
04060                 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
04061                     if (oid == ECC_X25519_OID && defOid == oid) {
04062                         defOid = 0;
04063                         defSz = 80;
04064                     }
04065                     sig = 1;
04066                     key |= ssl->pkCurveOID == pkOid;
04067                 break;
04068 #endif /* WOLFSSL_STATIC_DH */
04069 #endif
04070                 default:
04071                     if (oid == ECC_X25519_OID && defOid == oid) {
04072                         defOid = 0;
04073                         defSz = 80;
04074                     }
04075                     if (oid != ECC_X25519_OID)
04076                         sig = 1;
04077                     key = 1;
04078                 break;
04079             }
04080         }
04081 
04082         /* ChaCha20-Poly1305 ECC cipher suites */
04083         if (first == CHACHA_BYTE) {
04084             switch (second) {
04085                 /* ECDHE_ECDSA */
04086                 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
04087                 case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
04088                     sig |= ssl->pkCurveOID == pkOid;
04089                     key |= ssl->ecdhCurveOID == oid;
04090                     ephmSuite = 1;
04091                 break;
04092 #ifndef NO_RSA
04093                 /* ECDHE_RSA */
04094                 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
04095                 case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
04096                     sig = 1;
04097                     key |= ssl->ecdhCurveOID == oid;
04098                     ephmSuite = 1;
04099                 break;
04100 #endif
04101                 default:
04102                     sig = 1;
04103                     key = 1;
04104                 break;
04105             }
04106         }
04107     }
04108 
04109     /* Choose the default if it is at the required strength. */
04110 #ifdef HAVE_ECC
04111     if (ssl->ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz)
04112 #else
04113     if (ssl->ecdhCurveOID == 0)
04114 #endif
04115     {
04116         key = 1;
04117         ssl->ecdhCurveOID = defOid;
04118     }
04119     /* Choose any curve at the required strength. */
04120     if (ssl->ecdhCurveOID == 0) {
04121         key = 1;
04122         ssl->ecdhCurveOID = currOid;
04123     }
04124     /* Choose the default if it is at the next highest strength. */
04125     if (ssl->ecdhCurveOID == 0 && defSz == nextSz)
04126         ssl->ecdhCurveOID = defOid;
04127     /* Choose any curve at the next highest strength. */
04128     if (ssl->ecdhCurveOID == 0)
04129         ssl->ecdhCurveOID = nextOid;
04130     /* No curve and ephemeral ECC suite requires a matching curve. */
04131     if (ssl->ecdhCurveOID == 0 && ephmSuite)
04132         key = 0;
04133 
04134     return sig && key;
04135 }
04136 #endif
04137 
04138 #endif /* NO_WOLFSSL_SERVER */
04139 
04140 int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap)
04141 {
04142     TLSX* extension = NULL;
04143     SupportedCurve* curve = NULL;
04144     int ret;
04145 
04146     if (extensions == NULL)
04147         return BAD_FUNC_ARG;
04148 
04149     extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
04150 
04151     if (!extension) {
04152         ret = TLSX_SupportedCurve_New(&curve, name, heap);
04153         if (ret != 0)
04154             return ret;
04155 
04156         ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap);
04157         if (ret != 0) {
04158             XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
04159             return ret;
04160         }
04161     }
04162     else {
04163         ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data, name,
04164                                                                           heap);
04165         if (ret != 0)
04166             return ret;
04167     }
04168 
04169     return WOLFSSL_SUCCESS;
04170 }
04171 
04172 int TLSX_UsePointFormat(TLSX** extensions, byte format, void* heap)
04173 {
04174     TLSX* extension = NULL;
04175     PointFormat* point = NULL;
04176     int ret = 0;
04177 
04178     if (extensions == NULL)
04179         return BAD_FUNC_ARG;
04180 
04181     extension = TLSX_Find(*extensions, TLSX_EC_POINT_FORMATS);
04182 
04183     if (!extension) {
04184         ret = TLSX_PointFormat_New(&point, format, heap);
04185         if (ret != 0)
04186             return ret;
04187 
04188         ret = TLSX_Push(extensions, TLSX_EC_POINT_FORMATS, point, heap);
04189         if (ret != 0) {
04190             XFREE(point, heap, DYNAMIC_TYPE_TLSX);
04191             return ret;
04192         }
04193     }
04194     else {
04195         ret = TLSX_PointFormat_Append((PointFormat*)extension->data, format,
04196                                                                           heap);
04197         if (ret != 0)
04198             return ret;
04199     }
04200 
04201     return WOLFSSL_SUCCESS;
04202 }
04203 
04204 #define EC_FREE_ALL         TLSX_SupportedCurve_FreeAll
04205 #define EC_VALIDATE_REQUEST TLSX_SupportedCurve_ValidateRequest
04206 
04207 #ifndef NO_WOLFSSL_CLIENT
04208 #define EC_GET_SIZE TLSX_SupportedCurve_GetSize
04209 #define EC_WRITE    TLSX_SupportedCurve_Write
04210 #else
04211 #define EC_GET_SIZE(list)         0
04212 #define EC_WRITE(a, b)            0
04213 #endif
04214 
04215 #if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
04216                                          !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
04217 #define EC_PARSE TLSX_SupportedCurve_Parse
04218 #else
04219 #define EC_PARSE(a, b, c, d)      0
04220 #endif
04221 
04222 #define PF_FREE_ALL          TLSX_PointFormat_FreeAll
04223 #define PF_VALIDATE_REQUEST  TLSX_PointFormat_ValidateRequest
04224 #define PF_VALIDATE_RESPONSE TLSX_PointFormat_ValidateResponse
04225 
04226 #define PF_GET_SIZE TLSX_PointFormat_GetSize
04227 #define PF_WRITE    TLSX_PointFormat_Write
04228 
04229 #ifndef NO_WOLFSSL_SERVER
04230 #define PF_PARSE TLSX_PointFormat_Parse
04231 #else
04232 #define PF_PARSE(a, b, c, d)      0
04233 #endif
04234 
04235 #else
04236 
04237 #define EC_FREE_ALL(list, heap)
04238 #define EC_GET_SIZE(list)         0
04239 #define EC_WRITE(a, b)            0
04240 #define EC_PARSE(a, b, c, d)      0
04241 #define EC_VALIDATE_REQUEST(a, b)
04242 
04243 #define PF_FREE_ALL(list, heap)
04244 #define PF_GET_SIZE(list)         0
04245 #define PF_WRITE(a, b)            0
04246 #define PF_PARSE(a, b, c, d)      0
04247 #define PF_VALIDATE_REQUEST(a, b)
04248 #define PF_VALIDATE_RESPONSE(a, b)
04249 
04250 #endif /* HAVE_SUPPORTED_CURVES */
04251 
04252 /******************************************************************************/
04253 /* Renegotiation Indication                                                   */
04254 /******************************************************************************/
04255 
04256 #if defined(HAVE_SECURE_RENEGOTIATION) \
04257  || defined(HAVE_SERVER_RENEGOTIATION_INFO)
04258 
04259 static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
04260                                                                   int isRequest)
04261 {
04262     byte length = OPAQUE8_LEN; /* empty info length */
04263 
04264     /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */
04265     if (data && data->enabled) {
04266         /* client sends client_verify_data only */
04267         length += TLS_FINISHED_SZ;
04268 
04269         /* server also sends server_verify_data */
04270         if (!isRequest)
04271             length += TLS_FINISHED_SZ;
04272     }
04273 
04274     return length;
04275 }
04276 
04277 static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
04278                                                     byte* output, int isRequest)
04279 {
04280     word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
04281 
04282     if (data && data->enabled) {
04283         /* client sends client_verify_data only */
04284         XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
04285         offset += TLS_FINISHED_SZ;
04286 
04287         /* server also sends server_verify_data */
04288         if (!isRequest) {
04289             XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
04290             offset += TLS_FINISHED_SZ;
04291         }
04292     }
04293 
04294     output[0] = (byte)(offset - 1);  /* info length - self */
04295 
04296     return offset;
04297 }
04298 
04299 static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input,
04300                                                   word16 length, byte isRequest)
04301 {
04302     int ret = SECURE_RENEGOTIATION_E;
04303 
04304     if (length >= OPAQUE8_LEN) {
04305         if (ssl->secure_renegotiation == NULL) {
04306         #ifndef NO_WOLFSSL_SERVER
04307             if (isRequest && *input == 0) {
04308             #ifdef HAVE_SERVER_RENEGOTIATION_INFO
04309                 if (length == OPAQUE8_LEN) {
04310                     if (TLSX_Find(ssl->extensions,
04311                                   TLSX_RENEGOTIATION_INFO) == NULL) {
04312                         ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions,
04313                                                              ssl->heap);
04314                         if (ret == WOLFSSL_SUCCESS)
04315                             ret = 0;
04316 
04317                     } else {
04318                         ret = 0;
04319                     }
04320                 }
04321             #else
04322                 ret = 0;  /* don't reply, user didn't enable */
04323             #endif /* HAVE_SERVER_RENEGOTIATION_INFO */
04324             }
04325             #ifdef HAVE_SERVER_RENEGOTIATION_INFO
04326             else if (!isRequest) {
04327                 /* don't do anything on client side */
04328                 ret = 0;
04329             }
04330             #endif
04331         #endif
04332         }
04333         else if (isRequest) {
04334         #ifndef NO_WOLFSSL_SERVER
04335             if (*input == TLS_FINISHED_SZ) {
04336                 /* TODO compare client_verify_data */
04337                 ret = 0;
04338             }
04339         #endif
04340         }
04341         else {
04342         #ifndef NO_WOLFSSL_CLIENT
04343             if (!ssl->secure_renegotiation->enabled) {
04344                 if (*input == 0) {
04345                     ssl->secure_renegotiation->enabled = 1;
04346                     ret = 0;
04347                 }
04348             }
04349             else if (*input == 2 * TLS_FINISHED_SZ &&
04350                      length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) {
04351                 input++;  /* get past size */
04352 
04353                 /* validate client and server verify data */
04354                 if (XMEMCMP(input,
04355                             ssl->secure_renegotiation->client_verify_data,
04356                             TLS_FINISHED_SZ) == 0 &&
04357                     XMEMCMP(input + TLS_FINISHED_SZ,
04358                             ssl->secure_renegotiation->server_verify_data,
04359                             TLS_FINISHED_SZ) == 0) {
04360                     WOLFSSL_MSG("SCR client and server verify data match");
04361                     ret = 0;  /* verified */
04362                 } else {
04363                     /* already in error state */
04364                     WOLFSSL_MSG("SCR client and server verify data Failure");
04365                 }
04366             }
04367         #endif
04368         }
04369     }
04370 
04371     if (ret != 0) {
04372         SendAlert(ssl, alert_fatal, handshake_failure);
04373     }
04374 
04375     return ret;
04376 }
04377 
04378 int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap)
04379 {
04380     int ret = 0;
04381     SecureRenegotiation* data = NULL;
04382 
04383     data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap,
04384                                                              DYNAMIC_TYPE_TLSX);
04385     if (data == NULL)
04386         return MEMORY_E;
04387 
04388     XMEMSET(data, 0, sizeof(SecureRenegotiation));
04389 
04390     ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap);
04391     if (ret != 0) {
04392         XFREE(data, heap, DYNAMIC_TYPE_TLSX);
04393         return ret;
04394     }
04395 
04396     return WOLFSSL_SUCCESS;
04397 }
04398 
04399 #ifdef HAVE_SERVER_RENEGOTIATION_INFO
04400 
04401 int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap)
04402 {
04403     int ret;
04404 
04405     ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, NULL, heap);
04406     if (ret != 0)
04407         return ret;
04408 
04409     /* send empty renegotiation_info extension */
04410     TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
04411     if (ext)
04412         ext->resp = 1;
04413 
04414     return WOLFSSL_SUCCESS;
04415 }
04416 
04417 #endif /* HAVE_SERVER_RENEGOTIATION_INFO */
04418 
04419 
04420 #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
04421 #define SCR_GET_SIZE       TLSX_SecureRenegotiation_GetSize
04422 #define SCR_WRITE          TLSX_SecureRenegotiation_Write
04423 #define SCR_PARSE          TLSX_SecureRenegotiation_Parse
04424 
04425 #else
04426 
04427 #define SCR_FREE_ALL(a, heap)
04428 #define SCR_GET_SIZE(a, b)    0
04429 #define SCR_WRITE(a, b, c)    0
04430 #define SCR_PARSE(a, b, c, d) 0
04431 
04432 #endif /* HAVE_SECURE_RENEGOTIATION */
04433 
04434 /******************************************************************************/
04435 /* Session Tickets                                                            */
04436 /******************************************************************************/
04437 
04438 #ifdef HAVE_SESSION_TICKET
04439 
04440 #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
04441 static void TLSX_SessionTicket_ValidateRequest(WOLFSSL* ssl)
04442 {
04443     TLSX*          extension = TLSX_Find(ssl->extensions, TLSX_SESSION_TICKET);
04444     SessionTicket* ticket    = extension ?
04445                                          (SessionTicket*)extension->data : NULL;
04446 
04447     if (ticket) {
04448         /* TODO validate ticket timeout here! */
04449         if (ticket->lifetime == 0xfffffff) {
04450             /* send empty ticket on timeout */
04451             TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
04452         }
04453     }
04454 }
04455 #endif /* WLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
04456 
04457 
04458 static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
04459 {
04460     (void)isRequest;
04461     return ticket ? ticket->size : 0;
04462 }
04463 
04464 static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
04465                                                                   int isRequest)
04466 {
04467     word16 offset = 0; /* empty ticket */
04468 
04469     if (isRequest && ticket) {
04470         XMEMCPY(output + offset, ticket->data, ticket->size);
04471         offset += ticket->size;
04472     }
04473 
04474     return offset;
04475 }
04476 
04477 
04478 static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, byte* input, word16 length,
04479                                                                  byte isRequest)
04480 {
04481     int ret = 0;
04482 
04483     (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */
04484 
04485     if (!isRequest) {
04486         if (TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET))
04487             return TLSX_HandleUnsupportedExtension(ssl);
04488 
04489         if (length != 0)
04490             return BUFFER_ERROR;
04491 
04492 #ifndef NO_WOLFSSL_CLIENT
04493         ssl->expect_session_ticket = 1;
04494 #endif
04495     }
04496 #ifndef NO_WOLFSSL_SERVER
04497     else {
04498         /* server side */
04499         if (ssl->ctx->ticketEncCb == NULL) {
04500             WOLFSSL_MSG("Client sent session ticket, server has no callback");
04501             return 0;
04502         }
04503 
04504         if (length == 0) {
04505             /* blank ticket */
04506             ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
04507             if (ret == WOLFSSL_SUCCESS) {
04508                 ret = 0;
04509                 TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);  /* send blank ticket */
04510                 ssl->options.createTicket = 1;  /* will send ticket msg */
04511                 ssl->options.useTicket    = 1;
04512                 ssl->options.resuming     = 0;  /* no standard resumption */
04513                 ssl->arrays->sessionIDSz  = 0;  /* no echo on blank ticket */
04514             }
04515         } else {
04516             /* got actual ticket from client */
04517             ret = DoClientTicket(ssl, input, length);
04518             if (ret == WOLFSSL_TICKET_RET_OK) {    /* use ticket to resume */
04519                 WOLFSSL_MSG("Using exisitng client ticket");
04520                 ssl->options.useTicket = 1;
04521                 ssl->options.resuming  = 1;
04522             } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
04523                 WOLFSSL_MSG("Using existing client ticket, creating new one");
04524                 ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
04525                 if (ret == WOLFSSL_SUCCESS) {
04526                     ret = 0;
04527                     TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
04528                                                     /* send blank ticket */
04529                     ssl->options.createTicket = 1;  /* will send ticket msg */
04530                     ssl->options.useTicket    = 1;
04531                     ssl->options.resuming     = 1;
04532                 }
04533             } else if (ret == WOLFSSL_TICKET_RET_REJECT) {
04534                 WOLFSSL_MSG("Process client ticket rejected, not using");
04535                 ssl->options.rejectTicket = 1;
04536                 ret = 0;  /* not fatal */
04537             } else if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) {
04538                 WOLFSSL_MSG("Process client ticket fatal error, not using");
04539             }
04540         }
04541     }
04542 #endif /* NO_WOLFSSL_SERVER */
04543 
04544     return ret;
04545 }
04546 
04547 WOLFSSL_LOCAL SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
04548                                             byte* data, word16 size, void* heap)
04549 {
04550     SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
04551                                                        heap, DYNAMIC_TYPE_TLSX);
04552     if (ticket) {
04553         ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX);
04554         if (ticket->data == NULL) {
04555             XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
04556             return NULL;
04557         }
04558 
04559         XMEMCPY(ticket->data, data, size);
04560         ticket->size     = size;
04561         ticket->lifetime = lifetime;
04562     }
04563 
04564     return ticket;
04565 }
04566 WOLFSSL_LOCAL void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap)
04567 {
04568     if (ticket) {
04569         XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX);
04570         XFREE(ticket,       heap, DYNAMIC_TYPE_TLSX);
04571     }
04572 
04573     (void)heap;
04574 }
04575 
04576 int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap)
04577 {
04578     int ret = 0;
04579 
04580     if (extensions == NULL)
04581         return BAD_FUNC_ARG;
04582 
04583     /* If the ticket is NULL, the client will request a new ticket from the
04584        server. Otherwise, the client will use it in the next client hello. */
04585     if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap))
04586                                                                            != 0)
04587         return ret;
04588 
04589     return WOLFSSL_SUCCESS;
04590 }
04591 
04592 #define WOLF_STK_VALIDATE_REQUEST TLSX_SessionTicket_ValidateRequest
04593 #define WOLF_STK_GET_SIZE         TLSX_SessionTicket_GetSize
04594 #define WOLF_STK_WRITE            TLSX_SessionTicket_Write
04595 #define WOLF_STK_PARSE            TLSX_SessionTicket_Parse
04596 #define WOLF_STK_FREE(stk, heap)  TLSX_SessionTicket_Free((SessionTicket*)stk,(heap))
04597 
04598 #else
04599 
04600 #define WOLF_STK_FREE(a, b)
04601 #define WOLF_STK_VALIDATE_REQUEST(a)
04602 #define WOLF_STK_GET_SIZE(a, b)      0
04603 #define WOLF_STK_WRITE(a, b, c)      0
04604 #define WOLF_STK_PARSE(a, b, c, d)   0
04605 
04606 #endif /* HAVE_SESSION_TICKET */
04607 
04608 /******************************************************************************/
04609 /* Quantum-Safe-Hybrid                                                        */
04610 /******************************************************************************/
04611 
04612 #ifdef HAVE_QSH
04613 #if defined(HAVE_NTRU)
04614 static WC_RNG* gRng;
04615 static wolfSSL_Mutex* gRngMutex;
04616 #endif
04617 
04618 static void TLSX_QSH_FreeAll(QSHScheme* list, void* heap)
04619 {
04620     QSHScheme* current;
04621 
04622     while ((current = list)) {
04623         list = current->next;
04624         XFREE(current, heap, DYNAMIC_TYPE_TLSX);
04625     }
04626 
04627     (void)heap;
04628 }
04629 
04630 static int TLSX_QSH_Append(QSHScheme** list, word16 name, byte* pub,
04631                                                                   word16 pubLen)
04632 {
04633     QSHScheme* temp;
04634 
04635     if (list == NULL)
04636         return BAD_FUNC_ARG;
04637 
04638     if ((temp = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL,
04639                                                     DYNAMIC_TYPE_TLSX)) == NULL)
04640         return MEMORY_E;
04641 
04642     temp->name  = name;
04643     temp->PK    = pub;
04644     temp->PKLen = pubLen;
04645     temp->next  = *list;
04646 
04647     *list = temp;
04648 
04649     return 0;
04650 }
04651 
04652 
04653 /* request for server's public key : 02 indicates 0-2 requested */
04654 static byte TLSX_QSH_SerPKReq(byte* output, byte isRequest)
04655 {
04656     if (isRequest) {
04657         /* only request one public key from the server */
04658         output[0] = 0x01;
04659 
04660         return OPAQUE8_LEN;
04661     }
04662     else {
04663         return 0;
04664     }
04665 }
04666 
04667 #ifndef NO_WOLFSSL_CLIENT
04668 
04669 /* check for TLS_QSH suite */
04670 static void TLSX_QSH_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
04671 {
04672     int i;
04673 
04674     for (i = 0; i < ssl->suites->suiteSz; i+= 2)
04675         if (ssl->suites->suites[i] == QSH_BYTE)
04676             return;
04677 
04678     /* No QSH suite found */
04679     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_QUANTUM_SAFE_HYBRID));
04680 }
04681 
04682 
04683 /* return the size of the QSH hello extension
04684    list      the list of QSHScheme structs containing id and key
04685    isRequest if 1 then is being sent to the server
04686  */
04687 word16 TLSX_QSH_GetSize(QSHScheme* list, byte isRequest)
04688 {
04689     QSHScheme* temp = list;
04690     word16 length = 0;
04691 
04692     /* account for size of scheme list and public key list */
04693     if (isRequest)
04694         length = OPAQUE16_LEN;
04695     length += OPAQUE24_LEN;
04696 
04697     /* for each non null element in list add size */
04698     while ((temp)) {
04699         /* add public key info Scheme | Key Length | Key */
04700         length += OPAQUE16_LEN;
04701         length += OPAQUE16_LEN;
04702         length += temp->PKLen;
04703 
04704         /* if client add name size for scheme list
04705            advance to next QSHScheme struct in list */
04706         if (isRequest)
04707             length += OPAQUE16_LEN;
04708         temp = temp->next;
04709     }
04710 
04711     /* add length for request server public keys */
04712     if (isRequest)
04713         length += OPAQUE8_LEN;
04714 
04715     return length;
04716 }
04717 
04718 
04719 /* write out a list of QSHScheme IDs */
04720 static word16 TLSX_QSH_Write(QSHScheme* list, byte* output)
04721 {
04722     QSHScheme* current = list;
04723     word16 length      = 0;
04724 
04725     length += OPAQUE16_LEN;
04726 
04727     while (current) {
04728         c16toa(current->name, output + length);
04729         length += OPAQUE16_LEN;
04730         current = (QSHScheme*)current->next;
04731     }
04732 
04733     c16toa(length - OPAQUE16_LEN, output); /* writing list length */
04734 
04735     return length;
04736 }
04737 
04738 
04739 /* write public key list in extension */
04740 static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output);
04741 static word16 TLSX_QSHPK_WriteR(QSHScheme* format, byte* output)
04742 {
04743     word32 offset = 0;
04744     word16 public_len = 0;
04745 
04746     if (!format)
04747         return offset;
04748 
04749     /* write scheme ID */
04750     c16toa(format->name, output + offset);
04751     offset += OPAQUE16_LEN;
04752 
04753     /* write public key matching scheme */
04754     public_len = format->PKLen;
04755     c16toa(public_len, output + offset);
04756     offset += OPAQUE16_LEN;
04757     if (format->PK) {
04758         XMEMCPY(output+offset, format->PK, public_len);
04759     }
04760 
04761     return public_len + offset;
04762 }
04763 
04764 word16 TLSX_QSHPK_Write(QSHScheme* list, byte* output)
04765 {
04766     QSHScheme* current = list;
04767     word32 length = 0;
04768     word24 toWire;
04769 
04770     length += OPAQUE24_LEN;
04771 
04772     while (current) {
04773         length += TLSX_QSHPK_WriteR(current, output + length);
04774         current = (QSHScheme*)current->next;
04775     }
04776     /* length of public keys sent */
04777     c32to24(length - OPAQUE24_LEN, toWire);
04778     output[0] = toWire[0];
04779     output[1] = toWire[1];
04780     output[2] = toWire[2];
04781 
04782     return length;
04783 }
04784 
04785 #endif /* NO_WOLFSSL_CLIENT */
04786 #ifndef NO_WOLFSSL_SERVER
04787 
04788 static void TLSX_QSHAgreement(TLSX** extensions, void* heap)
04789 {
04790     TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
04791     QSHScheme* format = NULL;
04792     QSHScheme* del    = NULL;
04793     QSHScheme* prev   = NULL;
04794 
04795     if (extension == NULL)
04796         return;
04797 
04798     format = (QSHScheme*)extension->data;
04799     while (format) {
04800         if (format->PKLen == 0) {
04801             /* case of head */
04802             if (format == extension->data) {
04803                 extension->data = format->next;
04804             }
04805             if (prev)
04806                 prev->next = format->next;
04807             del = format;
04808             format = format->next;
04809             XFREE(del, heap, DYNAMIC_TYPE_TMP_BUFFER);
04810             del = NULL;
04811         } else {
04812             prev   = format;
04813             format = format->next;
04814         }
04815     }
04816 
04817     (void)heap;
04818 }
04819 
04820 
04821 /* Parse in hello extension
04822    input     the byte stream to process
04823    length    length of total extension found
04824    isRequest set to 1 if being sent to the server
04825  */
04826 static int TLSX_QSH_Parse(WOLFSSL* ssl, byte* input, word16 length,
04827                                                                  byte isRequest)
04828 {
04829     byte   numKeys    = 0;
04830     word16 offset     = 0;
04831     word16 schemSz    = 0;
04832     word16 offset_len = 0;
04833     word32 offset_pk  = 0;
04834     word16 name  = 0;
04835     word16 PKLen = 0;
04836     byte*  PK = NULL;
04837     int r;
04838 
04839 
04840     if (OPAQUE16_LEN > length)
04841         return BUFFER_ERROR;
04842 
04843     if (isRequest) {
04844         ato16(input, &schemSz);
04845 
04846         /* list of public keys available for QSH schemes */
04847         offset_len = schemSz + OPAQUE16_LEN;
04848     }
04849 
04850     offset_pk = ((input[offset_len] << 16)   & 0xFF00000) |
04851                 (((input[offset_len + 1]) << 8) & 0xFF00) |
04852                 (input[offset_len + 2] & 0xFF);
04853     offset_len += OPAQUE24_LEN;
04854 
04855     /* check buffer size */
04856     if (offset_pk > length)
04857         return BUFFER_ERROR;
04858 
04859     /* set maximum number of keys the client will accept */
04860     if (!isRequest)
04861         numKeys = (ssl->maxRequest < 1)? 1 : ssl->maxRequest;
04862 
04863     /* hello extension read list of scheme ids */
04864     if (isRequest) {
04865 
04866         /* read in request for public keys */
04867         ssl->minRequest = (input[length -1] >> 4) & 0xFF;
04868         ssl->maxRequest = input[length -1] & 0x0F;
04869 
04870         /* choose the min between min requested by client and 1 */
04871         numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
04872 
04873         if (ssl->minRequest > ssl->maxRequest)
04874             return BAD_FUNC_ARG;
04875 
04876         offset  += OPAQUE16_LEN;
04877         schemSz += offset;
04878 
04879         /* check buffer size */
04880         if (schemSz > length)
04881             return BUFFER_ERROR;
04882 
04883         while ((offset < schemSz) && numKeys) {
04884             /* Scheme ID list */
04885             ato16(input + offset, &name);
04886             offset += OPAQUE16_LEN;
04887 
04888             /* validate we have scheme id */
04889             if (ssl->user_set_QSHSchemes &&
04890                     !TLSX_ValidateQSHScheme(&ssl->extensions, name)) {
04891                 continue;
04892             }
04893 
04894             /* server create keys on demand */
04895             if ((r = TLSX_CreateNtruKey(ssl, name)) != 0) {
04896                 WOLFSSL_MSG("Error creating ntru keys");
04897                 return r;
04898             }
04899 
04900             /* peer sent an agreed upon scheme */
04901             r = TLSX_UseQSHScheme(&ssl->extensions, name, NULL, 0, ssl->heap);
04902 
04903             if (r != WOLFSSL_SUCCESS) return r; /* throw error */
04904 
04905             numKeys--;
04906         }
04907 
04908         /* choose the min between min requested by client and 1 */
04909         numKeys = (ssl->minRequest > 1) ? ssl->minRequest : 1;
04910     }
04911 
04912     /* QSHPK struct */
04913     offset_pk += offset_len;
04914     while ((offset_len < offset_pk) && numKeys) {
04915         QSHKey * temp;
04916 
04917         if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap,
04918                                                     DYNAMIC_TYPE_TLSX)) == NULL)
04919             return MEMORY_E;
04920 
04921         /* initialize */
04922         temp->next = NULL;
04923         temp->pub.buffer = NULL;
04924         temp->pub.length = 0;
04925         temp->pri.buffer = NULL;
04926         temp->pri.length = 0;
04927 
04928         /* scheme id */
04929         ato16(input + offset_len, &(temp->name));
04930         offset_len += OPAQUE16_LEN;
04931 
04932         /* public key length */
04933         ato16(input + offset_len, &PKLen);
04934         temp->pub.length = PKLen;
04935         offset_len += OPAQUE16_LEN;
04936 
04937 
04938         if (isRequest) {
04939             /* validate we have scheme id */
04940             if (ssl->user_set_QSHSchemes &&
04941                     (!TLSX_ValidateQSHScheme(&ssl->extensions, temp->name))) {
04942                 offset_len += PKLen;
04943                 XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX);
04944                 continue;
04945             }
04946         }
04947 
04948         /* read in public key */
04949         if (PKLen > 0) {
04950             temp->pub.buffer = (byte*)XMALLOC(temp->pub.length,
04951                                             ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
04952             XMEMCPY(temp->pub.buffer, input + offset_len, temp->pub.length);
04953             offset_len += PKLen;
04954         }
04955         else {
04956             PK = NULL;
04957         }
04958 
04959         /* use own key when adding to extensions list for sending reply */
04960         PKLen = 0;
04961         PK = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, &PKLen, temp->name);
04962         r  = TLSX_UseQSHScheme(&ssl->extensions, temp->name, PK, PKLen,
04963                                                                      ssl->heap);
04964 
04965         /* store peers key */
04966         ssl->peerQSHKeyPresent = 1;
04967         if (TLSX_AddQSHKey(&ssl->peerQSHKey, temp) != 0)
04968             return MEMORY_E;
04969 
04970         if (temp->pub.length == 0) {
04971             XFREE(temp, ssl->heap, DYNAMIC_TYPE_TLSX);
04972         }
04973 
04974         if (r != WOLFSSL_SUCCESS) {return r;} /* throw error */
04975 
04976         numKeys--;
04977     }
04978 
04979     /* reply to a QSH extension sent from client */
04980     if (isRequest) {
04981         TLSX_SetResponse(ssl, TLSX_QUANTUM_SAFE_HYBRID);
04982         /* only use schemes we have key generated for -- free the rest */
04983         TLSX_QSHAgreement(&ssl->extensions, ssl->heap);
04984     }
04985 
04986     return 0;
04987 }
04988 
04989 
04990 /* Used for parsing in QSHCipher structs on Key Exchange */
04991 int TLSX_QSHCipher_Parse(WOLFSSL* ssl, const byte* input, word16 length,
04992                                                                   byte isServer)
04993 {
04994     QSHKey* key;
04995     word16 Max_Secret_Len = 48;
04996     word16 offset     = 0;
04997     word16 offset_len = 0;
04998     word32 offset_pk  = 0;
04999     word16 name       = 0;
05000     word16 secretLen  = 0;
05001     byte*  secret     = NULL;
05002     word16 buffLen    = 0;
05003     byte buff[145]; /* size enough for 3 secrets */
05004     buffer* buf;
05005 
05006     /* pointer to location where secret should be stored */
05007     if (isServer) {
05008         buf = ssl->QSH_secret->CliSi;
05009     }
05010     else {
05011         buf = ssl->QSH_secret->SerSi;
05012     }
05013 
05014     offset_pk = ((input[offset_len] << 16)    & 0xFF0000) |
05015                 (((input[offset_len + 1]) << 8) & 0xFF00) |
05016                 (input[offset_len + 2] & 0xFF);
05017     offset_len += OPAQUE24_LEN;
05018 
05019     /* validating extension list length -- check if trying to read over edge
05020        of buffer */
05021     if (length < (offset_pk + OPAQUE24_LEN)) {
05022         return BUFFER_ERROR;
05023     }
05024 
05025     /* QSHCipherList struct */
05026     offset_pk += offset_len;
05027     while (offset_len < offset_pk) {
05028 
05029         /* scheme id */
05030         ato16(input + offset_len, &name);
05031         offset_len += OPAQUE16_LEN;
05032 
05033         /* public key length */
05034         ato16(input + offset_len, &secretLen);
05035         offset_len += OPAQUE16_LEN;
05036 
05037         /* read in public key */
05038         if (secretLen > 0) {
05039             secret = (byte*)(input + offset_len);
05040             offset_len += secretLen;
05041         }
05042         else {
05043             secret = NULL;
05044         }
05045 
05046         /* no secret sent */
05047         if (secret == NULL)
05048             continue;
05049 
05050         /* find corresponding key */
05051         key = ssl->QSH_Key;
05052         while (key) {
05053             if (key->name == name)
05054                 break;
05055             else
05056                 key = (QSHKey*)key->next;
05057         }
05058 
05059         /* if we do not have the key than there was a big issue negotiation */
05060         if (key == NULL) {
05061             WOLFSSL_MSG("key was null for decryption!!!\n");
05062             return MEMORY_E;
05063         }
05064 
05065         /* Decrypt sent secret */
05066         buffLen = Max_Secret_Len;
05067         QSH_Decrypt(key, secret, secretLen, buff + offset, &buffLen);
05068         offset += buffLen;
05069     }
05070 
05071     /* allocate memory for buffer */
05072     buf->length = offset;
05073     buf->buffer = (byte*)XMALLOC(offset, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05074     if (buf->buffer == NULL)
05075         return MEMORY_E;
05076 
05077     /* store secrets */
05078     XMEMCPY(buf->buffer, buff, offset);
05079     ForceZero(buff, offset);
05080 
05081     return offset_len;
05082 }
05083 
05084 
05085 /* return 1 on success */
05086 int TLSX_ValidateQSHScheme(TLSX** extensions, word16 theirs) {
05087     TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
05088     QSHScheme* format    = NULL;
05089 
05090     /* if no extension is sent then do not use QSH */
05091     if (!extension) {
05092         WOLFSSL_MSG("No QSH Extension");
05093         return 0;
05094     }
05095 
05096     for (format = (QSHScheme*)extension->data; format; format = format->next) {
05097         if (format->name == theirs) {
05098             WOLFSSL_MSG("Found Matching QSH Scheme");
05099             return 1; /* have QSH */
05100         }
05101     }
05102 
05103     return 0;
05104 }
05105 #endif /* NO_WOLFSSL_SERVER */
05106 
05107 /* test if the QSH Scheme is implemented
05108    return 1 if yes 0 if no */
05109 static int TLSX_HaveQSHScheme(word16 name)
05110 {
05111     switch(name) {
05112         #ifdef HAVE_NTRU
05113             case WOLFSSL_NTRU_EESS439:
05114             case WOLFSSL_NTRU_EESS593:
05115             case WOLFSSL_NTRU_EESS743:
05116                     return 1;
05117         #endif
05118             case WOLFSSL_LWE_XXX:
05119             case WOLFSSL_HFE_XXX:
05120                     return 0; /* not supported yet */
05121 
05122         default:
05123             return 0;
05124     }
05125 }
05126 
05127 
05128 /* Add a QSHScheme struct to list of usable ones */
05129 int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
05130                                                                      void* heap)
05131 {
05132     TLSX*      extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID);
05133     QSHScheme* format    = NULL;
05134     int        ret       = 0;
05135 
05136     /* sanity check */
05137     if (extensions == NULL || (pKey == NULL && pkeySz != 0))
05138         return BAD_FUNC_ARG;
05139 
05140     /* if scheme is implemented than add */
05141     if (TLSX_HaveQSHScheme(name)) {
05142         if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0)
05143             return ret;
05144 
05145         if (!extension) {
05146             if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format,
05147                                                                   heap)) != 0) {
05148                 XFREE(format, 0, DYNAMIC_TYPE_TLSX);
05149                 return ret;
05150             }
05151         }
05152         else {
05153             /* push new QSH object to extension data. */
05154             format->next = (QSHScheme*)extension->data;
05155             extension->data = (void*)format;
05156 
05157             /* look for another format of the same name to remove (replacement) */
05158             do {
05159                 if (format->next && (format->next->name == name)) {
05160                     QSHScheme* next = format->next;
05161 
05162                     format->next = next->next;
05163                     XFREE(next, 0, DYNAMIC_TYPE_TLSX);
05164 
05165                     break;
05166                 }
05167             } while ((format = format->next));
05168         }
05169     }
05170     return WOLFSSL_SUCCESS;
05171 }
05172 
05173 #define QSH_FREE_ALL         TLSX_QSH_FreeAll
05174 #define QSH_VALIDATE_REQUEST TLSX_QSH_ValidateRequest
05175 
05176 #ifndef NO_WOLFSSL_CLIENT
05177 #define QSH_GET_SIZE TLSX_QSH_GetSize
05178 #define QSH_WRITE    TLSX_QSH_Write
05179 #else
05180 #define QSH_GET_SIZE(list)         0
05181 #define QSH_WRITE(a, b)            0
05182 #endif
05183 
05184 #ifndef NO_WOLFSSL_SERVER
05185 #define QSH_PARSE TLSX_QSH_Parse
05186 #else
05187 #define QSH_PARSE(a, b, c, d)      0
05188 #endif
05189 
05190 #define QSHPK_WRITE TLSX_QSHPK_Write
05191 #define QSH_SERREQ TLSX_QSH_SerPKReq
05192 #else
05193 
05194 #define QSH_FREE_ALL(list, heap)
05195 #define QSH_GET_SIZE(list, a)      0
05196 #define QSH_WRITE(a, b)            0
05197 #define QSH_PARSE(a, b, c, d)      0
05198 #define QSHPK_WRITE(a, b)          0
05199 #define QSH_SERREQ(a, b)           0
05200 #define QSH_VALIDATE_REQUEST(a, b)
05201 
05202 #endif /* HAVE_QSH */
05203 
05204 /******************************************************************************/
05205 /* Supported Versions                                                         */
05206 /******************************************************************************/
05207 
05208 #ifdef WOLFSSL_TLS13
05209 /* Return the size of the SupportedVersions extension's data.
05210  *
05211  * data       The SSL/TLS object.
05212  * msgType The type of the message this extension is being written into.
05213  * returns the length of data that will be in the extension.
05214  */
05215 static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
05216 {
05217     WOLFSSL* ssl = (WOLFSSL*)data;
05218 
05219     if (msgType == client_hello) {
05220         /* TLS v1.2 and TLS v1.3  */
05221         int cnt = 2;
05222 
05223 #ifndef NO_OLD_TLS
05224         /* TLS v1.1  */
05225         cnt++;
05226     #ifdef WOLFSSL_ALLOW_TLSV10
05227         /* TLS v1.0  */
05228         cnt++;
05229     #endif
05230 #endif
05231 
05232         if (!ssl->options.downgrade)
05233             cnt = 1;
05234 
05235         *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
05236     }
05237 #ifndef WOLFSSL_TLS13_DRAFT_18
05238     else if (msgType == server_hello || msgType == hello_retry_request)
05239         *pSz += OPAQUE16_LEN;
05240 #endif
05241     else
05242         return SANITY_MSG_E;
05243 
05244     return 0;
05245 }
05246 
05247 /* Writes the SupportedVersions extension into the buffer.
05248  *
05249  * data    The SSL/TLS object.
05250  * output  The buffer to write the extension into.
05251  * msgType The type of the message this extension is being written into.
05252  * returns the length of data that was written.
05253  */
05254 static int TLSX_SupportedVersions_Write(void* data, byte* output,
05255                                            byte msgType, word16* pSz)
05256 {
05257     WOLFSSL* ssl = (WOLFSSL*)data;
05258     ProtocolVersion pv;
05259     int i;
05260     int cnt;
05261 
05262     if (msgType == client_hello) {
05263         pv = ssl->ctx->method->version;
05264         /* TLS v1.2 and TLS v1.3  */
05265         cnt = 2;
05266 
05267 #ifndef NO_OLD_TLS
05268         /* TLS v1.1  */
05269         cnt++;
05270     #ifdef WOLFSSL_ALLOW_TLSV10
05271         /* TLS v1.0  */
05272         cnt++;
05273     #endif
05274 #endif
05275 
05276         if (!ssl->options.downgrade)
05277             cnt = 1;
05278 
05279         *(output++) = (byte)(cnt * OPAQUE16_LEN);
05280         for (i = 0; i < cnt; i++) {
05281 #ifndef WOLFSSL_TLS13_FINAL
05282             /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
05283             if (pv.minor - i == TLSv1_3_MINOR) {
05284                 /* The TLS draft major number. */
05285                 *(output++) = TLS_DRAFT_MAJOR;
05286                 /* Version of draft supported. */
05287                 *(output++) = TLS_DRAFT_MINOR;
05288                 continue;
05289             }
05290 #endif
05291 
05292             *(output++) = pv.major;
05293             *(output++) = (byte)(pv.minor - i);
05294         }
05295 
05296         *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
05297     }
05298 #ifndef WOLFSSL_TLS13_DRAFT_18
05299     else if (msgType == server_hello || msgType == hello_retry_request) {
05300     #ifndef WOLFSSL_TLS13_FINAL
05301         if (ssl->version.major == SSLv3_MAJOR &&
05302                                           ssl->version.minor == TLSv1_3_MINOR) {
05303             output[0] = TLS_DRAFT_MAJOR;
05304             output[1] = TLS_DRAFT_MINOR;
05305         }
05306         else
05307     #endif
05308         {
05309             output[0] = ssl->version.major;
05310             output[1] = ssl->version.minor;
05311         }
05312 
05313         *pSz += OPAQUE16_LEN;
05314     }
05315 #endif
05316     else
05317         return SANITY_MSG_E;
05318 
05319     return 0;
05320 }
05321 
05322 /* Parse the SupportedVersions extension.
05323  *
05324  * ssl     The SSL/TLS object.
05325  * input   The buffer with the extension data.
05326  * length  The length of the extension data.
05327  * msgType The type of the message this extension is being parsed from.
05328  * returns 0 on success, otherwise failure.
05329  */
05330 static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, byte* input,
05331                                         word16 length, byte msgType)
05332 {
05333     ProtocolVersion pv = ssl->ctx->method->version;
05334     int i;
05335     int len;
05336     byte major, minor;
05337     int newMinor = 0;
05338 
05339     if (msgType == client_hello) {
05340         /* Must contain a length and at least one version. */
05341         if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1)
05342             return BUFFER_ERROR;
05343 
05344         len = *input;
05345 
05346         /* Protocol version array must fill rest of data. */
05347         if (length != OPAQUE8_LEN + len)
05348             return BUFFER_ERROR;
05349 
05350         input++;
05351 
05352         /* Find first match. */
05353         for (i = 0; i < len; i += OPAQUE16_LEN) {
05354             major = input[i];
05355             minor = input[i + OPAQUE8_LEN];
05356 
05357 #ifndef WOLFSSL_TLS13_FINAL
05358             /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
05359             if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
05360                 major = SSLv3_MAJOR;
05361                 minor = TLSv1_3_MINOR;
05362             }
05363 #endif
05364 
05365             if (major != pv.major)
05366                 continue;
05367 
05368             /* No upgrade allowed. */
05369             if (minor > ssl->version.minor)
05370                     continue;
05371             /* Check downgrade. */
05372             if (minor < ssl->version.minor) {
05373                 if (!ssl->options.downgrade)
05374                     continue;
05375 
05376                 if (minor < ssl->options.minDowngrade)
05377                     continue;
05378 
05379                 if (newMinor == 0 && minor > ssl->options.oldMinor) {
05380                     /* Downgrade the version. */
05381                     ssl->version.minor = minor;
05382                 }
05383             }
05384 
05385             if (minor >= TLSv1_3_MINOR) {
05386                 if (!ssl->options.tls1_3) {
05387                     ssl->options.tls1_3 = 1;
05388                     TLSX_Push(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl,
05389                               ssl->heap);
05390 #ifndef WOLFSSL_TLS13_DRAFT_18
05391                     TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
05392 #endif
05393                 }
05394                 if (minor > newMinor) {
05395                     ssl->version.minor = minor;
05396                     newMinor = minor;
05397                 }
05398             }
05399             else if (minor > ssl->options.oldMinor)
05400                 ssl->options.oldMinor = minor;
05401         }
05402     }
05403 #ifndef WOLFSSL_TLS13_DRAFT_18
05404     else if (msgType == server_hello || msgType == hello_retry_request) {
05405         /* Must contain one version. */
05406         if (length != OPAQUE16_LEN)
05407             return BUFFER_ERROR;
05408 
05409         major = input[0];
05410         minor = input[OPAQUE8_LEN];
05411 
05412     #ifndef WOLFSSL_TLS13_FINAL
05413         /* TODO: [TLS13] Remove code when TLS v1.3 becomes an RFC. */
05414         if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
05415             major = SSLv3_MAJOR;
05416             minor = TLSv1_3_MINOR;
05417         }
05418     #endif
05419 
05420         if (major != pv.major)
05421             return VERSION_ERROR;
05422 
05423         /* Can't downgrade with this extension below TLS v1.3. */
05424         if (minor < TLSv1_3_MINOR)
05425             return VERSION_ERROR;
05426 
05427         /* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
05428         if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR) {
05429             /* Set minor version back to TLS v1.3+ */
05430             ssl->version.minor = ssl->ctx->method->version.minor;
05431         }
05432 
05433         /* No upgrade allowed. */
05434         if (ssl->version.minor < minor)
05435             return VERSION_ERROR;
05436 
05437         /* Check downgrade. */
05438         if (ssl->version.minor > minor) {
05439             if (!ssl->options.downgrade)
05440                 return VERSION_ERROR;
05441 
05442             if (minor < ssl->options.minDowngrade)
05443                 return VERSION_ERROR;
05444 
05445             /* Downgrade the version. */
05446             ssl->version.minor = minor;
05447         }
05448     }
05449 #endif
05450     else
05451         return SANITY_MSG_E;
05452 
05453     return 0;
05454 }
05455 
05456 /* Sets a new SupportedVersions extension into the extension list.
05457  *
05458  * extensions  The list of extensions.
05459  * data        The extensions specific data.
05460  * heap        The heap used for allocation.
05461  * returns 0 on success, otherwise failure.
05462  */
05463 static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
05464                                      void* heap)
05465 {
05466     if (extensions == NULL || data == NULL)
05467         return BAD_FUNC_ARG;
05468 
05469     return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, (void *)data, heap);
05470 }
05471 
05472 #define SV_GET_SIZE  TLSX_SupportedVersions_GetSize
05473 #define SV_WRITE     TLSX_SupportedVersions_Write
05474 #define SV_PARSE     TLSX_SupportedVersions_Parse
05475 
05476 #else
05477 
05478 #define SV_GET_SIZE(a, b, c) 0
05479 #define SV_WRITE(a, b, c, d) 0
05480 #define SV_PARSE(a, b, c, d) 0
05481 
05482 #endif /* WOLFSSL_TLS13 */
05483 
05484 #if defined(WOLFSSL_TLS13)
05485 
05486 /******************************************************************************/
05487 /* Cookie                                                                     */
05488 /******************************************************************************/
05489 
05490 /* Free the cookie data.
05491  *
05492  * cookie  Cookie data.
05493  * heap    The heap used for allocation.
05494  */
05495 static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap)
05496 {
05497     (void)heap;
05498 
05499     if (cookie != NULL)
05500         XFREE(cookie, heap, DYNAMIC_TYPE_TLSX);
05501 }
05502 
05503 /* Get the size of the encoded Cookie extension.
05504  * In messages: ClientHello and HelloRetryRequest.
05505  *
05506  * cookie   The cookie to write.
05507  * msgType  The type of the message this extension is being written into.
05508  * returns the number of bytes of the encoded Cookie extension.
05509  */
05510 static int TLSX_Cookie_GetSize(Cookie* cookie, byte msgType, word16* pSz)
05511 {
05512     if (msgType == client_hello || msgType == hello_retry_request)
05513         *pSz += OPAQUE16_LEN + cookie->len;
05514     else
05515         return SANITY_MSG_E;
05516     return 0;
05517 }
05518 
05519 /* Writes the Cookie extension into the output buffer.
05520  * Assumes that the the output buffer is big enough to hold data.
05521  * In messages: ClientHello and HelloRetryRequest.
05522  *
05523  * cookie   The cookie to write.
05524  * output   The buffer to write into.
05525  * msgType  The type of the message this extension is being written into.
05526  * returns the number of bytes written into the buffer.
05527  */
05528 static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType, word16* pSz)
05529 {
05530     if (msgType == client_hello || msgType == hello_retry_request) {
05531         c16toa(cookie->len, output);
05532         output += OPAQUE16_LEN;
05533         XMEMCPY(output, &cookie->data, cookie->len);
05534         *pSz += OPAQUE16_LEN + cookie->len;
05535     }
05536     else
05537         return SANITY_MSG_E;
05538     return 0;
05539 }
05540 
05541 /* Parse the Cookie extension.
05542  * In messages: ClientHello and HelloRetryRequest.
05543  *
05544  * ssl      The SSL/TLS object.
05545  * input    The extension data.
05546  * length   The length of the extension data.
05547  * msgType  The type of the message this extension is being parsed from.
05548  * returns 0 on success and other values indicate failure.
05549  */
05550 static int TLSX_Cookie_Parse(WOLFSSL* ssl, byte* input, word16 length,
05551                                  byte msgType)
05552 {
05553     word16  len;
05554     word16  idx = 0;
05555     TLSX*   extension;
05556     Cookie* cookie;
05557 
05558     if (msgType != client_hello && msgType != hello_retry_request)
05559         return SANITY_MSG_E;
05560 
05561     /* Message contains length and Cookie which must be at least one byte
05562      * in length.
05563      */
05564     if (length < OPAQUE16_LEN + 1)
05565         return BUFFER_E;
05566     ato16(input + idx, &len);
05567     idx += OPAQUE16_LEN;
05568     if (length - idx != len)
05569         return BUFFER_E;
05570 
05571     if (msgType == hello_retry_request)
05572         return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0);
05573 
05574     /* client_hello */
05575     extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
05576     if (extension == NULL)
05577         return HRR_COOKIE_ERROR;
05578 
05579     cookie = (Cookie*)extension->data;
05580     if (cookie->len != len || XMEMCMP(&cookie->data, input + idx, len) != 0)
05581         return HRR_COOKIE_ERROR;
05582 
05583     /* Request seen. */
05584     extension->resp = 0;
05585 
05586     return 0;
05587 }
05588 
05589 /* Use the data to create a new Cookie object in the extensions.
05590  *
05591  * ssl    SSL/TLS object.
05592  * data   Cookie data.
05593  * len    Length of cookie data in bytes.
05594  * mac    MAC data.
05595  * macSz  Length of MAC data in bytes.
05596  * resp   Indicates the extension will go into a response (HelloRetryRequest).
05597  * returns 0 on success and other values indicate failure.
05598  */
05599 int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac,
05600                     byte macSz, int resp)
05601 {
05602     int     ret = 0;
05603     TLSX*   extension;
05604     Cookie* cookie;
05605 
05606     /* Find the cookie extension if it exists. */
05607     extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
05608     if (extension == NULL) {
05609         /* Push new cookie extension. */
05610         ret = TLSX_Push(&ssl->extensions, TLSX_COOKIE, NULL, ssl->heap);
05611         if (ret != 0)
05612             return ret;
05613 
05614         extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
05615         if (extension == NULL)
05616             return MEMORY_E;
05617     }
05618 
05619     /* The Cookie structure has one byte for cookie data already. */
05620     cookie = (Cookie*)XMALLOC(sizeof(Cookie) + len + macSz - 1, ssl->heap,
05621                               DYNAMIC_TYPE_TLSX);
05622     if (cookie == NULL)
05623         return MEMORY_E;
05624 
05625     cookie->len = len + macSz;
05626     XMEMCPY(&cookie->data, data, len);
05627     if (mac != NULL)
05628         XMEMCPY(&cookie->data + len, mac, macSz);
05629 
05630     extension->data = (void*)cookie;
05631     extension->resp = (byte)resp;
05632 
05633     return 0;
05634 }
05635 
05636 #define CKE_FREE_ALL  TLSX_Cookie_FreeAll
05637 #define CKE_GET_SIZE  TLSX_Cookie_GetSize
05638 #define CKE_WRITE     TLSX_Cookie_Write
05639 #define CKE_PARSE     TLSX_Cookie_Parse
05640 
05641 #else
05642 
05643 #define CKE_FREE_ALL(a, b)    0
05644 #define CKE_GET_SIZE(a, b, c) 0
05645 #define CKE_WRITE(a, b, c, d) 0
05646 #define CKE_PARSE(a, b, c, d) 0
05647 
05648 #endif
05649 
05650 /******************************************************************************/
05651 /* Signature Algorithms                                                       */
05652 /******************************************************************************/
05653 
05654 /* Return the size of the SignatureAlgorithms extension's data.
05655  *
05656  * data  Unused
05657  * returns the length of data that will be in the extension.
05658  */
05659 static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
05660 {
05661     WOLFSSL* ssl = (WOLFSSL*)data;
05662 
05663     return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
05664 }
05665 
05666 /* Creates a bit string of supported hash algorithms with RSA PSS.
05667  * The bit string is used when determining which signature algorithm to use
05668  * when creating the CertificateVerify message.
05669  * Note: Valid data has an even length as each signature algorithm is two bytes.
05670  *
05671  * ssl     The SSL/TLS object.
05672  * input   The buffer with the list of supported signature algorithms.
05673  * length  The length of the list in bytes.
05674  * returns 0 on success, BUFFER_ERROR when the length is not even.
05675  */
05676 static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, byte* input,
05677                                                                   word16 length)
05678 {
05679     word16 i;
05680 
05681     if ((length & 1) == 1)
05682         return BUFFER_ERROR;
05683 
05684     ssl->pssAlgo = 0;
05685     for (i = 0; i < length; i += 2) {
05686         if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac)
05687             ssl->pssAlgo |= 1 << input[i + 1];
05688     }
05689 
05690     return 0;
05691 }
05692 
05693 /* Writes the SignatureAlgorithms extension into the buffer.
05694  *
05695  * data    Unused
05696  * output  The buffer to write the extension into.
05697  * returns the length of data that was written.
05698  */
05699 static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output)
05700 {
05701     WOLFSSL* ssl = (WOLFSSL*)data;
05702 
05703     c16toa(ssl->suites->hashSigAlgoSz, output);
05704     XMEMCPY(output + OPAQUE16_LEN, ssl->suites->hashSigAlgo,
05705             ssl->suites->hashSigAlgoSz);
05706 
05707     TLSX_SignatureAlgorithms_MapPss(ssl, output + OPAQUE16_LEN,
05708                                     ssl->suites->hashSigAlgoSz);
05709 
05710     return OPAQUE16_LEN + ssl->suites->hashSigAlgoSz;
05711 }
05712 
05713 /* Parse the SignatureAlgorithms extension.
05714  *
05715  * ssl     The SSL/TLS object.
05716  * input   The buffer with the extension data.
05717  * length  The length of the extension data.
05718  * returns 0 on success, otherwise failure.
05719  */
05720 static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, byte* input,
05721                                   word16 length, byte isRequest, Suites* suites)
05722 {
05723     word16 len;
05724 
05725     if (!isRequest)
05726         return BUFFER_ERROR;
05727 
05728     /* Must contain a length and at least algorithm. */
05729     if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
05730         return BUFFER_ERROR;
05731 
05732     ato16(input, &len);
05733     input += OPAQUE16_LEN;
05734 
05735     /* Algorithm array must fill rest of data. */
05736     if (length != OPAQUE16_LEN + len)
05737         return BUFFER_ERROR;
05738 
05739     /* truncate hashSigAlgo list if too long */
05740     suites->hashSigAlgoSz = len;
05741     if (suites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
05742         WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
05743         suites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
05744     }
05745     XMEMCPY(suites->hashSigAlgo, input, suites->hashSigAlgoSz);
05746 
05747     return TLSX_SignatureAlgorithms_MapPss(ssl, input, len);
05748 }
05749 
05750 /* Sets a new SignatureAlgorithms extension into the extension list.
05751  *
05752  * extensions  The list of extensions.
05753  * data        The extensions specific data.
05754  * heap        The heap used for allocation.
05755  * returns 0 on success, otherwise failure.
05756  */
05757 static int TLSX_SetSignatureAlgorithms(TLSX** extensions, const void* data,
05758                                        void* heap)
05759 {
05760     if (extensions == NULL)
05761         return BAD_FUNC_ARG;
05762 
05763     return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, (void *)data, heap);
05764 }
05765 
05766 #define SA_GET_SIZE  TLSX_SignatureAlgorithms_GetSize
05767 #define SA_WRITE     TLSX_SignatureAlgorithms_Write
05768 #define SA_PARSE     TLSX_SignatureAlgorithms_Parse
05769 
05770 /******************************************************************************/
05771 /* Signature Algorithms Certificate                                           */
05772 /******************************************************************************/
05773 
05774 #ifdef WOLFSSL_TLS13
05775 #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
05776 /* Return the size of the SignatureAlgorithms extension's data.
05777  *
05778  * data  Unused
05779  * returns the length of data that will be in the extension.
05780  */
05781 static word16 TLSX_SignatureAlgorithmsCert_GetSize(void* data)
05782 {
05783     WOLFSSL* ssl = (WOLFSSL*)data;
05784 
05785     return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
05786 }
05787 
05788 /* Writes the SignatureAlgorithmsCert extension into the buffer.
05789  *
05790  * data    Unused
05791  * output  The buffer to write the extension into.
05792  * returns the length of data that was written.
05793  */
05794 static word16 TLSX_SignatureAlgorithmsCert_Write(void* data, byte* output)
05795 {
05796     WOLFSSL* ssl = (WOLFSSL*)data;
05797 
05798     c16toa(ssl->certHashSigAlgoSz, output);
05799     XMEMCPY(output + OPAQUE16_LEN, ssl->certHashSigAlgo,
05800             ssl->certHashSigAlgoSz);
05801 
05802     return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
05803 }
05804 
05805 /* Parse the SignatureAlgorithmsCert extension.
05806  *
05807  * ssl     The SSL/TLS object.
05808  * input   The buffer with the extension data.
05809  * length  The length of the extension data.
05810  * returns 0 on success, otherwise failure.
05811  */
05812 static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, byte* input,
05813                                               word16 length, byte isRequest)
05814 {
05815     word16 len;
05816 
05817     if (!isRequest)
05818         return BUFFER_ERROR;
05819 
05820     /* Must contain a length and at least algorithm. */
05821     if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
05822         return BUFFER_ERROR;
05823 
05824     ato16(input, &len);
05825     input += OPAQUE16_LEN;
05826 
05827     /* Algorithm array must fill rest of data. */
05828     if (length != OPAQUE16_LEN + len)
05829         return BUFFER_ERROR;
05830 
05831     /* truncate hashSigAlgo list if too long */
05832     ssl->certHashSigAlgoSz = len;
05833     if (ssl->certHashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
05834         WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
05835         ssl->certHashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
05836     }
05837     XMEMCPY(ssl->certHashSigAlgo, input, ssl->certHashSigAlgoSz);
05838 
05839     return 0;
05840 }
05841 
05842 /* Sets a new SignatureAlgorithmsCert extension into the extension list.
05843  *
05844  * extensions  The list of extensions.
05845  * data        The extensions specific data.
05846  * heap        The heap used for allocation.
05847  * returns 0 on success, otherwise failure.
05848  */
05849 static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data,
05850                                                                      void* heap)
05851 {
05852     if (extensions == NULL)
05853         return BAD_FUNC_ARG;
05854 
05855     return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, (void *)data,
05856                                                                           heap);
05857 }
05858 
05859 #define SAC_GET_SIZE  TLSX_SignatureAlgorithmsCert_GetSize
05860 #define SAC_WRITE     TLSX_SignatureAlgorithmsCert_Write
05861 #define SAC_PARSE     TLSX_SignatureAlgorithmsCert_Parse
05862 #endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
05863 #endif /* WOLFSSL_TLS13 */
05864 
05865 
05866 /******************************************************************************/
05867 /* Key Share                                                                  */
05868 /******************************************************************************/
05869 
05870 #ifdef WOLFSSL_TLS13
05871 /* Create a key share entry using named Diffie-Hellman parameters group.
05872  * Generates a key pair.
05873  *
05874  * ssl   The SSL/TLS object.
05875  * kse   The key share entry object.
05876  * returns 0 on success, otherwise failure.
05877  */
05878  DhParams* wc_Dh_ffdhe2048_Get()
05879 {
05880     return NULL;
05881 }
05882 
05883 static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
05884 {
05885     int             ret;
05886 #ifndef NO_DH
05887     byte*           keyData;
05888     void*           key = NULL;
05889     word32          keySz;
05890     word32          dataSz;
05891     const DhParams* params;
05892 #ifdef WOLFSSL_SMALL_STACK
05893     DhKey*          dhKey = NULL;
05894 #else
05895     DhKey           dhKey[1];
05896 #endif
05897 
05898     /* TODO: [TLS13] The key size should come from wolfcrypt. */
05899     /* Pick the parameters from the named group. */
05900     switch (kse->group) {
05901     #ifdef HAVE_FFDHE_2048
05902         case WOLFSSL_FFDHE_2048:
05903             params = wc_Dh_ffdhe2048_Get();
05904             keySz = 29;
05905             break;
05906     #endif
05907     #ifdef HAVE_FFDHE_3072
05908         case WOLFSSL_FFDHE_3072:
05909             params = wc_Dh_ffdhe3072_Get();
05910             keySz = 34;
05911             break;
05912     #endif
05913     #ifdef HAVE_FFDHE_4096
05914         case WOLFSSL_FFDHE_4096:
05915             params = wc_Dh_ffdhe4096_Get();
05916             keySz = 39;
05917             break;
05918     #endif
05919     #ifdef HAVE_FFDHE_6144
05920         case WOLFSSL_FFDHE_6144:
05921             params = wc_Dh_ffdhe6144_Get();
05922             keySz = 46;
05923             break;
05924     #endif
05925     #ifdef HAVE_FFDHE_8192
05926         case WOLFSSL_FFDHE_8192:
05927             params = wc_Dh_ffdhe8192_Get();
05928             keySz = 52;
05929             break;
05930     #endif
05931         default:
05932             return BAD_FUNC_ARG;
05933     }
05934 
05935 #ifdef WOLFSSL_SMALL_STACK
05936     dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH);
05937     if (dhKey == NULL)
05938         return MEMORY_E;
05939 #endif
05940 
05941     ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId);
05942     if (ret != 0) {
05943     #ifdef WOLFSSL_SMALL_STACK
05944         XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
05945     #endif
05946         return ret;
05947     }
05948 
05949     /* Allocate space for the public key. */
05950     dataSz = params->p_len;
05951     keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
05952     if (keyData == NULL) {
05953         ret = MEMORY_E;
05954         goto end;
05955     }
05956     /* Allocate space for the private key. */
05957     key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
05958     if (key == NULL) {
05959         ret = MEMORY_E;
05960         goto end;
05961     }
05962 
05963     /* Set key */
05964     ret = wc_DhSetKey(dhKey,
05965         (byte*)params->p, params->p_len,
05966         (byte*)params->g, params->g_len);
05967     if (ret != 0)
05968         goto end;
05969 
05970     /* Generate a new key pair. */
05971     ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, (byte*)key, &keySz, keyData,
05972                                &dataSz);
05973 #ifdef WOLFSSL_ASYNC_CRYPT
05974     /* TODO: Make this function non-blocking */
05975     if (ret == WC_PENDING_E) {
05976         ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
05977     }
05978 #endif
05979     if (ret != 0)
05980         goto end;
05981 
05982     if (params->p_len != dataSz) {
05983         /* Pad the front of the key data with zeros. */
05984         XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz);
05985         XMEMSET(keyData, 0, params->p_len - dataSz);
05986     }
05987 
05988     kse->pubKey = keyData;
05989     kse->pubKeyLen = params->p_len;
05990     kse->key = key;
05991     kse->keyLen = keySz;
05992 
05993 #ifdef WOLFSSL_DEBUG_TLS
05994     WOLFSSL_MSG("Public DH Key");
05995     WOLFSSL_BUFFER(keyData, params->p_len);
05996 #endif
05997 
05998 end:
05999 
06000     wc_FreeDhKey(dhKey);
06001 #ifdef WOLFSSL_SMALL_STACK
06002     XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
06003 #endif
06004 
06005     if (ret != 0) {
06006         /* Data owned by key share entry otherwise. */
06007         if (keyData != NULL)
06008             XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06009         if (key != NULL)
06010             XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
06011     }
06012 #else
06013     (void)ssl;
06014     (void)kse;
06015 
06016     ret = NOT_COMPILED_IN;
06017 #endif
06018 
06019     return ret;
06020 }
06021 
06022 /* Create a key share entry using X25519 parameters group.
06023  * Generates a key pair.
06024  *
06025  * ssl   The SSL/TLS object.
06026  * kse   The key share entry object.
06027  * returns 0 on success, otherwise failure.
06028  */
06029 static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
06030 {
06031     int             ret;
06032 #ifdef HAVE_CURVE25519
06033     byte*           keyData = NULL;
06034     word32          dataSize = CURVE25519_KEYSIZE;
06035     curve25519_key* key;
06036 
06037     /* Allocate an ECC key to hold private key. */
06038     key = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
06039                                            ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
06040     if (key == NULL) {
06041         WOLFSSL_MSG("EccTempKey Memory error");
06042         return MEMORY_E;
06043     }
06044 
06045     /* Make an ECC key. */
06046     ret = wc_curve25519_init(key);
06047     if (ret != 0)
06048         goto end;
06049     ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
06050     if (ret != 0)
06051         goto end;
06052 
06053     /* Allocate space for the public key. */
06054     keyData = (byte*)XMALLOC(CURVE25519_KEYSIZE, ssl->heap,
06055                                                        DYNAMIC_TYPE_PUBLIC_KEY);
06056     if (keyData == NULL) {
06057         WOLFSSL_MSG("Key data Memory error");
06058         ret = MEMORY_E;
06059         goto end;
06060     }
06061 
06062     /* Export public key. */
06063     if (wc_curve25519_export_public_ex(key, keyData, &dataSize,
06064                                                   EC25519_LITTLE_ENDIAN) != 0) {
06065         ret = ECC_EXPORT_ERROR;
06066         goto end;
06067     }
06068 
06069     kse->pubKey = keyData;
06070     kse->pubKeyLen = CURVE25519_KEYSIZE;
06071     kse->key = key;
06072 
06073 #ifdef WOLFSSL_DEBUG_TLS
06074     WOLFSSL_MSG("Public Curve25519 Key");
06075     WOLFSSL_BUFFER(keyData, dataSize);
06076 #endif
06077 
06078 end:
06079     if (ret != 0) {
06080         /* Data owned by key share entry otherwise. */
06081         if (keyData != NULL)
06082             XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06083         wc_curve25519_free(key);
06084         XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
06085     }
06086 #else
06087     (void)ssl;
06088     (void)kse;
06089 
06090     ret = NOT_COMPILED_IN;
06091 #endif /* HAVE_CURVE25519 */
06092 
06093     return ret;
06094 }
06095 
06096 /* Create a key share entry using named elliptic curve parameters group.
06097  * Generates a key pair.
06098  *
06099  * ssl   The SSL/TLS object.
06100  * kse   The key share entry object.
06101  * returns 0 on success, otherwise failure.
06102  */
06103 static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
06104 {
06105     int      ret;
06106 #ifdef HAVE_ECC
06107     byte*    keyData = NULL;
06108     word32   dataSize;
06109     byte*    keyPtr = NULL;
06110     word32   keySize;
06111     ecc_key* eccKey;
06112     word16   curveId;
06113 
06114     /* TODO: [TLS13] The key sizes should come from wolfcrypt. */
06115     /* Translate named group to a curve id. */
06116     switch (kse->group) {
06117     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
06118         #ifndef NO_ECC_SECP
06119         case WOLFSSL_ECC_SECP256R1:
06120             curveId = ECC_SECP256R1;
06121             keySize = 32;
06122             dataSize = keySize * 2 + 1;
06123             break;
06124         #endif /* !NO_ECC_SECP */
06125     #endif
06126     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
06127         #ifndef NO_ECC_SECP
06128         case WOLFSSL_ECC_SECP384R1:
06129             curveId = ECC_SECP384R1;
06130             keySize = 48;
06131             dataSize = keySize * 2 + 1;
06132             break;
06133         #endif /* !NO_ECC_SECP */
06134     #endif
06135     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
06136         #ifndef NO_ECC_SECP
06137         case WOLFSSL_ECC_SECP521R1:
06138             curveId = ECC_SECP521R1;
06139             keySize = 66;
06140             dataSize = keySize * 2 + 1;
06141             break;
06142         #endif /* !NO_ECC_SECP */
06143     #endif
06144     #ifdef HAVE_X448
06145         case WOLFSSL_ECC_X448:
06146             curveId = ECC_X448;
06147             dataSize = keySize = 56;
06148             break;
06149     #endif
06150         default:
06151             return BAD_FUNC_ARG;
06152     }
06153 
06154     /* Allocate an ECC key to hold private key. */
06155     keyPtr = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap,
06156                                                       DYNAMIC_TYPE_PRIVATE_KEY);
06157     if (keyPtr == NULL) {
06158         WOLFSSL_MSG("EccTempKey Memory error");
06159         return MEMORY_E;
06160     }
06161     eccKey = (ecc_key*)keyPtr;
06162 
06163     /* Make an ECC key. */
06164     ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId);
06165     if (ret != 0)
06166         goto end;
06167     ret = wc_ecc_make_key_ex(ssl->rng, keySize, eccKey, curveId);
06168 #ifdef WOLFSSL_ASYNC_CRYPT
06169     /* TODO: Make this function non-blocking */
06170     if (ret == WC_PENDING_E) {
06171         ret = wc_AsyncWait(ret, &eccKey->asyncDev, WC_ASYNC_FLAG_NONE);
06172     }
06173 #endif
06174     if (ret != 0)
06175         goto end;
06176 
06177     /* Allocate space for the public key. */
06178     keyData = (byte*)XMALLOC(dataSize, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06179     if (keyData == NULL) {
06180         WOLFSSL_MSG("Key data Memory error");
06181         ret = MEMORY_E;
06182         goto end;
06183     }
06184 
06185     /* Export public key. */
06186     if (wc_ecc_export_x963(eccKey, keyData, &dataSize) != 0) {
06187         ret = ECC_EXPORT_ERROR;
06188         goto end;
06189     }
06190 
06191     kse->pubKey = keyData;
06192     kse->pubKeyLen = dataSize;
06193     kse->key = keyPtr;
06194 
06195 #ifdef WOLFSSL_DEBUG_TLS
06196     WOLFSSL_MSG("Public ECC Key");
06197     WOLFSSL_BUFFER(keyData, dataSize);
06198 #endif
06199 
06200 end:
06201     if (ret != 0) {
06202         /* Data owned by key share entry otherwise. */
06203         if (keyPtr != NULL)
06204             XFREE(keyPtr, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
06205         if (keyData != NULL)
06206             XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06207     }
06208 #else
06209     (void)ssl;
06210     (void)kse;
06211 
06212     ret = NOT_COMPILED_IN;
06213 #endif /* HAVE_ECC */
06214 
06215     return ret;
06216 }
06217 
06218 /* Generate a secret/key using the key share entry.
06219  *
06220  * ssl  The SSL/TLS object.
06221  * kse  The key share entry holding peer data.
06222  */
06223 static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
06224 {
06225     /* Named FFHE groups have a bit set to identify them. */
06226     if ((kse->group & NAMED_DH_MASK) == NAMED_DH_MASK)
06227         return TLSX_KeyShare_GenDhKey(ssl, kse);
06228     if (kse->group == WOLFSSL_ECC_X25519)
06229         return TLSX_KeyShare_GenX25519Key(ssl, kse);
06230     return TLSX_KeyShare_GenEccKey(ssl, kse);
06231 }
06232 
06233 /* Free the key share dynamic data.
06234  *
06235  * list  The linked list of key share entry objects.
06236  * heap  The heap used for allocation.
06237  */
06238 static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
06239 {
06240     KeyShareEntry* current;
06241 
06242     while ((current = list) != NULL) {
06243         list = current->next;
06244         if ((current->group & NAMED_DH_MASK) == 0) {
06245             if (current->group == WOLFSSL_ECC_X25519) {
06246 #ifdef HAVE_CURVE25519
06247                 wc_curve25519_free((curve25519_key*)current->key);
06248 #endif
06249             }
06250             else {
06251 #ifdef HAVE_ECC
06252                 wc_ecc_free((ecc_key*)(current->key));
06253 #endif
06254             }
06255         }
06256         XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY);
06257         XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
06258         XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY);
06259         XFREE(current, heap, DYNAMIC_TYPE_TLSX);
06260     }
06261 
06262     (void)heap;
06263 }
06264 
06265 /* Get the size of the encoded key share extension.
06266  *
06267  * list     The linked list of key share extensions.
06268  * msgType  The type of the message this extension is being written into.
06269  * returns the number of bytes of the encoded key share extension.
06270  */
06271 static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType)
06272 {
06273     int            len = 0;
06274     byte           isRequest = (msgType == client_hello);
06275     KeyShareEntry* current;
06276 
06277     /* The named group the server wants to use. */
06278     if (msgType == hello_retry_request)
06279         return OPAQUE16_LEN;
06280 
06281     /* List of key exchange groups. */
06282     if (isRequest)
06283         len += OPAQUE16_LEN;
06284     while ((current = list) != NULL) {
06285         list = current->next;
06286 
06287         if (!isRequest && current->key == NULL)
06288             continue;
06289 
06290         len += (int)(KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen);
06291     }
06292 
06293     return (word16)len;
06294 }
06295 
06296 /* Writes the key share extension into the output buffer.
06297  * Assumes that the the output buffer is big enough to hold data.
06298  *
06299  * list     The linked list of key share entries.
06300  * output   The buffer to write into.
06301  * msgType  The type of the message this extension is being written into.
06302  * returns the number of bytes written into the buffer.
06303  */
06304 static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output,
06305                                   byte msgType)
06306 {
06307     word16         i = 0;
06308     byte           isRequest = (msgType == client_hello);
06309     KeyShareEntry* current;
06310 
06311     if (msgType == hello_retry_request) {
06312         c16toa(list->group, output);
06313         return OPAQUE16_LEN;
06314     }
06315 
06316     /* ClientHello has a list but ServerHello is only the chosen. */
06317     if (isRequest)
06318         i += OPAQUE16_LEN;
06319 
06320     /* Write out all in the list. */
06321     while ((current = list) != NULL) {
06322         list = current->next;
06323 
06324         if (!isRequest && current->key == NULL)
06325             continue;
06326 
06327         c16toa(current->group, &output[i]);
06328         i += KE_GROUP_LEN;
06329         c16toa((word16)(current->pubKeyLen), &output[i]);
06330         i += OPAQUE16_LEN;
06331         XMEMCPY(&output[i], current->pubKey, current->pubKeyLen);
06332         i += (word16)current->pubKeyLen;
06333     }
06334     /* Write the length of the list if required. */
06335     if (isRequest)
06336         c16toa(i - OPAQUE16_LEN, output);
06337 
06338     return i;
06339 }
06340 
06341 /* Process the DH key share extension on the client side.
06342  *
06343  * ssl            The SSL/TLS object.
06344  * keyShareEntry  The key share entry object to use to calculate shared secret.
06345  * returns 0 on success and other values indicate failure.
06346  */
06347 static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
06348 {
06349 #ifndef NO_DH
06350     int             ret;
06351     const DhParams* params;
06352 #ifdef WOLFSSL_SMALL_STACK
06353     DhKey*          dhKey = NULL;
06354 #else
06355     DhKey           dhKey[1];
06356 #endif
06357 
06358     switch (keyShareEntry->group) {
06359     #ifdef HAVE_FFDHE_2048
06360         case WOLFSSL_FFDHE_2048:
06361             params = wc_Dh_ffdhe2048_Get();
06362             break;
06363     #endif
06364     #ifdef HAVE_FFDHE_3072
06365         case WOLFSSL_FFDHE_3072:
06366             params = wc_Dh_ffdhe3072_Get();
06367             break;
06368     #endif
06369     #ifdef HAVE_FFDHE_4096
06370         case WOLFSSL_FFDHE_4096:
06371             params = wc_Dh_ffdhe4096_Get();
06372             break;
06373     #endif
06374     #ifdef HAVE_FFDHE_6144
06375         case WOLFSSL_FFDHE_6144:
06376             params = wc_Dh_ffdhe6144_Get();
06377             break;
06378     #endif
06379     #ifdef HAVE_FFDHE_8192
06380         case WOLFSSL_FFDHE_8192:
06381             params = wc_Dh_ffdhe8192_Get();
06382             break;
06383     #endif
06384         default:
06385             return PEER_KEY_ERROR;
06386     }
06387 
06388 #ifdef WOLFSSL_DEBUG_TLS
06389     WOLFSSL_MSG("Peer DH Key");
06390     WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
06391 #endif
06392 
06393 #ifdef WOLFSSL_SMALL_STACK
06394     dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH);
06395     if (dhKey == NULL)
06396         return MEMORY_E;
06397 #endif
06398 
06399     ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId);
06400     if (ret != 0) {
06401     #ifdef WOLFSSL_SMALL_STACK
06402         XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
06403     #endif
06404         return ret;
06405     }
06406 
06407     /* Set key */
06408     ret = wc_DhSetKey(dhKey, (byte*)params->p, params->p_len, (byte*)params->g,
06409                                                                  params->g_len);
06410     if (ret != 0) {
06411         wc_FreeDhKey(dhKey);
06412     #ifdef WOLFSSL_SMALL_STACK
06413         XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
06414     #endif
06415         return ret;
06416     }
06417 
06418     ret = wc_DhCheckPubKey(dhKey, keyShareEntry->ke, keyShareEntry->keLen);
06419     if (ret != 0) {
06420         wc_FreeDhKey(dhKey);
06421     #ifdef WOLFSSL_SMALL_STACK
06422         XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
06423     #endif
06424         return PEER_KEY_ERROR;
06425     }
06426 
06427     /* Derive secret from private key and peer's public key. */
06428     ret = wc_DhAgree(dhKey,
06429         ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
06430         (const byte*)keyShareEntry->key, keyShareEntry->keyLen,
06431         keyShareEntry->ke, keyShareEntry->keLen);
06432 #ifdef WOLFSSL_ASYNC_CRYPT
06433     /* TODO: Make this function non-blocking */
06434     if (ret == WC_PENDING_E) {
06435         ret = wc_AsyncWait(ret, dhKey.asyncDev, WC_ASYNC_FLAG_NONE);
06436     }
06437 #endif
06438 
06439     wc_FreeDhKey(dhKey);
06440 #ifdef WOLFSSL_SMALL_STACK
06441     XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH);
06442 #endif
06443 
06444     return ret;
06445 #else
06446     (void)ssl;
06447     (void)keyShareEntry;
06448     return PEER_KEY_ERROR;
06449 #endif
06450 }
06451 
06452 /* Process the X25519 key share extension on the client side.
06453  *
06454  * ssl            The SSL/TLS object.
06455  * keyShareEntry  The key share entry object to use to calculate shared secret.
06456  * returns 0 on success and other values indicate failure.
06457  */
06458 static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl,
06459                                        KeyShareEntry* keyShareEntry)
06460 {
06461     int ret;
06462 
06463 #ifdef HAVE_CURVE25519
06464     curve25519_key* key = (curve25519_key*)keyShareEntry->key;
06465     curve25519_key* peerX25519Key;
06466 
06467 #ifdef HAVE_ECC
06468     if (ssl->peerEccKey != NULL) {
06469         wc_ecc_free(ssl->peerEccKey);
06470         ssl->peerEccKey = NULL;
06471     }
06472 #endif
06473 
06474     peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
06475                                                              DYNAMIC_TYPE_TLSX);
06476     if (peerX25519Key == NULL) {
06477         WOLFSSL_MSG("PeerEccKey Memory error");
06478         return MEMORY_ERROR;
06479     }
06480     ret = wc_curve25519_init(peerX25519Key);
06481     if (ret != 0) {
06482         XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
06483         return ret;
06484     }
06485 #ifdef WOLFSSL_DEBUG_TLS
06486     WOLFSSL_MSG("Peer Curve25519 Key");
06487     WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
06488 #endif
06489 
06490     /* Point is validated by import function. */
06491     if (wc_curve25519_import_public_ex(keyShareEntry->ke, keyShareEntry->keLen,
06492                                                   peerX25519Key,
06493                                                   EC25519_LITTLE_ENDIAN) != 0) {
06494         ret = ECC_PEERKEY_ERROR;
06495     }
06496 
06497     if (ret == 0) {
06498         ssl->arrays->preMasterSz = ENCRYPT_LEN;
06499         ssl->ecdhCurveOID = ECC_X25519_OID;
06500 
06501         ret = wc_curve25519_shared_secret_ex(key, peerX25519Key,
06502                                                    ssl->arrays->preMasterSecret,
06503                                                    &ssl->arrays->preMasterSz,
06504                                                    EC25519_LITTLE_ENDIAN);
06505     }
06506     wc_curve25519_free(peerX25519Key);
06507     XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
06508 #else
06509     (void)ssl;
06510     (void)keyShareEntry;
06511 
06512     ret = PEER_KEY_ERROR;
06513 #endif /* HAVE_CURVE25519 */
06514 
06515     return ret;
06516 }
06517 
06518 /* Process the ECC key share extension on the client side.
06519  *
06520  * ssl            The SSL/TLS object.
06521  * keyShareEntry  The key share entry object to use to calculate shared secret.
06522  * returns 0 on success and other values indicate failure.
06523  */
06524 static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
06525 {
06526     int ret;
06527 
06528 #ifdef HAVE_ECC
06529     int curveId;
06530     ecc_key* keyShareKey = (ecc_key*)keyShareEntry->key;
06531 
06532     if (ssl->peerEccKey != NULL)
06533         wc_ecc_free(ssl->peerEccKey);
06534 
06535     ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
06536                                         DYNAMIC_TYPE_ECC);
06537     if (ssl->peerEccKey == NULL) {
06538         WOLFSSL_MSG("PeerEccKey Memory error");
06539         return MEMORY_ERROR;
06540     }
06541     ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId);
06542     if (ret != 0)
06543         return ret;
06544 
06545     /* find supported curve */
06546     switch (keyShareEntry->group) {
06547     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
06548         #ifndef NO_ECC_SECP
06549         case WOLFSSL_ECC_SECP256R1:
06550             curveId = ECC_SECP256R1;
06551             break;
06552         #endif /* !NO_ECC_SECP */
06553     #endif
06554     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
06555         #ifndef NO_ECC_SECP
06556         case WOLFSSL_ECC_SECP384R1:
06557             curveId = ECC_SECP384R1;
06558             break;
06559         #endif /* !NO_ECC_SECP */
06560     #endif
06561     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
06562         #ifndef NO_ECC_SECP
06563         case WOLFSSL_ECC_SECP521R1:
06564             curveId = ECC_SECP521R1;
06565             break;
06566         #endif /* !NO_ECC_SECP */
06567     #endif
06568     #ifdef HAVE_X448
06569         case WOLFSSL_ECC_X448:
06570             curveId = ECC_X448;
06571             break;
06572     #endif
06573         default:
06574             /* unsupported curve */
06575             return ECC_PEERKEY_ERROR;
06576     }
06577 
06578 #ifdef WOLFSSL_DEBUG_TLS
06579     WOLFSSL_MSG("Peer ECC Key");
06580     WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
06581 #endif
06582 
06583     /* Point is validated by import function. */
06584     if (wc_ecc_import_x963_ex(keyShareEntry->ke, keyShareEntry->keLen,
06585                               ssl->peerEccKey, curveId) != 0) {
06586         return ECC_PEERKEY_ERROR;
06587     }
06588     ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum;
06589 
06590     ssl->arrays->preMasterSz = ENCRYPT_LEN;
06591     do {
06592     #if defined(WOLFSSL_ASYNC_CRYPT)
06593         ret = wc_AsyncWait(ret, &keyShareKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
06594     #endif
06595         if (ret >= 0)
06596             ret = wc_ecc_shared_secret(keyShareKey, ssl->peerEccKey,
06597                 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
06598     } while (ret == WC_PENDING_E);
06599 
06600 #if 0
06601     /* TODO: Switch to support async here and use: */
06602     ret = EccSharedSecret(ssl, keyShareEntry->key, ssl->peerEccKey,
06603         keyShareEntry->ke, &keyShareEntry->keLen,
06604         ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz,
06605         ssl->options.side
06606     );
06607 #endif
06608 
06609 
06610 #else
06611     (void)ssl;
06612     (void)keyShareEntry;
06613 
06614     ret = PEER_KEY_ERROR;
06615 #endif /* HAVE_ECC */
06616 
06617     return ret;
06618 }
06619 
06620 /* Process the key share extension on the client side.
06621  *
06622  * ssl            The SSL/TLS object.
06623  * keyShareEntry  The key share entry object to use to calculate shared secret.
06624  * returns 0 on success and other values indicate failure.
06625  */
06626 static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
06627 {
06628     int ret;
06629 
06630 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
06631     ssl->session.namedGroup = (byte)keyShareEntry->group;
06632 #endif
06633     /* Use Key Share Data from server. */
06634     if (keyShareEntry->group & NAMED_DH_MASK)
06635         ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
06636     else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
06637         ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
06638     else
06639         ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
06640 
06641 #ifdef WOLFSSL_DEBUG_TLS
06642     WOLFSSL_MSG("KE Secret");
06643     WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
06644 #endif
06645 
06646     return ret;
06647 }
06648 
06649 /* Parse an entry of the KeyShare extension.
06650  *
06651  * ssl     The SSL/TLS object.
06652  * input   The extension data.
06653  * length  The length of the extension data.
06654  * kse     The new key share entry object.
06655  * returns a positive number to indicate amount of data parsed and a negative
06656  * number on error.
06657  */
06658 static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, byte* input, word16 length,
06659                                     KeyShareEntry **kse)
06660 {
06661     int    ret;
06662     word16 group;
06663     word16 keLen;
06664     int    offset = 0;
06665     byte*  ke;
06666 
06667     if (length < OPAQUE16_LEN + OPAQUE16_LEN)
06668         return BUFFER_ERROR;
06669     /* Named group */
06670     ato16(&input[offset], &group);
06671     offset += OPAQUE16_LEN;
06672     /* Key exchange data - public key. */
06673     ato16(&input[offset], &keLen);
06674     offset += OPAQUE16_LEN;
06675     if (keLen < 1 || keLen > length - offset)
06676         return BUFFER_ERROR;
06677 
06678     /* Store a copy in the key share object. */
06679     ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06680     if (ke == NULL)
06681         return MEMORY_E;
06682     XMEMCPY(ke, &input[offset], keLen);
06683 
06684     /* Populate a key share object in the extension. */
06685     ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse);
06686     if (ret != 0) {
06687         XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06688         return ret;
06689     }
06690 
06691     /* Total length of the parsed data. */
06692     return offset + keLen;
06693 }
06694 
06695 /* Searches the groups sent for the specified named group.
06696  *
06697  * ssl    SSL/TLS object.
06698  * name   Group name to match.
06699  * returns 1 when the extension has the group name and 0 otherwise.
06700  */
06701 static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group)
06702 {
06703     TLSX*          extension;
06704     KeyShareEntry* list;
06705 
06706     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
06707     if (extension == NULL) {
06708         extension = TLSX_Find(ssl->ctx->extensions, TLSX_KEY_SHARE);
06709         if (extension == NULL)
06710             return 0;
06711     }
06712 
06713     list = (KeyShareEntry*)extension->data;
06714     while (list != NULL) {
06715         if (list->group == group)
06716             return 1;
06717         list = list->next;
06718     }
06719 
06720     return 0;
06721 }
06722 
06723 
06724 /* Searches the supported groups extension for the specified named group.
06725  *
06726  * ssl   The SSL/TLS object.
06727  * name  The group name to match.
06728  * returns 1 when the extension has the group name and 0 otherwise.
06729  */
06730 static int TLSX_SupportedGroups_Find(WOLFSSL* ssl, word16 name)
06731 {
06732 #ifdef HAVE_SUPPORTED_CURVES
06733     TLSX*          extension;
06734     SupportedCurve* curve = NULL;
06735 
06736     if ((extension = TLSX_Find(ssl->extensions,
06737                                               TLSX_SUPPORTED_GROUPS)) == NULL) {
06738         if ((extension = TLSX_Find(ssl->ctx->extensions,
06739                                               TLSX_SUPPORTED_GROUPS)) == NULL) {
06740             return 0;
06741         }
06742     }
06743 
06744     for (curve = (SupportedCurve*)extension->data; curve; curve = curve->next) {
06745         if (curve->name == name)
06746             return 1;
06747     }
06748 #endif
06749 
06750     (void)ssl;
06751     (void)name;
06752 
06753     return 0;
06754 }
06755 
06756 
06757 /* Parse the KeyShare extension.
06758  * Different formats in different messages.
06759  *
06760  * ssl      The SSL/TLS object.
06761  * input    The extension data.
06762  * length   The length of the extension data.
06763  * msgType  The type of the message this extension is being parsed from.
06764  * returns 0 on success and other values indicate failure.
06765  */
06766 static int TLSX_KeyShare_Parse(WOLFSSL* ssl, byte* input, word16 length,
06767                                byte msgType)
06768 {
06769     int ret;
06770     KeyShareEntry *keyShareEntry;
06771     word16 group;
06772 
06773     if (msgType == client_hello) {
06774         int    offset = 0;
06775         word16 len;
06776         TLSX*  extension;
06777 
06778         /* Add a KeyShare extension if it doesn't exist. */
06779         extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
06780         if (extension == NULL) {
06781             /* Push new KeyShare extension. */
06782             ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
06783             if (ret != 0)
06784                 return ret;
06785         }
06786 
06787         if (length < OPAQUE16_LEN)
06788             return BUFFER_ERROR;
06789 
06790         /* ClientHello contains zero or more key share entries. */
06791         ato16(input, &len);
06792         if (len != length - OPAQUE16_LEN)
06793             return BUFFER_ERROR;
06794         offset += OPAQUE16_LEN;
06795 
06796         while (offset < length) {
06797             ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset], length,
06798                                                                 &keyShareEntry);
06799             if (ret < 0)
06800                 return ret;
06801 
06802             offset += ret;
06803         }
06804 
06805         ret = 0;
06806     }
06807     else if (msgType == server_hello) {
06808         int len;
06809 
06810         if (length < OPAQUE16_LEN)
06811             return BUFFER_ERROR;
06812 
06813         /* The data is the named group the server wants to use. */
06814         ato16(input, &group);
06815 
06816         /* Check the selected group was supported by ClientHello extensions. */
06817         if (!TLSX_SupportedGroups_Find(ssl, group))
06818             return BAD_KEY_SHARE_DATA;
06819 
06820         /* Check if the group was sent. */
06821         if (!TLSX_KeyShare_Find(ssl, group))
06822             return BAD_KEY_SHARE_DATA;
06823 
06824         /* ServerHello contains one key share entry. */
06825         len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry);
06826         if (len != length)
06827             return BUFFER_ERROR;
06828 
06829         /* Not in list sent if there isn't a private key. */
06830         if (keyShareEntry->key == NULL)
06831             return BAD_KEY_SHARE_DATA;
06832 
06833         /* Process the entry to calculate the secret. */
06834         ret = TLSX_KeyShare_Process(ssl, keyShareEntry);
06835         if (ret == 0)
06836             ssl->session.namedGroup = ssl->namedGroup = group;
06837     }
06838     else if (msgType == hello_retry_request) {
06839         if (length != OPAQUE16_LEN)
06840             return BUFFER_ERROR;
06841 
06842         /* The data is the named group the server wants to use. */
06843         ato16(input, &group);
06844 
06845         /* Check the selected group was supported by ClientHello extensions. */
06846         if (!TLSX_SupportedGroups_Find(ssl, group))
06847             return BAD_KEY_SHARE_DATA;
06848 
06849         /* Check if the group was sent. */
06850         if (TLSX_KeyShare_Find(ssl, group))
06851             return BAD_KEY_SHARE_DATA;
06852 
06853         /* Clear out unusable key shares. */
06854         ret = TLSX_KeyShare_Empty(ssl);
06855         if (ret != 0)
06856             return ret;
06857 
06858         /* Try to use the server's group. */
06859         ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
06860     }
06861     else {
06862         /* Not a message type that is allowed to have this extension. */
06863         return SANITY_MSG_E;
06864     }
06865 
06866     return ret;
06867 }
06868 
06869 /* Create a new key share entry and put it into the list.
06870  *
06871  * list           The linked list of key share entries.
06872  * group          The named group.
06873  * heap           The memory to allocate with.
06874  * keyShareEntry  The new key share entry object.
06875  * returns 0 on success and other values indicate failure.
06876  */
06877 static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
06878                              KeyShareEntry** keyShareEntry)
06879 {
06880     KeyShareEntry* kse;
06881 
06882     kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap,
06883                                   DYNAMIC_TYPE_TLSX);
06884     if (kse == NULL)
06885         return MEMORY_E;
06886 
06887     XMEMSET(kse, 0, sizeof(*kse));
06888     kse->group = (word16)group;
06889 
06890     /* Add it to the back and maintain the links. */
06891     while (*list != NULL)
06892         list = &((*list)->next);
06893     *list = kse;
06894     *keyShareEntry = kse;
06895 
06896     (void)heap;
06897 
06898     return 0;
06899 }
06900 
06901 /* Use the data to create a new key share object in the extensions.
06902  *
06903  * ssl    The SSL/TLS object.
06904  * group  The named group.
06905  * len    The length of the public key data.
06906  * data   The public key data.
06907  * kse    The new key share entry object.
06908  * returns 0 on success and other values indicate failure.
06909  */
06910 int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
06911                       KeyShareEntry **kse)
06912 {
06913     int            ret = 0;
06914     TLSX*          extension;
06915     KeyShareEntry* keyShareEntry = NULL;
06916 
06917     /* Find the KeyShare extension if it exists. */
06918     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
06919     if (extension == NULL) {
06920         /* Push new KeyShare extension. */
06921         ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
06922         if (ret != 0)
06923             return ret;
06924 
06925         extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
06926         if (extension == NULL)
06927             return MEMORY_E;
06928     }
06929     extension->resp = 0;
06930 
06931     /* Try to find the key share entry with this group. */
06932     keyShareEntry = (KeyShareEntry*)extension->data;
06933     while (keyShareEntry != NULL) {
06934         if (keyShareEntry->group == group)
06935             break;
06936         keyShareEntry = keyShareEntry->next;
06937     }
06938 
06939     /* Create a new key share entry if not found. */
06940     if (keyShareEntry == NULL) {
06941         ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group,
06942                                 ssl->heap, &keyShareEntry);
06943         if (ret != 0)
06944             return ret;
06945     }
06946 
06947     if (data != NULL) {
06948         keyShareEntry->ke = data;
06949         keyShareEntry->keLen = len;
06950     }
06951     else {
06952         /* Generate a key pair. */
06953         ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry);
06954         if (ret != 0)
06955             return ret;
06956     }
06957 
06958     if (kse != NULL)
06959         *kse = keyShareEntry;
06960 
06961     return 0;
06962 }
06963 
06964 /* Set an empty Key Share extension.
06965  *
06966  * ssl  The SSL/TLS object.
06967  * returns 0 on success and other values indicate failure.
06968  */
06969 int TLSX_KeyShare_Empty(WOLFSSL* ssl)
06970 {
06971     int   ret = 0;
06972     TLSX* extension;
06973 
06974     /* Find the KeyShare extension if it exists. */
06975     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
06976     if (extension == NULL) {
06977         /* Push new KeyShare extension. */
06978         ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
06979     }
06980     else if (extension->data != NULL) {
06981         TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
06982         extension->data = NULL;
06983     }
06984 
06985     return ret;
06986 }
06987 
06988 /* Returns whether this group is supported.
06989  *
06990  * namedGroup  The named group to check.
06991  * returns 1 when supported or 0 otherwise.
06992  */
06993 static int TLSX_KeyShare_IsSupported(int namedGroup)
06994 {
06995     switch (namedGroup) {
06996     #ifdef HAVE_FFDHE_2048
06997         case WOLFSSL_FFDHE_2048:
06998             break;
06999     #endif
07000     #ifdef HAVE_FFDHE_3072
07001         case WOLFSSL_FFDHE_3072:
07002             break;
07003     #endif
07004     #ifdef HAVE_FFDHE_4096
07005         case WOLFSSL_FFDHE_4096:
07006             break;
07007     #endif
07008     #ifdef HAVE_FFDHE_6144
07009         case WOLFSSL_FFDHE_6144:
07010             break;
07011     #endif
07012     #ifdef HAVE_FFDHE_8192
07013         case WOLFSSL_FFDHE_8192:
07014             break;
07015     #endif
07016     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
07017         #ifndef NO_ECC_SECP
07018         case WOLFSSL_ECC_SECP256R1:
07019             break;
07020         #endif /* !NO_ECC_SECP */
07021     #endif
07022     #ifdef HAVE_CURVE25519
07023         case WOLFSSL_ECC_X25519:
07024             break;
07025     #endif
07026     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
07027         #ifndef NO_ECC_SECP
07028         case WOLFSSL_ECC_SECP384R1:
07029             break;
07030         #endif /* !NO_ECC_SECP */
07031     #endif
07032     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
07033         #ifndef NO_ECC_SECP
07034         case WOLFSSL_ECC_SECP521R1:
07035             break;
07036         #endif /* !NO_ECC_SECP */
07037     #endif
07038     #ifdef HAVE_X448
07039         case WOLFSSL_ECC_X448:
07040             break;
07041     #endif
07042         default:
07043             return 0;
07044     }
07045 
07046     return 1;
07047 }
07048 
07049 /* Examines the application specified group ranking and returns the rank of the
07050  * group.
07051  * If no group ranking set then all groups are rank 0 (highest).
07052  *
07053  * ssl    The SSL/TLS object.
07054  * group  The group to check ranking for.
07055  * returns ranking from 0 to MAX_GROUP_COUNT-1 or -1 when group not in list.
07056  */
07057 static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
07058 {
07059     byte i;
07060 
07061     if (ssl->numGroups == 0) {
07062 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
07063     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
07064         #ifndef NO_ECC_SECP
07065             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP256R1;
07066         #endif
07067     #endif
07068 #endif
07069     #ifndef HAVE_FIPS
07070         #if defined(HAVE_CURVE25519)
07071             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519;
07072         #endif
07073     #endif
07074 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
07075     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
07076         #ifndef NO_ECC_SECP
07077             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP384R1;
07078         #endif
07079     #endif
07080     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
07081         #ifndef NO_ECC_SECP
07082             ssl->group[ssl->numGroups++] = WOLFSSL_ECC_SECP521R1;
07083         #endif
07084     #endif
07085 #endif
07086             /* Add FFDHE supported groups. */
07087         #ifdef HAVE_FFDHE_2048
07088             ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_2048;
07089         #endif
07090         #ifdef HAVE_FFDHE_3072
07091             ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_3072;
07092         #endif
07093         #ifdef HAVE_FFDHE_4096
07094             ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_4096;
07095         #endif
07096         #ifdef HAVE_FFDHE_6144
07097             ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_6144;
07098         #endif
07099         #ifdef HAVE_FFDHE_8192
07100             ssl->group[ssl->numGroups++] = WOLFSSL_FFDHE_8192;
07101         #endif
07102     }
07103 
07104     for (i = 0; i < ssl->numGroups; i++)
07105         if (ssl->group[i] == group)
07106             return i;
07107 
07108     return -1;
07109 }
07110 
07111 /* Set a key share that is supported by the client into extensions.
07112  *
07113  * ssl  The SSL/TLS object.
07114  * returns BAD_KEY_SHARE_DATA if no supported group has a key share,
07115  * 0 if a supported group has a key share and other values indicate an error.
07116  */
07117 static int TLSX_KeyShare_SetSupported(WOLFSSL* ssl)
07118 {
07119     int             ret;
07120 #ifdef HAVE_SUPPORTED_CURVES
07121     TLSX*           extension;
07122     SupportedCurve* curve = NULL;
07123     SupportedCurve* preferredCurve = NULL;
07124     int             preferredRank = WOLFSSL_MAX_GROUP_COUNT;
07125     int             rank;
07126 
07127     extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
07128     if (extension != NULL)
07129         curve = (SupportedCurve*)extension->data;
07130     /* Use server's preference order. */
07131     for (; curve != NULL; curve = curve->next) {
07132         if (!TLSX_KeyShare_IsSupported(curve->name))
07133             continue;
07134 
07135         rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
07136         if (rank == -1)
07137             continue;
07138         if (rank < preferredRank) {
07139             preferredCurve = curve;
07140             preferredRank = rank;
07141         }
07142     }
07143     curve = preferredCurve;
07144 
07145     if (curve == NULL)
07146         return BAD_KEY_SHARE_DATA;
07147 
07148     /* Delete the old key share data list. */
07149     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
07150     if (extension != NULL) {
07151         TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
07152         extension->data = NULL;
07153     }
07154 
07155     /* Add in the chosen group. */
07156     ret = TLSX_KeyShare_Use(ssl, curve->name, 0, NULL, NULL);
07157     if (ret != 0)
07158         return ret;
07159 
07160     /* Set extension to be in reponse. */
07161     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
07162     extension->resp = 1;
07163 #else
07164 
07165     (void)ssl;
07166     ret = NOT_COMPILED_IN;
07167 #endif
07168 
07169     return ret;
07170 }
07171 
07172 /* Ensure there is a key pair that can be used for key exchange.
07173  *
07174  * ssl  The SSL/TLS object.
07175  * returns 0 on success and other values indicate failure.
07176  */
07177 int TLSX_KeyShare_Establish(WOLFSSL *ssl)
07178 {
07179     int            ret;
07180     TLSX*          extension;
07181     KeyShareEntry* clientKSE = NULL;
07182     KeyShareEntry* serverKSE;
07183     KeyShareEntry* list = NULL;
07184     KeyShareEntry* preferredKSE = NULL;
07185     int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
07186     int rank;
07187 
07188     /* Find the KeyShare extension if it exists. */
07189     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
07190     if (extension != NULL)
07191         list = (KeyShareEntry*)extension->data;
07192 
07193     if (extension && extension->resp == 1)
07194         return 0;
07195 
07196     /* Use server's preference order. */
07197     for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) {
07198         if (clientKSE->ke == NULL)
07199             continue;
07200 
07201         /* Check consistency now - extensions in any order. */
07202         if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group))
07203             return BAD_KEY_SHARE_DATA;
07204 
07205     #ifdef OPENSSL_EXTRA
07206         if ((clientKSE->group & NAMED_DH_MASK) == 0) {
07207             /* Check if server supports group. */
07208             if (ssl->ctx->disabledCurves & (1 << clientKSE->group))
07209                 continue;
07210         }
07211     #endif
07212         if (!TLSX_KeyShare_IsSupported(clientKSE->group))
07213             continue;
07214 
07215         rank = TLSX_KeyShare_GroupRank(ssl, clientKSE->group);
07216         if (rank == -1)
07217             continue;
07218         if (rank < preferredRank) {
07219             preferredKSE = clientKSE;
07220             preferredRank = rank;
07221         }
07222     }
07223     clientKSE = preferredKSE;
07224 
07225     /* No supported group found - send HelloRetryRequest. */
07226     if (clientKSE == NULL) {
07227         ret = TLSX_KeyShare_SetSupported(ssl);
07228         /* Return KEY_SHARE_ERROR to indicate HelloRetryRequest required. */
07229         if (ret == 0)
07230             return KEY_SHARE_ERROR;
07231         return ret;
07232     }
07233 
07234     list = NULL;
07235     /* Generate a new key pair. */
07236     ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE);
07237     if (ret != 0)
07238         return ret;
07239 
07240     if (clientKSE->key == NULL) {
07241         ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
07242         if (ret != 0)
07243             return ret;
07244     }
07245     else {
07246         serverKSE->key = clientKSE->key;
07247         serverKSE->keyLen = clientKSE->keyLen;
07248         serverKSE->pubKey = clientKSE->pubKey;
07249         serverKSE->pubKeyLen = clientKSE->pubKeyLen;
07250         clientKSE->key = NULL;
07251         clientKSE->pubKey = NULL;
07252     }
07253     serverKSE->ke = clientKSE->ke;
07254     serverKSE->keLen = clientKSE->keLen;
07255     clientKSE->ke = NULL;
07256     clientKSE->keLen = 0;
07257 
07258     TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
07259     extension->data = (void *)serverKSE;
07260 
07261     extension->resp = 1;
07262 
07263     return 0;
07264 }
07265 
07266 /* Derive the shared secret of the key exchange.
07267  *
07268  * ssl  The SSL/TLS object.
07269  * returns 0 on success and other values indicate failure.
07270  */
07271 int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
07272 {
07273     int            ret;
07274     TLSX*          extension;
07275     KeyShareEntry* list = NULL;
07276 
07277     /* Find the KeyShare extension if it exists. */
07278     extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
07279     if (extension != NULL)
07280         list = (KeyShareEntry*)extension->data;
07281 
07282     if (list == NULL)
07283         return KEY_SHARE_ERROR;
07284 
07285     /* Calculate secret. */
07286     ret = TLSX_KeyShare_Process(ssl, list);
07287     if (ret != 0)
07288         return ret;
07289 
07290     return ret;
07291 }
07292 
07293 #define KS_FREE_ALL  TLSX_KeyShare_FreeAll
07294 #define KS_GET_SIZE  TLSX_KeyShare_GetSize
07295 #define KS_WRITE     TLSX_KeyShare_Write
07296 #define KS_PARSE     TLSX_KeyShare_Parse
07297 
07298 #else
07299 
07300 #define KS_FREE_ALL(a, b)
07301 #define KS_GET_SIZE(a, b)    0
07302 #define KS_WRITE(a, b, c)    0
07303 #define KS_PARSE(a, b, c, d) 0
07304 
07305 #endif /* WOLFSSL_TLS13 */
07306 
07307 /******************************************************************************/
07308 /* Pre-Shared Key                                                             */
07309 /******************************************************************************/
07310 
07311 #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
07312 /* Free the pre-shared key dynamic data.
07313  *
07314  * list  The linked list of key share entry objects.
07315  * heap  The heap used for allocation.
07316  */
07317 static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap)
07318 {
07319     PreSharedKey* current;
07320 
07321     while ((current = list) != NULL) {
07322         list = current->next;
07323         XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX);
07324         XFREE(current, heap, DYNAMIC_TYPE_TLSX);
07325     }
07326 
07327     (void)heap;
07328 }
07329 
07330 /* Get the size of the encoded pre shared key extension.
07331  *
07332  * list     The linked list of pre-shared key extensions.
07333  * msgType  The type of the message this extension is being written into.
07334  * returns the number of bytes of the encoded pre-shared key extension or
07335  * SANITY_MSG_E to indicate invalid message type.
07336  */
07337 static word16 TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType)
07338 {
07339     if (msgType == client_hello) {
07340         /* Length of identities + Length of binders. */
07341         word16 len = OPAQUE16_LEN + OPAQUE16_LEN;
07342         while (list != NULL) {
07343             /* Each entry has: identity, ticket age and binder. */
07344             len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
07345                    OPAQUE8_LEN + list->binderLen;
07346             list = list->next;
07347         }
07348         return len;
07349     }
07350 
07351     if (msgType == server_hello) {
07352         return OPAQUE16_LEN;
07353     }
07354 
07355     return 0;
07356 }
07357 
07358 /* The number of bytes to be written for the binders.
07359  *
07360  * list     The linked list of pre-shared key extensions.
07361  * msgType  The type of the message this extension is being written into.
07362  * returns the number of bytes of the encoded pre-shared key extension or
07363  * SANITY_MSG_E to indicate invalid message type.
07364  */
07365 word16 TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType)
07366 {
07367     word16 len;
07368 
07369     if (msgType != client_hello)
07370         return SANITY_MSG_E;
07371 
07372     /* Length of all binders. */
07373     len = OPAQUE16_LEN;
07374     while (list != NULL) {
07375         len += OPAQUE8_LEN + list->binderLen;
07376         list = list->next;
07377     }
07378 
07379     return len;
07380 }
07381 
07382 /* Writes the pre-shared key extension into the output buffer - binders only.
07383  * Assumes that the the output buffer is big enough to hold data.
07384  *
07385  * list     The linked list of key share entries.
07386  * output   The buffer to write into.
07387  * msgType  The type of the message this extension is being written into.
07388  * returns the number of bytes written into the buffer.
07389  */
07390 word16 TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output,
07391                                       byte msgType)
07392 {
07393     PreSharedKey* current = list;
07394     word16 idx = 0;
07395     word16 lenIdx;
07396     word16 len;
07397 
07398     if (msgType != client_hello)
07399         return SANITY_MSG_E;
07400 
07401     /* Skip length of all binders. */
07402     lenIdx = idx;
07403     idx += OPAQUE16_LEN;
07404     while (current != NULL) {
07405         /* Binder data length. */
07406         output[idx++] = current->binderLen;
07407         /* Binder data. */
07408         XMEMCPY(output + idx, current->binder, current->binderLen);
07409         idx += current->binderLen;
07410 
07411         current = current->next;
07412     }
07413     /* Length of the binders. */
07414     len = idx - lenIdx - OPAQUE16_LEN;
07415     c16toa(len, output + lenIdx);
07416 
07417     return idx;
07418 }
07419 
07420 
07421 /* Writes the pre-shared key extension into the output buffer.
07422  * Assumes that the the output buffer is big enough to hold data.
07423  *
07424  * list     The linked list of key share entries.
07425  * output   The buffer to write into.
07426  * msgType  The type of the message this extension is being written into.
07427  * returns the number of bytes written into the buffer.
07428  */
07429 static word16 TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output,
07430                                       byte msgType)
07431 {
07432     if (msgType == client_hello) {
07433         PreSharedKey* current = list;
07434         word16 idx = 0;
07435         word16 lenIdx;
07436         word16 len;
07437 
07438         /* Write identites only. Binders after HMACing over this. */
07439         lenIdx = idx;
07440         idx += OPAQUE16_LEN;
07441         while (current != NULL) {
07442             /* Identity length */
07443             c16toa(current->identityLen, output + idx);
07444             idx += OPAQUE16_LEN;
07445             /* Identity data */
07446             XMEMCPY(output + idx, current->identity, current->identityLen);
07447             idx += current->identityLen;
07448 
07449             /* Obfuscated ticket age. */
07450             c32toa(current->ticketAge, output + idx);
07451             idx += OPAQUE32_LEN;
07452 
07453             current = current->next;
07454         }
07455         /* Length of the identites. */
07456         len = idx - lenIdx - OPAQUE16_LEN;
07457         c16toa(len, output + lenIdx);
07458 
07459         /* Don't include binders here.
07460          * The binders are based on the hash of all the ClientHello data up to
07461          * and include the identities written above.
07462          */
07463         idx += TLSX_PreSharedKey_GetSizeBinders(list, msgType);
07464 
07465         return idx;
07466     }
07467 
07468     if (msgType == server_hello) {
07469         word16 i;
07470 
07471         /* Find the index of the chosen identity. */
07472         for (i=0; list != NULL && !list->chosen; i++)
07473             list = list->next;
07474         if (list == NULL)
07475             return BUILD_MSG_ERROR;
07476 
07477         /* The index of the identity chosen by the server from the list supplied
07478          * by the client.
07479          */
07480         c16toa(i, output);
07481         return OPAQUE16_LEN;
07482     }
07483 
07484     return 0;
07485 }
07486 
07487 /* Parse the pre-shared key extension.
07488  * Different formats in different messages.
07489  *
07490  * ssl      The SSL/TLS object.
07491  * input    The extension data.
07492  * length   The length of the extension data.
07493  * msgType  The type of the message this extension is being parsed from.
07494  * returns 0 on success and other values indicate failure.
07495  */
07496 static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
07497                                    byte msgType)
07498 {
07499     TLSX*         extension;
07500     PreSharedKey* list;
07501 
07502     if (msgType == client_hello) {
07503         int    ret;
07504         word16 len;
07505         word16 idx = 0;
07506 
07507         TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
07508 
07509         /* Length of identities and of binders. */
07510         if (length - idx < OPAQUE16_LEN + OPAQUE16_LEN)
07511             return BUFFER_E;
07512 
07513         /* Length of identities. */
07514         ato16(input + idx, &len);
07515         idx += OPAQUE16_LEN;
07516         if (len < MIN_PSK_ID_LEN || length - idx < len)
07517             return BUFFER_E;
07518 
07519         /* Create a pre-shared key object for each identity. */
07520         while (len > 0) {
07521             byte*  identity;
07522             word16 identityLen;
07523             word32 age;
07524 
07525             if (len < OPAQUE16_LEN)
07526                 return BUFFER_E;
07527 
07528             /* Length of identity. */
07529             ato16(input + idx, &identityLen);
07530             idx += OPAQUE16_LEN;
07531             if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN)
07532                 return BUFFER_E;
07533             /* Cache identity pointer. */
07534             identity = input + idx;
07535             idx += identityLen;
07536             /* Ticket age. */
07537             ato32(input + idx, &age);
07538             idx += OPAQUE32_LEN;
07539 
07540             ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac,
07541                                         0, 0, 1, NULL);
07542             if (ret != 0)
07543                 return ret;
07544 
07545             /* Done with this identity. */
07546             len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN;
07547         }
07548 
07549         /* Find the list of identities sent to server. */
07550         extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
07551         if (extension == NULL)
07552             return PSK_KEY_ERROR;
07553         list = (PreSharedKey*)extension->data;
07554 
07555         /* Length of binders. */
07556         ato16(input + idx, &len);
07557         idx += OPAQUE16_LEN;
07558         if (len < MIN_PSK_BINDERS_LEN || length - idx < len)
07559             return BUFFER_E;
07560 
07561         /* Set binder for each identity. */
07562         while (list != NULL && len > 0) {
07563             /* Length of binder */
07564             list->binderLen = input[idx++];
07565             if (list->binderLen < WC_SHA256_DIGEST_SIZE ||
07566                     list->binderLen > WC_MAX_DIGEST_SIZE)
07567                 return BUFFER_E;
07568             if (len < OPAQUE8_LEN + list->binderLen)
07569                 return BUFFER_E;
07570 
07571             /* Copy binder into static buffer. */
07572             XMEMCPY(list->binder, input + idx, list->binderLen);
07573             idx += list->binderLen;
07574 
07575             /* Done with binder entry. */
07576             len -= OPAQUE8_LEN + list->binderLen;
07577 
07578             /* Next identity. */
07579             list = list->next;
07580         }
07581         if (list != NULL || len != 0)
07582             return BUFFER_E;
07583 
07584         return 0;
07585     }
07586 
07587     if (msgType == server_hello) {
07588         word16 idx;
07589 
07590         /* Index of identity chosen by server. */
07591         if (length != OPAQUE16_LEN)
07592             return BUFFER_E;
07593         ato16(input, &idx);
07594 
07595     #ifdef WOLFSSL_EARLY_DATA
07596         ssl->options.pskIdIndex = idx + 1;
07597     #endif
07598 
07599         /* Find the list of identities sent to server. */
07600         extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
07601         if (extension == NULL)
07602             return PSK_KEY_ERROR;
07603         list = (PreSharedKey*)extension->data;
07604 
07605         /* Mark the identity as chosen. */
07606         for (; list != NULL && idx > 0; idx--)
07607             list = list->next;
07608         if (list == NULL)
07609             return PSK_KEY_ERROR;
07610         list->chosen = 1;
07611 
07612     #ifdef HAVE_SESSION_TICKET
07613         if (list->resumption) {
07614            /* Check that the session's details are the same as the server's. */
07615            if (ssl->options.cipherSuite0  != ssl->session.cipherSuite0       ||
07616                ssl->options.cipherSuite   != ssl->session.cipherSuite        ||
07617                ssl->session.version.major != ssl->ctx->method->version.major ||
07618                ssl->session.version.minor != ssl->ctx->method->version.minor) {
07619                return PSK_KEY_ERROR;
07620            }
07621         }
07622     #endif
07623 
07624         return 0;
07625     }
07626 
07627     return SANITY_MSG_E;
07628 }
07629 
07630 /* Create a new pre-shared key and put it into the list.
07631  *
07632  * list          The linked list of pre-shared key.
07633  * identity      The identity.
07634  * len           The length of the identity data.
07635  * heap          The memory to allocate with.
07636  * preSharedKey  The new pre-shared key object.
07637  * returns 0 on success and other values indicate failure.
07638  */
07639 static int TLSX_PreSharedKey_New(PreSharedKey** list, byte* identity,
07640                                  word16 len, void *heap,
07641                                  PreSharedKey** preSharedKey)
07642 {
07643     PreSharedKey* psk;
07644 
07645     psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX);
07646     if (psk == NULL)
07647         return MEMORY_E;
07648     XMEMSET(psk, 0, sizeof(*psk));
07649 
07650     /* Make a copy of the identity data. */
07651     psk->identity = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TLSX);
07652     if (psk->identity == NULL) {
07653         XFREE(psk, heap, DYNAMIC_TYPE_TLSX);
07654         return MEMORY_E;
07655     }
07656     XMEMCPY(psk->identity, identity, len);
07657     psk->identityLen = len;
07658 
07659     /* Add it to the end and maintain the links. */
07660     while (*list != NULL)
07661         list = &((*list)->next);
07662     *list = psk;
07663     *preSharedKey = psk;
07664 
07665     return 0;
07666 }
07667 
07668 static WC_INLINE byte GetHmacLength(int hmac)
07669 {
07670     switch (hmac) {
07671     #ifndef NO_SHA256
07672         case sha256_mac:
07673             return WC_SHA256_DIGEST_SIZE;
07674     #endif
07675     #ifdef WOLFSSL_SHA384
07676         case sha384_mac:
07677             return WC_SHA384_DIGEST_SIZE;
07678     #endif
07679     #ifdef WOLFSSL_SHA512
07680         case sha512_mac:
07681             return WC_SHA512_DIGEST_SIZE;
07682     #endif
07683     }
07684     return 0;
07685 }
07686 
07687 /* Use the data to create a new pre-shared key object in the extensions.
07688  *
07689  * ssl           The SSL/TLS object.
07690  * identity      The identity.
07691  * len           The length of the identity data.
07692  * age           The age of the identity.
07693  * hmac          The HMAC algorithm.
07694  * ciphersuite0  The first byte of the ciphersuite to use.
07695  * ciphersuite   The second byte of the ciphersuite to use.
07696  * resumption    The PSK is for resumption of a session.
07697  * preSharedKey  The new pre-shared key object.
07698  * returns 0 on success and other values indicate failure.
07699  */
07700 int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
07701                           byte hmac, byte cipherSuite0,
07702                           byte cipherSuite, byte resumption,
07703                           PreSharedKey **preSharedKey)
07704 {
07705     int           ret = 0;
07706     TLSX*         extension;
07707     PreSharedKey* psk = NULL;
07708 
07709     /* Find the pre-shared key extension if it exists. */
07710     extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
07711     if (extension == NULL) {
07712         /* Push new pre-shared key extension. */
07713         ret = TLSX_Push(&ssl->extensions, TLSX_PRE_SHARED_KEY, NULL, ssl->heap);
07714         if (ret != 0)
07715             return ret;
07716 
07717         extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
07718         if (extension == NULL)
07719             return MEMORY_E;
07720     }
07721 
07722     /* Try to find the pre-shared key with this identity. */
07723     psk = (PreSharedKey*)extension->data;
07724     while (psk != NULL) {
07725         if ((psk->identityLen == len) &&
07726                (XMEMCMP(psk->identity, identity, len) == 0)) {
07727             break;
07728         }
07729         psk = psk->next;
07730     }
07731 
07732     /* Create a new pre-shared key object if not found. */
07733     if (psk == NULL) {
07734         ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity,
07735                                     len, ssl->heap, &psk);
07736         if (ret != 0)
07737             return ret;
07738     }
07739 
07740     /* Update/set age and HMAC algorithm. */
07741     psk->ticketAge    = age;
07742     psk->hmac         = hmac;
07743     psk->cipherSuite0 = cipherSuite0;
07744     psk->cipherSuite  = cipherSuite;
07745     psk->resumption   = resumption;
07746     psk->binderLen    = GetHmacLength(psk->hmac);
07747 
07748     if (preSharedKey != NULL)
07749         *preSharedKey = psk;
07750 
07751     return 0;
07752 }
07753 
07754 #define PSK_FREE_ALL  TLSX_PreSharedKey_FreeAll
07755 #define PSK_GET_SIZE  TLSX_PreSharedKey_GetSize
07756 #define PSK_WRITE     TLSX_PreSharedKey_Write
07757 #define PSK_PARSE     TLSX_PreSharedKey_Parse
07758 
07759 #else
07760 
07761 #define PSK_FREE_ALL(a, b)
07762 #define PSK_GET_SIZE(a, b)    0
07763 #define PSK_WRITE(a, b, c)    0
07764 #define PSK_PARSE(a, b, c, d) 0
07765 
07766 #endif
07767 
07768 /******************************************************************************/
07769 /* PSK Key Exchange Modes                                                     */
07770 /******************************************************************************/
07771 
07772 #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
07773 /* Get the size of the encoded PSK KE modes extension.
07774  * Only in ClientHello.
07775  *
07776  * modes    The PSK KE mode bit string.
07777  * msgType  The type of the message this extension is being written into.
07778  * returns the number of bytes of the encoded PSK KE mode extension.
07779  */
07780 static word16 TLSX_PskKeModes_GetSize(byte modes, byte msgType)
07781 {
07782     if (msgType == client_hello) {
07783         /* Format: Len | Modes* */
07784         word16 len = OPAQUE8_LEN;
07785         /* Check whether each possible mode is to be written. */
07786         if (modes & (1 << PSK_KE))
07787             len += OPAQUE8_LEN;
07788         if (modes & (1 << PSK_DHE_KE))
07789             len += OPAQUE8_LEN;
07790         return len;
07791     }
07792 
07793     return SANITY_MSG_E;
07794 }
07795 
07796 /* Writes the PSK KE modes extension into the output buffer.
07797  * Assumes that the the output buffer is big enough to hold data.
07798  * Only in ClientHello.
07799  *
07800  * modes    The PSK KE mode bit string.
07801  * output   The buffer to write into.
07802  * msgType  The type of the message this extension is being written into.
07803  * returns the number of bytes written into the buffer.
07804  */
07805 static word16 TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType)
07806 {
07807     if (msgType == client_hello) {
07808         /* Format: Len | Modes* */
07809         int idx = OPAQUE8_LEN;
07810 
07811         /* Write out each possible mode. */
07812         if (modes & (1 << PSK_KE))
07813             output[idx++] = PSK_KE;
07814         if (modes & (1 << PSK_DHE_KE))
07815             output[idx++] = PSK_DHE_KE;
07816         /* Write out length of mode list. */
07817         output[0] = idx - OPAQUE8_LEN;
07818 
07819         return idx;
07820     }
07821 
07822     return SANITY_MSG_E;
07823 }
07824 
07825 /* Parse the PSK KE modes extension.
07826  * Only in ClientHello.
07827  *
07828  * ssl      The SSL/TLS object.
07829  * input    The extension data.
07830  * length   The length of the extension data.
07831  * msgType  The type of the message this extension is being parsed from.
07832  * returns 0 on success and other values indicate failure.
07833  */
07834 static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, byte* input, word16 length,
07835                                  byte msgType)
07836 {
07837     int    ret;
07838 
07839     if (msgType == client_hello) {
07840         /* Format: Len | Modes* */
07841         int   idx = 0;
07842         int   len;
07843         byte  modes = 0;
07844 
07845         /* Ensure length byte exists. */
07846         if (length < OPAQUE8_LEN)
07847             return BUFFER_E;
07848 
07849         /* Get length of mode list and ensure that is the only data. */
07850         len = input[0];
07851         if (length - OPAQUE8_LEN != len)
07852             return BUFFER_E;
07853 
07854         idx = OPAQUE8_LEN;
07855         /* Set a bit for each recognized modes. */
07856         while (len > 0) {
07857             /* Ignore unrecognized modes.  */
07858             if (input[idx] <= PSK_DHE_KE)
07859                modes |= 1 << input[idx];
07860             idx++;
07861             len--;
07862         }
07863 
07864         ret = TLSX_PskKeModes_Use(ssl, modes);
07865         if (ret != 0)
07866             return ret;
07867 
07868         return 0;
07869     }
07870 
07871     return SANITY_MSG_E;
07872 }
07873 
07874 /* Use the data to create a new PSK Key Exchange Modes object in the extensions.
07875  *
07876  * ssl    The SSL/TLS object.
07877  * modes  The PSK key exchange modes.
07878  * returns 0 on success and other values indicate failure.
07879  */
07880 int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes)
07881 {
07882     int           ret = 0;
07883     TLSX*         extension;
07884 
07885     /* Find the PSK key exchange modes extension if it exists. */
07886     extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
07887     if (extension == NULL) {
07888         /* Push new PSK key exchange modes extension. */
07889         ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL,
07890             ssl->heap);
07891         if (ret != 0)
07892             return ret;
07893 
07894         extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
07895         if (extension == NULL)
07896             return MEMORY_E;
07897     }
07898 
07899     extension->val = modes;
07900 
07901     return 0;
07902 }
07903 
07904 #define PKM_GET_SIZE  TLSX_PskKeModes_GetSize
07905 #define PKM_WRITE     TLSX_PskKeModes_Write
07906 #define PKM_PARSE     TLSX_PskKeModes_Parse
07907 
07908 #else
07909 
07910 #define PKM_GET_SIZE(a, b)    0
07911 #define PKM_WRITE(a, b, c)    0
07912 #define PKM_PARSE(a, b, c, d) 0
07913 
07914 #endif
07915 
07916 /******************************************************************************/
07917 /* Post-Handshake Authentication                                              */
07918 /******************************************************************************/
07919 
07920 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
07921 /* Get the size of the encoded Post-Hanshake Authentication extension.
07922  * Only in ClientHello.
07923  *
07924  * msgType  The type of the message this extension is being written into.
07925  * returns the number of bytes of the encoded Post-Hanshake Authentication
07926  * extension.
07927  */
07928 static word16 TLSX_PostHandAuth_GetSize(byte msgType)
07929 {
07930     if (msgType == client_hello)
07931         return 0;
07932 
07933     return SANITY_MSG_E;
07934 }
07935 
07936 /* Writes the Post-Handshake Authentication extension into the output buffer.
07937  * Assumes that the the output buffer is big enough to hold data.
07938  * Only in ClientHello.
07939  *
07940  * output   The buffer to write into.
07941  * msgType  The type of the message this extension is being written into.
07942  * returns the number of bytes written into the buffer.
07943  */
07944 static word16 TLSX_PostHandAuth_Write(byte* output, byte msgType)
07945 {
07946     (void)output;
07947 
07948     if (msgType == client_hello)
07949         return 0;
07950 
07951     return SANITY_MSG_E;
07952 }
07953 
07954 /* Parse the Post-Handshake Authentication extension.
07955  * Only in ClientHello.
07956  *
07957  * ssl      The SSL/TLS object.
07958  * input    The extension data.
07959  * length   The length of the extension data.
07960  * msgType  The type of the message this extension is being parsed from.
07961  * returns 0 on success and other values indicate failure.
07962  */
07963 static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, byte* input, word16 length,
07964                                  byte msgType)
07965 {
07966     (void)input;
07967 
07968     if (msgType == client_hello) {
07969         /* Ensure extension is empty. */
07970         if (length != 0)
07971             return BUFFER_E;
07972 
07973         ssl->options.postHandshakeAuth = 1;
07974         return 0;
07975     }
07976 
07977     return SANITY_MSG_E;
07978 }
07979 
07980 /* Create a new Post-handshake authentication object in the extensions.
07981  *
07982  * ssl    The SSL/TLS object.
07983  * returns 0 on success and other values indicate failure.
07984  */
07985 static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
07986 {
07987     int   ret = 0;
07988     TLSX* extension;
07989 
07990     /* Find the PSK key exchange modes extension if it exists. */
07991     extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH);
07992     if (extension == NULL) {
07993         /* Push new Post-handshake Authentication extension. */
07994         ret = TLSX_Push(&ssl->extensions, TLSX_POST_HANDSHAKE_AUTH, NULL,
07995             ssl->heap);
07996         if (ret != 0)
07997             return ret;
07998     }
07999 
08000     return 0;
08001 }
08002 
08003 #define PHA_GET_SIZE  TLSX_PostHandAuth_GetSize
08004 #define PHA_WRITE     TLSX_PostHandAuth_Write
08005 #define PHA_PARSE     TLSX_PostHandAuth_Parse
08006 
08007 #else
08008 
08009 #define PHA_GET_SIZE(a)       0
08010 #define PHA_WRITE(a, b)       0
08011 #define PHA_PARSE(a, b, c, d) 0
08012 
08013 #endif
08014 
08015 /******************************************************************************/
08016 /* Early Data Indication                                                      */
08017 /******************************************************************************/
08018 
08019 #ifdef WOLFSSL_EARLY_DATA
08020 /* Get the size of the encoded Early Data Indication extension.
08021  * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
08022  *
08023  * msgType  The type of the message this extension is being written into.
08024  * returns the number of bytes of the encoded Early Data Indication extension.
08025  */
08026 static word16 TLSX_EarlyData_GetSize(byte msgType)
08027 {
08028     if (msgType == client_hello || msgType == encrypted_extensions)
08029         return 0;
08030     if (msgType == session_ticket)
08031         return OPAQUE32_LEN;
08032 
08033     return SANITY_MSG_E;
08034 }
08035 
08036 /* Writes the Early Data Indicator extension into the output buffer.
08037  * Assumes that the the output buffer is big enough to hold data.
08038  * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
08039  *
08040  * max      The maximum early data size.
08041  * output   The buffer to write into.
08042  * msgType  The type of the message this extension is being written into.
08043  * returns the number of bytes written into the buffer.
08044  */
08045 static word16 TLSX_EarlyData_Write(word32 max, byte* output, byte msgType)
08046 {
08047     if (msgType == client_hello || msgType == encrypted_extensions) {
08048         return 0;
08049     }
08050     if (msgType == session_ticket) {
08051         c32toa(max, output);
08052         return OPAQUE32_LEN;
08053     }
08054 
08055     return SANITY_MSG_E;
08056 }
08057 
08058 /* Parse the Early Data Indicator extension.
08059  * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
08060  *
08061  * ssl      The SSL/TLS object.
08062  * input    The extension data.
08063  * length   The length of the extension data.
08064  * msgType  The type of the message this extension is being parsed from.
08065  * returns 0 on success and other values indicate failure.
08066  */
08067 static int TLSX_EarlyData_Parse(WOLFSSL* ssl, byte* input, word16 length,
08068                                  byte msgType)
08069 {
08070     if (msgType == client_hello) {
08071         if (length != 0)
08072             return BUFFER_E;
08073 
08074         return TLSX_EarlyData_Use(ssl, 0);
08075     }
08076     if (msgType == encrypted_extensions) {
08077         if (length != 0)
08078             return BUFFER_E;
08079 
08080         /* Ensure the index of PSK identity chosen by server is 0.
08081          * Index is plus one to handle 'not set' value of 0.
08082          */
08083         if (ssl->options.pskIdIndex != 1)
08084             return PSK_KEY_ERROR;
08085 
08086         return TLSX_EarlyData_Use(ssl, 1);
08087     }
08088     if (msgType == session_ticket) {
08089         word32 max;
08090 
08091         if (length != OPAQUE32_LEN)
08092             return BUFFER_E;
08093         ato32(input, &max);
08094 
08095         ssl->session.maxEarlyDataSz = max;
08096         return 0;
08097     }
08098 
08099     return SANITY_MSG_E;
08100 }
08101 
08102 /* Use the data to create a new Early Data object in the extensions.
08103  *
08104  * ssl  The SSL/TLS object.
08105  * max  The maximum early data size.
08106  * returns 0 on success and other values indicate failure.
08107  */
08108 int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 max)
08109 {
08110     int   ret = 0;
08111     TLSX* extension;
08112 
08113     /* Find the early data extension if it exists. */
08114     extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
08115     if (extension == NULL) {
08116         /* Push new early data extension. */
08117         ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap);
08118         if (ret != 0)
08119             return ret;
08120 
08121         extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
08122         if (extension == NULL)
08123             return MEMORY_E;
08124     }
08125 
08126     extension->resp = 1;
08127     extension->val  = max;
08128 
08129     return 0;
08130 }
08131 
08132 #define EDI_GET_SIZE  TLSX_EarlyData_GetSize
08133 #define EDI_WRITE     TLSX_EarlyData_Write
08134 #define EDI_PARSE     TLSX_EarlyData_Parse
08135 
08136 #else
08137 
08138 #define EDI_GET_SIZE(a)       0
08139 #define EDI_WRITE(a, b, c)    0
08140 #define EDI_PARSE(a, b, c, d) 0
08141 
08142 #endif
08143 
08144 /******************************************************************************/
08145 /* TLS Extensions Framework                                                   */
08146 /******************************************************************************/
08147 
08148 /** Finds an extension in the provided list. */
08149 TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
08150 {
08151     TLSX* extension = list;
08152 
08153     while (extension && extension->type != type)
08154         extension = extension->next;
08155 
08156     return extension;
08157 }
08158 
08159 /** Remove an extension. */
08160 void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap)
08161 {
08162     TLSX* extension = *list;
08163     TLSX** next = list;
08164 
08165     while (extension && extension->type != type) {
08166         next = &extension->next;
08167         extension = extension->next;
08168     }
08169 
08170     if (extension) {
08171         *next = extension->next;
08172         extension->next = NULL;
08173         TLSX_FreeAll(extension, heap);
08174     }
08175 }
08176 
08177 /** Releases all extensions in the provided list. */
08178 void TLSX_FreeAll(TLSX* list, void* heap)
08179 {
08180     TLSX* extension;
08181 
08182     while ((extension = list)) {
08183         list = extension->next;
08184 
08185         switch (extension->type) {
08186 
08187             case TLSX_SERVER_NAME:
08188                 SNI_FREE_ALL((SNI*)extension->data, heap);
08189                 break;
08190 
08191             case TLSX_MAX_FRAGMENT_LENGTH:
08192                 MFL_FREE_ALL(extension->data, heap);
08193                 break;
08194 
08195             case TLSX_TRUNCATED_HMAC:
08196                 /* Nothing to do. */
08197                 break;
08198 
08199             case TLSX_SUPPORTED_GROUPS:
08200                 EC_FREE_ALL((SupportedCurve*)extension->data, heap);
08201                 break;
08202 
08203             case TLSX_EC_POINT_FORMATS:
08204                 PF_FREE_ALL((PointFormat*)extension->data, heap);
08205                 break;
08206 
08207             case TLSX_STATUS_REQUEST:
08208                 CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap);
08209                 break;
08210 
08211             case TLSX_STATUS_REQUEST_V2:
08212                 CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data,
08213                         heap);
08214                 break;
08215 
08216             case TLSX_RENEGOTIATION_INFO:
08217                 SCR_FREE_ALL(extension->data, heap);
08218                 break;
08219 
08220             case TLSX_SESSION_TICKET:
08221                 WOLF_STK_FREE(extension->data, heap);
08222                 break;
08223 
08224             case TLSX_QUANTUM_SAFE_HYBRID:
08225                 QSH_FREE_ALL((QSHScheme*)extension->data, heap);
08226                 break;
08227 
08228             case TLSX_APPLICATION_LAYER_PROTOCOL:
08229                 ALPN_FREE_ALL((ALPN*)extension->data, heap);
08230                 break;
08231 
08232             case TLSX_SIGNATURE_ALGORITHMS:
08233                 break;
08234 
08235 #ifdef WOLFSSL_TLS13
08236             case TLSX_SUPPORTED_VERSIONS:
08237                 break;
08238 
08239             case TLSX_COOKIE:
08240                 CKE_FREE_ALL((Cookie*)extension->data, heap);
08241                 break;
08242 
08243     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
08244             case TLSX_PRE_SHARED_KEY:
08245                 PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
08246                 break;
08247 
08248             case TLSX_PSK_KEY_EXCHANGE_MODES:
08249                 break;
08250     #endif
08251 
08252     #ifdef WOLFSSL_EARLY_DATA
08253             case TLSX_EARLY_DATA:
08254                 break;
08255     #endif
08256 
08257     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
08258             case TLSX_POST_HANDSHAKE_AUTH:
08259                 break;
08260     #endif
08261 
08262     #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
08263             case TLSX_SIGNATURE_ALGORITHMS_CERT:
08264                 break;
08265     #endif
08266 
08267             case TLSX_KEY_SHARE:
08268                 KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
08269                 break;
08270 #endif
08271         }
08272 
08273         XFREE(extension, heap, DYNAMIC_TYPE_TLSX);
08274     }
08275 
08276     (void)heap;
08277 }
08278 
08279 /** Checks if the tls extensions are supported based on the protocol version. */
08280 int TLSX_SupportExtensions(WOLFSSL* ssl) {
08281     return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
08282 }
08283 
08284 /** Tells the buffered size of the extensions in a list. */
08285 static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, word16* pLength)
08286 {
08287     int    ret = 0;
08288     TLSX*  extension;
08289     word16 length = 0;
08290     byte   isRequest = (msgType == client_hello ||
08291                         msgType == certificate_request);
08292 
08293     while ((extension = list)) {
08294         list = extension->next;
08295 
08296         /* only extensions marked as response are sent back to the client. */
08297         if (!isRequest && !extension->resp)
08298             continue; /* skip! */
08299 
08300         /* ssl level extensions are expected to override ctx level ones. */
08301         if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
08302             continue; /* skip! */
08303 
08304         /* extension type + extension data length. */
08305         length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
08306 
08307 
08308         switch (extension->type) {
08309 
08310             case TLSX_SERVER_NAME:
08311                 /* SNI only sends the name on the request. */
08312                 if (isRequest)
08313                     length += SNI_GET_SIZE((SNI*)extension->data);
08314                 break;
08315 
08316             case TLSX_MAX_FRAGMENT_LENGTH:
08317                 length += MFL_GET_SIZE(extension->data);
08318                 break;
08319 
08320             case TLSX_TRUNCATED_HMAC:
08321                 /* always empty. */
08322                 break;
08323 
08324             case TLSX_SUPPORTED_GROUPS:
08325                 length += EC_GET_SIZE((SupportedCurve*)extension->data);
08326                 break;
08327 
08328             case TLSX_EC_POINT_FORMATS:
08329                 length += PF_GET_SIZE((PointFormat*)extension->data);
08330                 break;
08331 
08332             case TLSX_STATUS_REQUEST:
08333                 length += CSR_GET_SIZE(
08334                          (CertificateStatusRequest*)extension->data, isRequest);
08335                 break;
08336 
08337             case TLSX_STATUS_REQUEST_V2:
08338                 length += CSR2_GET_SIZE(
08339                         (CertificateStatusRequestItemV2*)extension->data,
08340                         isRequest);
08341                 break;
08342 
08343             case TLSX_RENEGOTIATION_INFO:
08344                 length += SCR_GET_SIZE((SecureRenegotiation*)extension->data,
08345                         isRequest);
08346                 break;
08347 
08348             case TLSX_SESSION_TICKET:
08349                 length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data,
08350                         isRequest);
08351                 break;
08352 
08353             case TLSX_QUANTUM_SAFE_HYBRID:
08354                 length += QSH_GET_SIZE((QSHScheme*)extension->data, isRequest);
08355                 break;
08356 
08357             case TLSX_APPLICATION_LAYER_PROTOCOL:
08358                 length += ALPN_GET_SIZE((ALPN*)extension->data);
08359                 break;
08360 
08361             case TLSX_SIGNATURE_ALGORITHMS:
08362                 length += SA_GET_SIZE(extension->data);
08363                 break;
08364 
08365 #ifdef WOLFSSL_TLS13
08366             case TLSX_SUPPORTED_VERSIONS:
08367                 ret = SV_GET_SIZE(extension->data, msgType, &length);
08368                 break;
08369 
08370             case TLSX_COOKIE:
08371                 ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
08372                 break;
08373 
08374     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
08375             case TLSX_PRE_SHARED_KEY:
08376                 length += PSK_GET_SIZE((PreSharedKey*)extension->data, msgType);
08377                 break;
08378 
08379             case TLSX_PSK_KEY_EXCHANGE_MODES:
08380                 length += PKM_GET_SIZE(extension->val, msgType);
08381                 break;
08382     #endif
08383 
08384     #ifdef WOLFSSL_EARLY_DATA
08385             case TLSX_EARLY_DATA:
08386                 length += EDI_GET_SIZE(msgType);
08387                 break;
08388     #endif
08389 
08390     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
08391             case TLSX_POST_HANDSHAKE_AUTH:
08392                 length += PHA_GET_SIZE(msgType);
08393                 break;
08394     #endif
08395 
08396     #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
08397             case TLSX_SIGNATURE_ALGORITHMS_CERT:
08398                 length += SAC_GET_SIZE(extension->data);
08399                 break;
08400     #endif
08401 
08402             case TLSX_KEY_SHARE:
08403                 length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
08404                 break;
08405 #endif
08406         }
08407 
08408         /* marks the extension as processed so ctx level */
08409         /* extensions don't overlap with ssl level ones. */
08410         TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
08411     }
08412 
08413     *pLength += length;
08414 
08415     return ret;
08416 }
08417 
08418 /** Writes the extensions of a list in a buffer. */
08419 static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
08420                          byte msgType, word16* pOffset)
08421 {
08422     int    ret = 0;
08423     TLSX*  extension;
08424     word16 offset = 0;
08425     word16 length_offset = 0;
08426     byte   isRequest = (msgType == client_hello ||
08427                         msgType == certificate_request);
08428 
08429     while ((extension = list)) {
08430         list = extension->next;
08431 
08432         /* only extensions marked as response are written in a response. */
08433         if (!isRequest && !extension->resp)
08434             continue; /* skip! */
08435 
08436         /* ssl level extensions are expected to override ctx level ones. */
08437         if (!IS_OFF(semaphore, TLSX_ToSemaphore(extension->type)))
08438             continue; /* skip! */
08439 
08440         /* writes extension type. */
08441         c16toa(extension->type, output + offset);
08442         offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
08443         length_offset = offset;
08444 
08445         /* extension data should be written internally. */
08446         switch (extension->type) {
08447             case TLSX_SERVER_NAME:
08448                 if (isRequest) {
08449                     WOLFSSL_MSG("SNI extension to write");
08450                     offset += SNI_WRITE((SNI*)extension->data, output + offset);
08451                 }
08452                 break;
08453 
08454             case TLSX_MAX_FRAGMENT_LENGTH:
08455                 WOLFSSL_MSG("Max Fragment Length extension to write");
08456                 offset += MFL_WRITE((byte*)extension->data, output + offset);
08457                 break;
08458 
08459             case TLSX_TRUNCATED_HMAC:
08460                 WOLFSSL_MSG("Truncated HMAC extension to write");
08461                 /* always empty. */
08462                 break;
08463 
08464             case TLSX_SUPPORTED_GROUPS:
08465                 WOLFSSL_MSG("Supported Groups extension to write");
08466                 offset += EC_WRITE((SupportedCurve*)extension->data,
08467                                     output + offset);
08468                 break;
08469 
08470             case TLSX_EC_POINT_FORMATS:
08471                 WOLFSSL_MSG("Point Formats extension to write");
08472                 offset += PF_WRITE((PointFormat*)extension->data,
08473                                     output + offset);
08474                 break;
08475 
08476             case TLSX_STATUS_REQUEST:
08477                 WOLFSSL_MSG("Certificate Status Request extension to write");
08478                 offset += CSR_WRITE((CertificateStatusRequest*)extension->data,
08479                         output + offset, isRequest);
08480                 break;
08481 
08482             case TLSX_STATUS_REQUEST_V2:
08483                 WOLFSSL_MSG("Certificate Status Request v2 extension to write");
08484                 offset += CSR2_WRITE(
08485                         (CertificateStatusRequestItemV2*)extension->data,
08486                         output + offset, isRequest);
08487                 break;
08488 
08489             case TLSX_RENEGOTIATION_INFO:
08490                 WOLFSSL_MSG("Secure Renegotiation extension to write");
08491                 offset += SCR_WRITE((SecureRenegotiation*)extension->data,
08492                         output + offset, isRequest);
08493                 break;
08494 
08495             case TLSX_SESSION_TICKET:
08496                 WOLFSSL_MSG("Session Ticket extension to write");
08497                 offset += WOLF_STK_WRITE((SessionTicket*)extension->data,
08498                         output + offset, isRequest);
08499                 break;
08500 
08501             case TLSX_QUANTUM_SAFE_HYBRID:
08502                 WOLFSSL_MSG("Quantum-Safe-Hybrid extension to write");
08503                 if (isRequest) {
08504                     offset += QSH_WRITE((QSHScheme*)extension->data, output + offset);
08505                 }
08506                 offset += QSHPK_WRITE((QSHScheme*)extension->data, output + offset);
08507                 offset += QSH_SERREQ(output + offset, isRequest);
08508                 break;
08509 
08510             case TLSX_APPLICATION_LAYER_PROTOCOL:
08511                 WOLFSSL_MSG("ALPN extension to write");
08512                 offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
08513                 break;
08514 
08515             case TLSX_SIGNATURE_ALGORITHMS:
08516                 WOLFSSL_MSG("Signature Algorithms extension to write");
08517                 offset += SA_WRITE(extension->data, output + offset);
08518                 break;
08519 
08520 #ifdef WOLFSSL_TLS13
08521             case TLSX_SUPPORTED_VERSIONS:
08522                 WOLFSSL_MSG("Supported Versions extension to write");
08523                 ret = SV_WRITE(extension->data, output + offset, msgType, &offset);
08524                 break;
08525 
08526             case TLSX_COOKIE:
08527                 WOLFSSL_MSG("Cookie extension to write");
08528                 ret = CKE_WRITE((Cookie*)extension->data, output + offset,
08529                                 msgType, &offset);
08530                 break;
08531 
08532     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
08533             case TLSX_PRE_SHARED_KEY:
08534                 WOLFSSL_MSG("Pre-Shared Key extension to write");
08535                 offset += PSK_WRITE((PreSharedKey*)extension->data,
08536                                     output + offset, msgType);
08537                 break;
08538 
08539             case TLSX_PSK_KEY_EXCHANGE_MODES:
08540                 WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
08541                 offset += PKM_WRITE(extension->val, output + offset, msgType);
08542                 break;
08543     #endif
08544 
08545     #ifdef WOLFSSL_EARLY_DATA
08546             case TLSX_EARLY_DATA:
08547                 WOLFSSL_MSG("Early Data extension to write");
08548                 offset += EDI_WRITE(extension->val, output + offset, msgType);
08549                 break;
08550     #endif
08551 
08552     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
08553             case TLSX_POST_HANDSHAKE_AUTH:
08554                 WOLFSSL_MSG("Post-Handshake Authentication extension to write");
08555                 offset += PHA_WRITE(output + offset, msgType);
08556                 break;
08557     #endif
08558 
08559     #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
08560             case TLSX_SIGNATURE_ALGORITHMS_CERT:
08561                 WOLFSSL_MSG("Signature Algorithms extension to write");
08562                 offset += SAC_WRITE(extension->data, output + offset);
08563                 break;
08564     #endif
08565 
08566             case TLSX_KEY_SHARE:
08567                 WOLFSSL_MSG("Key Share extension to write");
08568                 offset += KS_WRITE((KeyShareEntry*)extension->data,
08569                                    output + offset, msgType);
08570                 break;
08571 #endif
08572         }
08573 
08574         /* writes extension data length. */
08575         c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
08576 
08577         /* marks the extension as processed so ctx level */
08578         /* extensions don't overlap with ssl level ones. */
08579         TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
08580     }
08581 
08582     *pOffset += offset;
08583 
08584     return ret;
08585 }
08586 
08587 
08588 #if defined(HAVE_NTRU) && defined(HAVE_QSH)
08589 
08590 static word32 GetEntropy(unsigned char* out, word32 num_bytes)
08591 {
08592     int ret = 0;
08593 
08594     if (gRng == NULL) {
08595         if ((gRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL,
08596                                                     DYNAMIC_TYPE_TLSX)) == NULL)
08597             return DRBG_OUT_OF_MEMORY;
08598         wc_InitRng(gRng);
08599     }
08600 
08601     if (gRngMutex == NULL) {
08602         if ((gRngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL,
08603                                                     DYNAMIC_TYPE_TLSX)) == NULL)
08604             return DRBG_OUT_OF_MEMORY;
08605         wc_InitMutex(gRngMutex);
08606     }
08607 
08608     ret |= wc_LockMutex(gRngMutex);
08609     ret |= wc_RNG_GenerateBlock(gRng, out, num_bytes);
08610     ret |= wc_UnLockMutex(gRngMutex);
08611 
08612     if (ret != 0)
08613         return DRBG_ENTROPY_FAIL;
08614 
08615     return DRBG_OK;
08616 }
08617 #endif
08618 
08619 
08620 #ifdef HAVE_QSH
08621 static int TLSX_CreateQSHKey(WOLFSSL* ssl, int type)
08622 {
08623     int ret;
08624 
08625     (void)ssl;
08626 
08627     switch (type) {
08628 #ifdef HAVE_NTRU
08629         case WOLFSSL_NTRU_EESS439:
08630         case WOLFSSL_NTRU_EESS593:
08631         case WOLFSSL_NTRU_EESS743:
08632             ret = TLSX_CreateNtruKey(ssl, type);
08633             break;
08634 #endif
08635         default:
08636             WOLFSSL_MSG("Unknown type for creating NTRU key");
08637             return -1;
08638     }
08639 
08640     return ret;
08641 }
08642 
08643 
08644 static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key)
08645 {
08646     QSHKey* current;
08647 
08648     if (key == NULL)
08649         return BAD_FUNC_ARG;
08650 
08651     /* if no public key stored in key then do not add */
08652     if (key->pub.length == 0 || key->pub.buffer == NULL)
08653         return 0;
08654 
08655     /* first element to be added to the list */
08656     current = *list;
08657     if (current == NULL) {
08658         *list = key;
08659         return 0;
08660     }
08661 
08662     while (current->next) {
08663         /* can only have one of the key in the list */
08664         if (current->name == key->name)
08665             return -1;
08666         current = (QSHKey*)current->next;
08667     }
08668 
08669     current->next = (struct QSHKey*)key;
08670 
08671     return 0;
08672 }
08673 
08674 
08675 #if defined(HAVE_NTRU)
08676 int TLSX_CreateNtruKey(WOLFSSL* ssl, int type)
08677 {
08678     int ret = -1;
08679     int ntruType;
08680 
08681     /* variable declarations for NTRU*/
08682     QSHKey* temp = NULL;
08683     byte   public_key[1027];
08684     word16 public_key_len = sizeof(public_key);
08685     byte   private_key[1120];
08686     word16 private_key_len = sizeof(private_key);
08687     DRBG_HANDLE drbg;
08688 
08689     if (ssl == NULL)
08690         return BAD_FUNC_ARG;
08691 
08692     switch (type) {
08693         case WOLFSSL_NTRU_EESS439:
08694             ntruType = NTRU_EES439EP1;
08695             break;
08696         case WOLFSSL_NTRU_EESS593:
08697             ntruType = NTRU_EES593EP1;
08698             break;
08699         case WOLFSSL_NTRU_EESS743:
08700             ntruType = NTRU_EES743EP1;
08701             break;
08702         default:
08703             WOLFSSL_MSG("Unknown type for creating NTRU key");
08704             return -1;
08705     }
08706     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
08707     if (ret != DRBG_OK) {
08708         WOLFSSL_MSG("NTRU drbg instantiate failed\n");
08709         return ret;
08710     }
08711 
08712     if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
08713                      &public_key_len, NULL, &private_key_len, NULL)) != NTRU_OK)
08714         return ret;
08715 
08716     if ((ret = ntru_crypto_ntru_encrypt_keygen(drbg, ntruType,
08717         &public_key_len, public_key, &private_key_len, private_key)) != NTRU_OK)
08718         return ret;
08719 
08720     ret = ntru_crypto_drbg_uninstantiate(drbg);
08721     if (ret != NTRU_OK) {
08722         WOLFSSL_MSG("NTRU drbg uninstantiate failed\n");
08723         return ret;
08724     }
08725 
08726     if ((temp = (QSHKey*)XMALLOC(sizeof(QSHKey), ssl->heap,
08727                                                     DYNAMIC_TYPE_TLSX)) == NULL)
08728         return MEMORY_E;
08729     temp->name = type;
08730     temp->pub.length = public_key_len;
08731     temp->pub.buffer = (byte*)XMALLOC(public_key_len, ssl->heap,
08732                                 DYNAMIC_TYPE_PUBLIC_KEY);
08733     XMEMCPY(temp->pub.buffer, public_key, public_key_len);
08734     temp->pri.length = private_key_len;
08735     temp->pri.buffer = (byte*)XMALLOC(private_key_len, ssl->heap,
08736                                 DYNAMIC_TYPE_ARRAYS);
08737     XMEMCPY(temp->pri.buffer, private_key, private_key_len);
08738     temp->next = NULL;
08739 
08740     TLSX_AddQSHKey(&ssl->QSH_Key, temp);
08741 
08742     (void)ssl;
08743     (void)type;
08744 
08745     return ret;
08746 }
08747 #endif
08748 
08749 
08750 /*
08751     Used to find a public key from the list of keys
08752     pubLen length of array
08753     name   input the name of the scheme looking for ie WOLFSSL_NTRU_ESSXXX
08754 
08755     returns a pointer to public key byte* or NULL if not found
08756  */
08757 static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name)
08758 {
08759     QSHKey* current = qsh;
08760 
08761     if (qsh == NULL || pubLen == NULL)
08762         return NULL;
08763 
08764     *pubLen = 0;
08765 
08766     while(current) {
08767         if (current->name == name) {
08768             *pubLen = current->pub.length;
08769             return current->pub.buffer;
08770         }
08771         current = (QSHKey*)current->next;
08772     }
08773 
08774     return NULL;
08775 }
08776 #endif /* HAVE_QSH */
08777 
08778 #if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
08779         !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
08780     (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \
08781         !defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \
08782     ((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
08783         defined(HAVE_SUPPORTED_CURVES))
08784 
08785 static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
08786 {
08787     int ret = WOLFSSL_SUCCESS;
08788 #ifdef WOLFSSL_TLS13
08789     int i;
08790 
08791 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
08792     if (ssl->options.resuming && ssl->session.namedGroup != 0) {
08793         return TLSX_UseSupportedCurve(extensions, ssl->session.namedGroup,
08794                                                                      ssl->heap);
08795     }
08796 #endif
08797 
08798     if (ssl->numGroups != 0) {
08799         for (i = 0; i < ssl->numGroups; i++) {
08800             ret = TLSX_UseSupportedCurve(extensions, ssl->group[i], ssl->heap);
08801             if (ret != WOLFSSL_SUCCESS)
08802                 return ret;
08803         }
08804         return WOLFSSL_SUCCESS;
08805     }
08806 #endif /* WOLFSSL_TLS13 */
08807 
08808 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
08809     #ifndef HAVE_FIPS
08810         #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
08811             #ifndef NO_ECC_SECP
08812                 ret = TLSX_UseSupportedCurve(extensions,
08813                                               WOLFSSL_ECC_SECP160R1, ssl->heap);
08814                 if (ret != WOLFSSL_SUCCESS) return ret;
08815             #endif
08816             #ifdef HAVE_ECC_SECPR2
08817                 ret = TLSX_UseSupportedCurve(extensions,
08818                                               WOLFSSL_ECC_SECP160R2, ssl->heap);
08819                 if (ret != WOLFSSL_SUCCESS) return ret;
08820             #endif
08821             #ifdef HAVE_ECC_KOBLITZ
08822                 ret = TLSX_UseSupportedCurve(extensions,
08823                                               WOLFSSL_ECC_SECP160K1, ssl->heap);
08824                 if (ret != WOLFSSL_SUCCESS) return ret;
08825             #endif
08826         #endif
08827         #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
08828             #ifndef NO_ECC_SECP
08829                 ret = TLSX_UseSupportedCurve(extensions,
08830                                               WOLFSSL_ECC_SECP192R1, ssl->heap);
08831                 if (ret != WOLFSSL_SUCCESS) return ret;
08832             #endif
08833             #ifdef HAVE_ECC_KOBLITZ
08834                 ret = TLSX_UseSupportedCurve(extensions,
08835                                               WOLFSSL_ECC_SECP192K1, ssl->heap);
08836                 if (ret != WOLFSSL_SUCCESS) return ret;
08837             #endif
08838         #endif
08839     #endif
08840         #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
08841             #ifndef NO_ECC_SECP
08842                 ret = TLSX_UseSupportedCurve(extensions,
08843                                               WOLFSSL_ECC_SECP224R1, ssl->heap);
08844                 if (ret != WOLFSSL_SUCCESS) return ret;
08845             #endif
08846             #ifdef HAVE_ECC_KOBLITZ
08847                 ret = TLSX_UseSupportedCurve(extensions,
08848                                               WOLFSSL_ECC_SECP224K1, ssl->heap);
08849                 if (ret != WOLFSSL_SUCCESS) return ret;
08850             #endif
08851         #endif
08852         #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
08853             #ifndef NO_ECC_SECP
08854                 ret = TLSX_UseSupportedCurve(extensions,
08855                                               WOLFSSL_ECC_SECP256R1, ssl->heap);
08856                 if (ret != WOLFSSL_SUCCESS) return ret;
08857             #endif
08858         #endif
08859 #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
08860 
08861         #ifndef HAVE_FIPS
08862             #if defined(HAVE_CURVE25519)
08863                 ret = TLSX_UseSupportedCurve(extensions,
08864                                                  WOLFSSL_ECC_X25519, ssl->heap);
08865                 if (ret != WOLFSSL_SUCCESS) return ret;
08866             #endif
08867         #endif /* HAVE_FIPS */
08868 
08869 #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
08870         #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
08871             #ifdef HAVE_ECC_KOBLITZ
08872                 ret = TLSX_UseSupportedCurve(extensions,
08873                                               WOLFSSL_ECC_SECP256K1, ssl->heap);
08874                 if (ret != WOLFSSL_SUCCESS) return ret;
08875             #endif
08876             #ifdef HAVE_ECC_BRAINPOOL
08877                 ret = TLSX_UseSupportedCurve(extensions,
08878                                         WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap);
08879                 if (ret != WOLFSSL_SUCCESS) return ret;
08880             #endif
08881         #endif
08882         #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
08883             #ifndef NO_ECC_SECP
08884                 ret = TLSX_UseSupportedCurve(extensions,
08885                                               WOLFSSL_ECC_SECP384R1, ssl->heap);
08886                 if (ret != WOLFSSL_SUCCESS) return ret;
08887             #endif
08888             #ifdef HAVE_ECC_BRAINPOOL
08889                 ret = TLSX_UseSupportedCurve(extensions,
08890                                         WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap);
08891                 if (ret != WOLFSSL_SUCCESS) return ret;
08892             #endif
08893         #endif
08894         #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
08895             #ifdef HAVE_ECC_BRAINPOOL
08896                 ret = TLSX_UseSupportedCurve(extensions,
08897                                         WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap);
08898                 if (ret != WOLFSSL_SUCCESS) return ret;
08899             #endif
08900         #endif
08901         #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
08902             #ifndef NO_ECC_SECP
08903                 ret = TLSX_UseSupportedCurve(extensions,
08904                                               WOLFSSL_ECC_SECP521R1, ssl->heap);
08905                 if (ret != WOLFSSL_SUCCESS) return ret;
08906             #endif
08907         #endif
08908 #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
08909 
08910     #ifdef WOLFSSL_TLS13
08911         if (IsAtLeastTLSv1_3(ssl->version)) {
08912                 /* Add FFDHE supported groups. */
08913         #ifdef HAVE_FFDHE_2048
08914                 ret = TLSX_UseSupportedCurve(extensions,
08915                                              WOLFSSL_FFDHE_2048, ssl->heap);
08916                 if (ret != WOLFSSL_SUCCESS)
08917                     return ret;
08918         #endif
08919         #ifdef HAVE_FFDHE_3072
08920                 ret = TLSX_UseSupportedCurve(extensions,
08921                                              WOLFSSL_FFDHE_3072, ssl->heap);
08922                 if (ret != WOLFSSL_SUCCESS)
08923                     return ret;
08924         #endif
08925         #ifdef HAVE_FFDHE_4096
08926                 ret = TLSX_UseSupportedCurve(extensions,
08927                                              WOLFSSL_FFDHE_4096, ssl->heap);
08928                 if (ret != WOLFSSL_SUCCESS)
08929                     return ret;
08930         #endif
08931         #ifdef HAVE_FFDHE_6144
08932                 ret = TLSX_UseSupportedCurve(extensions,
08933                                              WOLFSSL_FFDHE_6144, ssl->heap);
08934                 if (ret != WOLFSSL_SUCCESS)
08935                     return ret;
08936         #endif
08937         #ifdef HAVE_FFDHE_8192
08938                 ret = TLSX_UseSupportedCurve(extensions,
08939                                              WOLFSSL_FFDHE_8192, ssl->heap);
08940                 if (ret != WOLFSSL_SUCCESS)
08941                     return ret;
08942         #endif
08943         }
08944     #endif /* WOLFSSL_TLS13 */
08945 
08946     (void)ssl;
08947     (void)extensions;
08948 
08949     return ret;
08950 }
08951 
08952 #endif
08953 
08954 int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
08955 {
08956     int ret = 0;
08957     byte* public_key      = NULL;
08958     word16 public_key_len = 0;
08959 #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
08960     int usingPSK = 0;
08961 #endif
08962 #ifdef HAVE_QSH
08963     TLSX* extension;
08964     QSHScheme* qsh;
08965     QSHScheme* next;
08966 
08967     /* add supported QSHSchemes */
08968     WOLFSSL_MSG("Adding supported QSH Schemes");
08969 #endif
08970 
08971     /* server will add extension depending on whats parsed from client */
08972     if (!isServer) {
08973 #ifdef HAVE_QSH
08974         /* test if user has set a specific scheme already */
08975         if (!ssl->user_set_QSHSchemes) {
08976             if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
08977                 if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) {
08978                     WOLFSSL_MSG("Error creating ntru keys");
08979                     return ret;
08980                 }
08981                 if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) {
08982                     WOLFSSL_MSG("Error creating ntru keys");
08983                     return ret;
08984                 }
08985                 if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) {
08986                     WOLFSSL_MSG("Error creating ntru keys");
08987                     return ret;
08988                 }
08989 
08990             /* add NTRU 256 */
08991             public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
08992                     &public_key_len, WOLFSSL_NTRU_EESS743);
08993             }
08994             if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743,
08995                                   public_key, public_key_len, ssl->heap)
08996                                   != WOLFSSL_SUCCESS)
08997                 ret = -1;
08998 
08999             /* add NTRU 196 */
09000             if (ssl->sendQSHKeys) {
09001                 public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
09002                     &public_key_len, WOLFSSL_NTRU_EESS593);
09003             }
09004             if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593,
09005                                   public_key, public_key_len, ssl->heap)
09006                                   != WOLFSSL_SUCCESS)
09007                 ret = -1;
09008 
09009             /* add NTRU 128 */
09010             if (ssl->sendQSHKeys) {
09011                 public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
09012                     &public_key_len, WOLFSSL_NTRU_EESS439);
09013             }
09014             if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439,
09015                                   public_key, public_key_len, ssl->heap)
09016                                   != WOLFSSL_SUCCESS)
09017                 ret = -1;
09018         }
09019         else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) {
09020             /* for each scheme make a client key */
09021             extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
09022             if (extension) {
09023                 qsh = (QSHScheme*)extension->data;
09024 
09025                 while (qsh) {
09026                     if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0)
09027                         return ret;
09028 
09029                     /* get next now because qsh could be freed */
09030                     next = qsh->next;
09031 
09032                     /* find the public key created and add to extension*/
09033                     public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key,
09034                              &public_key_len, qsh->name);
09035                     if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name,
09036                                           public_key, public_key_len,
09037                                           ssl->heap) != WOLFSSL_SUCCESS)
09038                         ret = -1;
09039                     qsh = next;
09040                 }
09041             }
09042         }
09043 #endif
09044 
09045 #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
09046                                                   defined(HAVE_SUPPORTED_CURVES)
09047         if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
09048             if (TLSX_Find(ssl->ctx->extensions,
09049                                                TLSX_SUPPORTED_GROUPS) == NULL) {
09050                 ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
09051                 if (ret != WOLFSSL_SUCCESS)
09052                     return ret;
09053                 if (!IsAtLeastTLSv1_3(ssl->version) &&
09054                         TLSX_Find(ssl->ctx->extensions,
09055                                                TLSX_EC_POINT_FORMATS) == NULL &&
09056                         TLSX_Find(ssl->extensions,
09057                                                TLSX_EC_POINT_FORMATS) == NULL) {
09058                     ret = TLSX_UsePointFormat(&ssl->extensions,
09059                                                      WOLFSSL_EC_PF_UNCOMPRESSED,
09060                                                      ssl->heap);
09061                     if (ret != WOLFSSL_SUCCESS)
09062                         return ret;
09063                 }
09064             }
09065             else if (!IsAtLeastTLSv1_3(ssl->version) &&
09066                      TLSX_Find(ssl->ctx->extensions,
09067                                                TLSX_EC_POINT_FORMATS) == NULL) {
09068                 ret = TLSX_UsePointFormat(&ssl->ctx->extensions,
09069                                                      WOLFSSL_EC_PF_UNCOMPRESSED,
09070                                                      ssl->heap);
09071                 if (ret != WOLFSSL_SUCCESS)
09072                     return ret;
09073             }
09074         }
09075 #endif /* (HAVE_ECC || HAVE_CURVE25519) && HAVE_SUPPORTED_CURVES */
09076     } /* is not server */
09077 
09078     WOLFSSL_MSG("Adding signature algorithms extension");
09079     if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap))
09080                                                                          != 0) {
09081             return ret;
09082     }
09083 
09084     #ifdef WOLFSSL_TLS13
09085         if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
09086             /* Add mandatory TLS v1.3 extension: supported version */
09087             WOLFSSL_MSG("Adding supported versions extension");
09088             if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl,
09089                                                              ssl->heap)) != 0) {
09090                 return ret;
09091             }
09092 
09093     #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \
09094                                                   defined(HAVE_SUPPORTED_CURVES)
09095         if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) {
09096             /* Put in DH groups for TLS 1.3 only. */
09097             ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
09098             if (ret != WOLFSSL_SUCCESS)
09099                 return ret;
09100             ret = 0;
09101         }
09102     #endif /* !HAVE_ECC && !HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */
09103 
09104         #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
09105             if (ssl->certHashSigAlgoSz > 0) {
09106                 WOLFSSL_MSG("Adding signature algorithms cert extension");
09107                 if ((ret = TLSX_SetSignatureAlgorithmsCert(&ssl->extensions,
09108                                                         ssl, ssl->heap)) != 0) {
09109                     return ret;
09110                 }
09111             }
09112         #endif /* !WOLFSSL_TLS13_DRAFT_18 && !WOLFSSL_TLS13_DRAFT_22 */
09113 
09114             if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
09115                 word16 namedGroup;
09116 
09117         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09118                 if (ssl->options.resuming && ssl->session.namedGroup != 0)
09119                     namedGroup = ssl->session.namedGroup;
09120                 else
09121         #endif
09122                 {
09123         #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
09124                               defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
09125                     namedGroup = WOLFSSL_ECC_SECP256R1;
09126         #elif defined(HAVE_CURVE25519)
09127                     namedGroup = WOLFSSL_ECC_X25519;
09128         #elif defined(HAVE_ECC) && (!defined(NO_ECC384) || \
09129                               defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
09130                     namedGroup = WOLFSSL_ECC_SECP384R1;
09131         #elif defined(HAVE_ECC) && (!defined(NO_ECC521) || \
09132                               defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
09133                     namedGroup = WOLFSSL_ECC_SECP521R1;
09134         #elif defined(HAVE_FFDHE_2048)
09135                     namedGroup = WOLFSSL_FFDHE_2048;
09136         #elif defined(HAVE_FFDHE_3072)
09137                     namedGroup = WOLFSSL_FFDHE_3072;
09138         #elif defined(HAVE_FFDHE_4096)
09139                     namedGroup = WOLFSSL_FFDHE_4096;
09140         #elif defined(HAVE_FFDHE_6144)
09141                     namedGroup = WOLFSSL_FFDHE_6144;
09142         #elif defined(HAVE_FFDHE_8192)
09143                     namedGroup = WOLFSSL_FFDHE_8192;
09144         #else
09145                     return KEY_SHARE_ERROR;
09146         #endif
09147                 }
09148                 ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
09149                 if (ret != 0)
09150                     return ret;
09151             }
09152 
09153         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09154             TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
09155         #endif
09156         #if defined(HAVE_SESSION_TICKET)
09157             if (ssl->options.resuming && ssl->session.ticketLen > 0) {
09158                 WOLFSSL_SESSION* sess = &ssl->session;
09159                 word32           milli;
09160 
09161                 /* Determine the MAC algorithm for the cipher suite used. */
09162                 ssl->options.cipherSuite0 = sess->cipherSuite0;
09163                 ssl->options.cipherSuite  = sess->cipherSuite;
09164                 ret = SetCipherSpecs(ssl);
09165                 if (ret != 0)
09166                     return ret;
09167                 milli = TimeNowInMilliseconds() - sess->ticketSeen +
09168                         sess->ticketAdd;
09169                 /* Pre-shared key is mandatory extension for resumption. */
09170                 ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen,
09171                                             milli, ssl->specs.mac_algorithm,
09172                                             ssl->options.cipherSuite0,
09173                                             ssl->options.cipherSuite, 1,
09174                                             NULL);
09175                 if (ret != 0)
09176                     return ret;
09177 
09178                 usingPSK = 1;
09179             }
09180         #endif
09181         #ifndef NO_PSK
09182             if (ssl->options.client_psk_cb != NULL) {
09183                 /* Default ciphersuite. */
09184                 byte cipherSuite0 = TLS13_BYTE;
09185                 byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
09186 
09187                 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
09188                         ssl->arrays->server_hint, ssl->arrays->client_identity,
09189                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
09190                 if (ssl->arrays->psk_keySz == 0 ||
09191                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
09192                     return PSK_KEY_ERROR;
09193                 }
09194                 ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
09195                 /* TODO: Callback should be able to change ciphersuite. */
09196                 ssl->options.cipherSuite0 = cipherSuite0;
09197                 ssl->options.cipherSuite  = cipherSuite;
09198                 ret = SetCipherSpecs(ssl);
09199                 if (ret != 0)
09200                     return ret;
09201 
09202                 ret = TLSX_PreSharedKey_Use(ssl,
09203                                   (byte*)ssl->arrays->client_identity,
09204                                   (word16)XSTRLEN(ssl->arrays->client_identity),
09205                                   0, ssl->specs.mac_algorithm,
09206                                   cipherSuite0, cipherSuite, 0,
09207                                   NULL);
09208                 if (ret != 0)
09209                     return ret;
09210 
09211                 usingPSK = 1;
09212             }
09213         #endif
09214         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09215             if (usingPSK) {
09216                 byte modes;
09217 
09218                 /* Pre-shared key modes: mandatory extension for resumption. */
09219                 modes = 1 << PSK_KE;
09220             #if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519)
09221                 if (!ssl->options.noPskDheKe)
09222                     modes |= 1 << PSK_DHE_KE;
09223             #endif
09224                 ret = TLSX_PskKeModes_Use(ssl, modes);
09225                 if (ret != 0)
09226                     return ret;
09227             }
09228         #endif
09229         #if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
09230             if (!isServer && ssl->options.postHandshakeAuth) {
09231                 ret = TLSX_PostHandAuth_Use(ssl);
09232                 if (ret != 0)
09233                     return ret;
09234             }
09235         #endif
09236         }
09237 
09238     #endif
09239 
09240     (void)isServer;
09241     (void)public_key;
09242     (void)public_key_len;
09243     (void)ssl;
09244 
09245     return ret;
09246 }
09247 
09248 
09249 #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
09250 
09251 /** Tells the buffered size of extensions to be sent into the client hello. */
09252 int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength)
09253 {
09254     int ret = 0;
09255     word16 length = 0;
09256     byte semaphore[SEMAPHORE_SIZE] = {0};
09257 
09258     if (!TLSX_SupportExtensions(ssl))
09259         return 0;
09260     if (msgType == client_hello) {
09261         EC_VALIDATE_REQUEST(ssl, semaphore);
09262         PF_VALIDATE_REQUEST(ssl, semaphore);
09263         QSH_VALIDATE_REQUEST(ssl, semaphore);
09264         WOLF_STK_VALIDATE_REQUEST(ssl);
09265         if (ssl->suites->hashSigAlgoSz == 0)
09266             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
09267 #if defined(WOLFSSL_TLS13)
09268         if (!IsAtLeastTLSv1_2(ssl))
09269             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09270         if (!IsAtLeastTLSv1_3(ssl->version)) {
09271             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09272     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09273             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09274             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
09275     #endif
09276     #ifdef WOLFSSL_EARLY_DATA
09277             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
09278     #endif
09279             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
09280     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
09281             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
09282     #endif
09283         }
09284     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09285         if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.noPskDheKe) {
09286         #if !defined(NO_PSK)
09287             if (ssl->options.havePSK)
09288                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09289         #endif
09290         #if defined(HAVE_SESSION_TICKET)
09291             if (ssl->options.resuming)
09292                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09293         #endif
09294         }
09295     #endif
09296 #endif
09297     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
09298      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
09299         if (!ssl->ctx->cm->ocspStaplingEnabled) {
09300             /* mark already sent, so it won't send it */
09301             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09302             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
09303         }
09304     #endif
09305     }
09306 #ifdef WOLFSSL_TLS13
09307     #ifndef NO_CERTS
09308     else if (msgType == certificate_request) {
09309         XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09310         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
09311         /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
09312          *       TLSX_CERTIFICATE_AUTHORITIES, OID_FILTERS
09313          *       TLSX_STATUS_REQUEST
09314          */
09315     }
09316     #endif
09317 #endif
09318 
09319     if (ssl->extensions)
09320         ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
09321     if (ssl->ctx && ssl->ctx->extensions)
09322         ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType, &length);
09323 
09324 #ifdef HAVE_EXTENDED_MASTER
09325     if (msgType == client_hello && ssl->options.haveEMS &&
09326                                               !IsAtLeastTLSv1_3(ssl->version)) {
09327         length += HELLO_EXT_SZ;
09328     }
09329 #endif
09330 
09331     if (length)
09332         length += OPAQUE16_LEN; /* for total length storage. */
09333 
09334     *pLength += length;
09335 
09336     return ret;
09337 }
09338 
09339 /** Writes the extensions to be sent into the client hello. */
09340 int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset)
09341 {
09342     int ret = 0;
09343     word16 offset = 0;
09344     byte semaphore[SEMAPHORE_SIZE] = {0};
09345 
09346     if (!TLSX_SupportExtensions(ssl) || output == NULL)
09347         return 0;
09348 
09349     offset += OPAQUE16_LEN; /* extensions length */
09350 
09351     if (msgType == client_hello) {
09352         EC_VALIDATE_REQUEST(ssl, semaphore);
09353         PF_VALIDATE_REQUEST(ssl, semaphore);
09354         WOLF_STK_VALIDATE_REQUEST(ssl);
09355         QSH_VALIDATE_REQUEST(ssl, semaphore);
09356         if (ssl->suites->hashSigAlgoSz == 0)
09357             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
09358 #ifdef WOLFSSL_TLS13
09359         if (!IsAtLeastTLSv1_2(ssl))
09360             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09361         if (!IsAtLeastTLSv1_3(ssl->version)) {
09362             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09363     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09364             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
09365     #endif
09366     #ifdef WOLFSSL_EARLY_DATA
09367             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
09368     #endif
09369             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
09370     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
09371             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
09372     #endif
09373         }
09374     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09375         if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.noPskDheKe) {
09376         #if !defined(NO_PSK)
09377             if (ssl->options.havePSK)
09378                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09379         #endif
09380         #if defined(HAVE_SESSION_TICKET)
09381             if (ssl->options.resuming)
09382                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09383         #endif
09384         }
09385     #endif
09386     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09387         /* Must write Pre-shared Key extension at the end in TLS v1.3.
09388          * Must not write out Pre-shared Key extension in earlier versions of
09389          * protocol.
09390          */
09391         TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09392     #endif
09393 #endif
09394     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
09395      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
09396          /* mark already sent, so it won't send it */
09397         if (!ssl->ctx->cm->ocspStaplingEnabled) {
09398             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09399             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
09400         }
09401     #endif
09402     }
09403 #ifdef WOLFSSL_TLS13
09404     #ifndef NO_CERT
09405     else if (msgType == certificate_request) {
09406         XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09407         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
09408         /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
09409          *       TLSX_CERTIFICATE_AUTHORITIES, TLSX_OID_FILTERS
09410          *       TLSX_STATUS_REQUEST
09411          */
09412     }
09413     #endif
09414 #endif
09415 
09416     if (ssl->extensions) {
09417         ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
09418                          msgType, &offset);
09419     }
09420     if (ssl->ctx && ssl->ctx->extensions) {
09421         ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore,
09422                          msgType, &offset);
09423     }
09424 
09425 #ifdef HAVE_EXTENDED_MASTER
09426     if (msgType == client_hello && ssl->options.haveEMS &&
09427                                               !IsAtLeastTLSv1_3(ssl->version)) {
09428         c16toa(HELLO_EXT_EXTMS, output + offset);
09429         offset += HELLO_EXT_TYPE_SZ;
09430         c16toa(0, output + offset);
09431         offset += HELLO_EXT_SZ_SZ;
09432     }
09433 #endif
09434 
09435 #ifdef WOLFSSL_TLS13
09436     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09437     if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) {
09438         /* Write out what we can of Pre-shared key extension.  */
09439         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09440         ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
09441                          client_hello, &offset);
09442     }
09443     #endif
09444 #endif
09445 
09446     if (offset > OPAQUE16_LEN || msgType != client_hello)
09447         c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
09448 
09449      *pOffset += offset;
09450 
09451     return ret;
09452 }
09453 
09454 #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
09455 
09456 #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER)
09457 
09458 /** Tells the buffered size of extensions to be sent into the server hello. */
09459 int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
09460 {
09461     int ret = 0;
09462     word16 length = 0;
09463     byte semaphore[SEMAPHORE_SIZE] = {0};
09464 
09465     switch (msgType) {
09466 #ifndef NO_WOLFSSL_SERVER
09467         case server_hello:
09468             PF_VALIDATE_RESPONSE(ssl, semaphore);
09469     #ifdef WOLFSSL_TLS13
09470                 if (ssl->options.tls1_3) {
09471                     XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09472         #ifndef WOLFSSL_TLS13_DRAFT_18
09473                     TURN_OFF(semaphore,
09474                                      TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09475         #endif
09476                     if (!ssl->options.noPskDheKe)
09477                         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09478         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09479                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09480         #endif
09481                 }
09482                 else {
09483                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09484         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09485                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09486         #endif
09487                 }
09488     #endif
09489             break;
09490 
09491     #ifdef WOLFSSL_TLS13
09492         case hello_retry_request:
09493             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09494         #ifndef WOLFSSL_TLS13_DRAFT_18
09495                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09496         #endif
09497             if (!ssl->options.noPskDheKe)
09498                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09499             TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
09500             break;
09501     #endif
09502 
09503     #ifdef WOLFSSL_TLS13
09504         case encrypted_extensions:
09505             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
09506             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09507             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
09508             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09509         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09510             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09511         #endif
09512         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
09513             TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09514         #endif
09515             break;
09516 
09517         #ifdef WOLFSSL_EARLY_DATA
09518         case session_ticket:
09519             if (ssl->options.tls1_3) {
09520                 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09521                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
09522             }
09523             break;
09524         #endif
09525     #endif
09526 #endif
09527 
09528 #ifdef WOLFSSL_TLS13
09529     #ifndef NO_CERT
09530         case certificate:
09531             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09532             TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09533             /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
09534              *       TLSX_SERVER_CERTIFICATE_TYPE
09535              */
09536             break;
09537     #endif
09538 #endif
09539     }
09540 
09541     #ifdef HAVE_QSH
09542         /* change response if not using TLS_QSH */
09543         if (!ssl->options.haveQSH) {
09544             TLSX* ext = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID);
09545             if (ext)
09546                 ext->resp = 0;
09547         }
09548     #endif
09549 
09550 #ifdef HAVE_EXTENDED_MASTER
09551     if (ssl->options.haveEMS && msgType == server_hello)
09552         length += HELLO_EXT_SZ;
09553 #endif
09554 
09555     if (TLSX_SupportExtensions(ssl))
09556         ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
09557 
09558     /* All the response data is set at the ssl object only, so no ctx here. */
09559 
09560     if (length || msgType != server_hello)
09561         length += OPAQUE16_LEN; /* for total length storage. */
09562 
09563     *pLength += length;
09564 
09565     return ret;
09566 }
09567 
09568 /** Writes the server hello extensions into a buffer. */
09569 int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset)
09570 {
09571     int ret = 0;
09572     word16 offset = 0;
09573 
09574     if (TLSX_SupportExtensions(ssl) && output) {
09575         byte semaphore[SEMAPHORE_SIZE] = {0};
09576 
09577         switch (msgType) {
09578 #ifndef NO_WOLFSSL_SERVER
09579             case server_hello:
09580                 PF_VALIDATE_RESPONSE(ssl, semaphore);
09581     #ifdef WOLFSSL_TLS13
09582                 if (ssl->options.tls1_3) {
09583                     XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09584         #ifndef WOLFSSL_TLS13_DRAFT_18
09585                     TURN_OFF(semaphore,
09586                                      TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09587         #endif
09588                     if (!ssl->options.noPskDheKe)
09589                         TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09590         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09591                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09592         #endif
09593                 }
09594                 else {
09595                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09596         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09597                     TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09598         #endif
09599                 }
09600     #endif
09601                 break;
09602 
09603     #ifdef WOLFSSL_TLS13
09604             case hello_retry_request:
09605                 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09606         #ifndef WOLFSSL_TLS13_DRAFT_18
09607                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09608         #endif
09609                 if (!ssl->options.noPskDheKe)
09610                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09611                 /* Cookie is written below as last extension. */
09612                 break;
09613     #endif
09614 
09615     #ifdef WOLFSSL_TLS13
09616             case encrypted_extensions:
09617                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
09618                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
09619                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
09620                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
09621         #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09622                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
09623         #endif
09624         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
09625                 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09626         #endif
09627                 break;
09628 
09629         #ifdef WOLFSSL_EARLY_DATA
09630             case session_ticket:
09631                 if (ssl->options.tls1_3) {
09632                     XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09633                     TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
09634                 }
09635                 break;
09636         #endif
09637     #endif
09638 #endif
09639 
09640     #ifdef WOLFSSL_TLS13
09641         #ifndef NO_CERTS
09642             case certificate:
09643                 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09644                 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
09645                 /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
09646                  *       TLSX_SERVER_CERTIFICATE_TYPE
09647                  */
09648                 break;
09649         #endif
09650     #endif
09651         }
09652 
09653         offset += OPAQUE16_LEN; /* extensions length */
09654 
09655         ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
09656                          msgType, &offset);
09657 
09658 #ifdef WOLFSSL_TLS13
09659         if (msgType == hello_retry_request) {
09660             XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
09661             TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
09662             ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
09663                              msgType, &offset);
09664         }
09665 #endif
09666 
09667 #ifdef HAVE_EXTENDED_MASTER
09668         if (ssl->options.haveEMS && msgType == server_hello) {
09669             c16toa(HELLO_EXT_EXTMS, output + offset);
09670             offset += HELLO_EXT_TYPE_SZ;
09671             c16toa(0, output + offset);
09672             offset += HELLO_EXT_SZ_SZ;
09673         }
09674 #endif
09675 
09676         if (offset > OPAQUE16_LEN || msgType != server_hello)
09677             c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
09678     }
09679 
09680     if (pOffset)
09681         *pOffset += offset;
09682 
09683     return ret;
09684 }
09685 
09686 #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */
09687 
09688 /** Parses a buffer of TLS extensions. */
09689 int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
09690                                                                  Suites *suites)
09691 {
09692     int ret = 0;
09693     word16 offset = 0;
09694     byte isRequest = (msgType == client_hello ||
09695                       msgType == certificate_request);
09696 
09697 #ifdef HAVE_EXTENDED_MASTER
09698     byte pendingEMS = 0;
09699 #endif
09700 #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
09701     int pskDone = 0;
09702 #endif
09703 
09704     if (!ssl || !input || (isRequest && !suites))
09705         return BAD_FUNC_ARG;
09706 
09707     while (ret == 0 && offset < length) {
09708         word16 type;
09709         word16 size;
09710 
09711 #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
09712         if (msgType == client_hello && pskDone)
09713             return PSK_KEY_ERROR;
09714 #endif
09715 
09716         if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
09717             return BUFFER_ERROR;
09718 
09719         ato16(input + offset, &type);
09720         offset += HELLO_EXT_TYPE_SZ;
09721 
09722         ato16(input + offset, &size);
09723         offset += OPAQUE16_LEN;
09724 
09725         if (offset + size > length)
09726             return BUFFER_ERROR;
09727 
09728         switch (type) {
09729             case TLSX_SERVER_NAME:
09730                 WOLFSSL_MSG("SNI extension received");
09731 
09732 #ifdef WOLFSSL_TLS13
09733                 if (IsAtLeastTLSv1_3(ssl->version) &&
09734                         msgType != client_hello &&
09735                         msgType != encrypted_extensions) {
09736                     return EXT_NOT_ALLOWED;
09737                 }
09738 #endif
09739                 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
09740                 break;
09741 
09742             case TLSX_MAX_FRAGMENT_LENGTH:
09743                 WOLFSSL_MSG("Max Fragment Length extension received");
09744 
09745 #ifdef WOLFSSL_TLS13
09746                 if (IsAtLeastTLSv1_3(ssl->version) &&
09747                         msgType != client_hello &&
09748                         msgType != encrypted_extensions) {
09749                     return EXT_NOT_ALLOWED;
09750                 }
09751 #endif
09752                 ret = MFL_PARSE(ssl, input + offset, size, isRequest);
09753                 break;
09754 
09755             case TLSX_TRUNCATED_HMAC:
09756                 WOLFSSL_MSG("Truncated HMAC extension received");
09757 
09758 #ifdef WOLFSSL_TLS13
09759                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09760                     break;
09761 #endif
09762                 ret = THM_PARSE(ssl, input + offset, size, isRequest);
09763                 break;
09764 
09765             case TLSX_SUPPORTED_GROUPS:
09766                 WOLFSSL_MSG("Supported Groups extension received");
09767 
09768 #ifdef WOLFSSL_TLS13
09769                 if (IsAtLeastTLSv1_3(ssl->version) &&
09770                         msgType != client_hello &&
09771                         msgType != encrypted_extensions) {
09772                     return EXT_NOT_ALLOWED;
09773                 }
09774 #endif
09775                 ret = EC_PARSE(ssl, input + offset, size, isRequest);
09776                 break;
09777 
09778             case TLSX_EC_POINT_FORMATS:
09779                 WOLFSSL_MSG("Point Formats extension received");
09780 
09781 #ifdef WOLFSSL_TLS13
09782                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09783                     break;
09784 #endif
09785                 ret = PF_PARSE(ssl, input + offset, size, isRequest);
09786                 break;
09787 
09788             case TLSX_STATUS_REQUEST:
09789                 WOLFSSL_MSG("Certificate Status Request extension received");
09790 
09791 #ifdef WOLFSSL_TLS13
09792                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09793                     break;
09794 #endif
09795                 ret = CSR_PARSE(ssl, input + offset, size, isRequest);
09796                 break;
09797 
09798             case TLSX_STATUS_REQUEST_V2:
09799                 WOLFSSL_MSG("Certificate Status Request v2 extension received");
09800 
09801 #ifdef WOLFSSL_TLS13
09802                 if (IsAtLeastTLSv1_3(ssl->version) &&
09803                         msgType != client_hello &&
09804                         msgType != certificate_request &&
09805                         msgType != certificate) {
09806                     return EXT_NOT_ALLOWED;
09807                 }
09808 #endif
09809                 ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
09810                 break;
09811 
09812 #ifdef HAVE_EXTENDED_MASTER
09813             case HELLO_EXT_EXTMS:
09814                 WOLFSSL_MSG("Extended Master Secret extension received");
09815 
09816 #ifdef WOLFSSL_TLS13
09817                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09818                     break;
09819 #endif
09820 #ifndef NO_WOLFSSL_SERVER
09821                 if (isRequest)
09822                     ssl->options.haveEMS = 1;
09823 #endif
09824                 pendingEMS = 1;
09825                 break;
09826 #endif
09827 
09828             case TLSX_RENEGOTIATION_INFO:
09829                 WOLFSSL_MSG("Secure Renegotiation extension received");
09830 
09831 #ifdef WOLFSSL_TLS13
09832                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09833                     break;
09834 #endif
09835                 ret = SCR_PARSE(ssl, input + offset, size, isRequest);
09836                 break;
09837 
09838             case TLSX_SESSION_TICKET:
09839                 WOLFSSL_MSG("Session Ticket extension received");
09840 
09841 #ifdef WOLFSSL_TLS13
09842                 if (IsAtLeastTLSv1_3(ssl->version) &&
09843                         msgType != client_hello) {
09844                     return EXT_NOT_ALLOWED;
09845                 }
09846 #endif
09847                 ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest);
09848                 break;
09849 
09850             case TLSX_QUANTUM_SAFE_HYBRID:
09851                 WOLFSSL_MSG("Quantum-Safe-Hybrid extension received");
09852 
09853 #ifdef WOLFSSL_TLS13
09854                 if (IsAtLeastTLSv1_3(ssl->version) && !ssl->options.downgrade)
09855                     break;
09856 #endif
09857                 ret = QSH_PARSE(ssl, input + offset, size, isRequest);
09858                 break;
09859 
09860             case TLSX_APPLICATION_LAYER_PROTOCOL:
09861                 WOLFSSL_MSG("ALPN extension received");
09862 
09863 #ifdef WOLFSSL_TLS13
09864                 if (IsAtLeastTLSv1_3(ssl->version) &&
09865                         msgType != client_hello &&
09866                         msgType != encrypted_extensions) {
09867                     return EXT_NOT_ALLOWED;
09868                 }
09869 #endif
09870                 ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
09871                 break;
09872 
09873             case TLSX_SIGNATURE_ALGORITHMS:
09874                 WOLFSSL_MSG("Signature Algorithms extension received");
09875 
09876                 if (!IsAtLeastTLSv1_2(ssl))
09877                     break;
09878 
09879 #ifdef WOLFSSL_TLS13
09880                 if (IsAtLeastTLSv1_3(ssl->version) &&
09881                         msgType != client_hello &&
09882                         msgType != certificate_request) {
09883                     return EXT_NOT_ALLOWED;
09884                 }
09885 #endif
09886                 ret = SA_PARSE(ssl, input + offset, size, isRequest, suites);
09887                 break;
09888 
09889 #ifdef WOLFSSL_TLS13
09890             case TLSX_SUPPORTED_VERSIONS:
09891                 WOLFSSL_MSG("Supported Versions extension received");
09892 
09893                 if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
09894                     break;
09895 
09896                 if (IsAtLeastTLSv1_3(ssl->version) &&
09897     #ifdef WOLFSSL_TLS13_DRAFT_18
09898                         msgType != client_hello
09899     #else
09900                         msgType != client_hello &&
09901                         msgType != server_hello &&
09902                         msgType != hello_retry_request
09903     #endif
09904                    ) {
09905                     return EXT_NOT_ALLOWED;
09906                 }
09907                 ret = SV_PARSE(ssl, input + offset, size, msgType);
09908                 break;
09909 
09910             case TLSX_COOKIE:
09911                 WOLFSSL_MSG("Cookie extension received");
09912 
09913                 if (!IsAtLeastTLSv1_3(ssl->version))
09914                     break;
09915 
09916                 if (IsAtLeastTLSv1_3(ssl->version) &&
09917                         msgType != client_hello &&
09918                         msgType != hello_retry_request) {
09919                     return EXT_NOT_ALLOWED;
09920                 }
09921                 ret = CKE_PARSE(ssl, input + offset, size, msgType);
09922                 break;
09923 
09924     #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
09925             case TLSX_PRE_SHARED_KEY:
09926                 WOLFSSL_MSG("Pre-Shared Key extension received");
09927 
09928                 if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
09929                     break;
09930 
09931                 if (IsAtLeastTLSv1_3(ssl->version) &&
09932                         msgType != client_hello &&
09933                         msgType != server_hello) {
09934                     return EXT_NOT_ALLOWED;
09935                 }
09936                 ret = PSK_PARSE(ssl, input + offset, size, msgType);
09937                 pskDone = 1;
09938                 break;
09939 
09940             case TLSX_PSK_KEY_EXCHANGE_MODES:
09941                 WOLFSSL_MSG("PSK Key Exchange Modes extension received");
09942 
09943                 if (!IsAtLeastTLSv1_3(ssl->version))
09944                     break;
09945 
09946                 if (IsAtLeastTLSv1_3(ssl->version) &&
09947                         msgType != client_hello) {
09948                     return EXT_NOT_ALLOWED;
09949                 }
09950                 ret = PKM_PARSE(ssl, input + offset, size, msgType);
09951                 break;
09952     #endif
09953 
09954     #ifdef WOLFSSL_EARLY_DATA
09955             case TLSX_EARLY_DATA:
09956                 WOLFSSL_MSG("Early Data extension received");
09957 
09958                 if (!IsAtLeastTLSv1_3(ssl->version))
09959                     break;
09960 
09961                 if (IsAtLeastTLSv1_3(ssl->version) &&
09962                          msgType != client_hello &&
09963                          msgType != session_ticket &&
09964                          msgType != encrypted_extensions) {
09965                     return EXT_NOT_ALLOWED;
09966                 }
09967                 ret = EDI_PARSE(ssl, input + offset, size, msgType);
09968                 break;
09969     #endif
09970 
09971     #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
09972             case TLSX_POST_HANDSHAKE_AUTH:
09973                 WOLFSSL_MSG("Post Handshake Authentication extension received");
09974 
09975                 if (!IsAtLeastTLSv1_3(ssl->version))
09976                     break;
09977 
09978                 if (IsAtLeastTLSv1_3(ssl->version) &&
09979                         msgType != client_hello) {
09980                     return EXT_NOT_ALLOWED;
09981                 }
09982                 ret = PHA_PARSE(ssl, input + offset, size, msgType);
09983                 break;
09984     #endif
09985 
09986     #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
09987             case TLSX_SIGNATURE_ALGORITHMS_CERT:
09988                 WOLFSSL_MSG("Signature Algorithms extension received");
09989 
09990                 if (!IsAtLeastTLSv1_3(ssl->version))
09991                     break;
09992 
09993                 if (IsAtLeastTLSv1_3(ssl->version) &&
09994                         msgType != client_hello &&
09995                         msgType != certificate_request) {
09996                     return EXT_NOT_ALLOWED;
09997                 }
09998 
09999                 ret = SAC_PARSE(ssl, input + offset, size, isRequest);
10000                 break;
10001     #endif
10002 
10003             case TLSX_KEY_SHARE:
10004                 WOLFSSL_MSG("Key Share extension received");
10005 
10006                 if (!IsAtLeastTLSv1_3(ssl->ctx->method->version))
10007                     break;
10008 
10009                 if (IsAtLeastTLSv1_3(ssl->ctx->method->version) &&
10010                         msgType != client_hello &&
10011                         msgType != server_hello &&
10012                         msgType != hello_retry_request) {
10013                     return EXT_NOT_ALLOWED;
10014                 }
10015                 ret = KS_PARSE(ssl, input + offset, size, msgType);
10016                 break;
10017 #endif
10018         }
10019 
10020         /* offset should be updated here! */
10021         offset += size;
10022     }
10023 
10024 #ifdef HAVE_EXTENDED_MASTER
10025     if (!isRequest && ssl->options.haveEMS && !pendingEMS)
10026         ssl->options.haveEMS = 0;
10027 #endif
10028 
10029     if (ret == 0)
10030         ret = SNI_VERIFY_PARSE(ssl, isRequest);
10031 
10032     return ret;
10033 }
10034 
10035 /* undefining semaphore macros */
10036 #undef IS_OFF
10037 #undef TURN_ON
10038 #undef SEMAPHORE_SIZE
10039 
10040 #endif /* HAVE_TLS_EXTENSIONS */
10041 
10042 #ifndef NO_WOLFSSL_CLIENT
10043 
10044 #ifndef NO_OLD_TLS
10045 
10046     #ifdef WOLFSSL_ALLOW_TLSV10
10047     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
10048     /* Gets a WOLFSL_METHOD type that is not set as client or server
10049      *
10050      * Returns a pointer to a WOLFSSL_METHOD struct
10051      */
10052     WOLFSSL_METHOD* wolfTLSv1_method(void) {
10053         WOLFSSL_METHOD* m;
10054         WOLFSSL_ENTER("wolfTLSv1_method");
10055     #ifndef NO_WOLFSSL_CLIENT
10056         m = wolfTLSv1_client_method();
10057     #else
10058         m = wolfTLSv1_server_method();
10059     #endif
10060         if (m != NULL) {
10061             m->side = WOLFSSL_NEITHER_END;
10062         }
10063 
10064         return m;
10065     }
10066     #endif /* OPENSSL_EXTRA || OPENSSL_ALL*/
10067 
10068     WOLFSSL_METHOD* wolfTLSv1_client_method(void)
10069     {
10070         return wolfTLSv1_client_method_ex(NULL);
10071     }
10072 
10073     WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap)
10074     {
10075         WOLFSSL_METHOD* method =
10076                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10077                                                      heap, DYNAMIC_TYPE_METHOD);
10078         (void)heap;
10079         if (method)
10080             InitSSL_Method(method, MakeTLSv1());
10081         return method;
10082     }
10083     #endif /* WOLFSSL_ALLOW_TLSV10 */
10084 
10085     WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
10086     {
10087         return wolfTLSv1_1_client_method_ex(NULL);
10088     }
10089 
10090     WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap)
10091     {
10092         WOLFSSL_METHOD* method =
10093                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10094                                                      heap, DYNAMIC_TYPE_METHOD);
10095         (void)heap;
10096         if (method)
10097             InitSSL_Method(method, MakeTLSv1_1());
10098         return method;
10099     }
10100 
10101 #endif /* !NO_OLD_TLS */
10102 
10103 #ifndef WOLFSSL_NO_TLS12
10104 
10105     WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
10106     {
10107         return wolfTLSv1_2_client_method_ex(NULL);
10108     }
10109 
10110     WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap)
10111     {
10112         WOLFSSL_METHOD* method =
10113                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10114                                                      heap, DYNAMIC_TYPE_METHOD);
10115         (void)heap;
10116         if (method)
10117             InitSSL_Method(method, MakeTLSv1_2());
10118         return method;
10119     }
10120 
10121 #endif /* WOLFSSL_NO_TLS12 */
10122 
10123 #ifdef WOLFSSL_TLS13
10124     /* The TLS v1.3 client method data.
10125      *
10126      * returns the method data for a TLS v1.3 client.
10127      */
10128     WOLFSSL_METHOD* wolfTLSv1_3_client_method(void)
10129     {
10130         return wolfTLSv1_3_client_method_ex(NULL);
10131     }
10132 
10133     /* The TLS v1.3 client method data.
10134      *
10135      * heap  The heap used for allocation.
10136      * returns the method data for a TLS v1.3 client.
10137      */
10138     WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap)
10139     {
10140         WOLFSSL_METHOD* method = (WOLFSSL_METHOD*)
10141                                  XMALLOC(sizeof(WOLFSSL_METHOD), heap,
10142                                          DYNAMIC_TYPE_METHOD);
10143         (void)heap;
10144         if (method)
10145             InitSSL_Method(method, MakeTLSv1_3());
10146         return method;
10147     }
10148 #endif /* WOLFSSL_TLS13 */
10149 
10150 
10151     WOLFSSL_METHOD* wolfSSLv23_client_method(void)
10152     {
10153         return wolfSSLv23_client_method_ex(NULL);
10154     }
10155 
10156 
10157     WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
10158     {
10159         WOLFSSL_METHOD* method =
10160                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10161                                                      heap, DYNAMIC_TYPE_METHOD);
10162         (void)heap;
10163         if (method) {
10164 #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
10165 #if defined(WOLFSSL_TLS13)
10166             InitSSL_Method(method, MakeTLSv1_3());
10167 #else
10168             InitSSL_Method(method, MakeTLSv1_2());
10169 #endif
10170 #else
10171     #ifndef NO_OLD_TLS
10172             InitSSL_Method(method, MakeTLSv1_1());
10173     #endif
10174 #endif
10175 #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
10176             method->downgrade = 1;
10177 #endif
10178         }
10179         return method;
10180     }
10181 
10182 #endif /* NO_WOLFSSL_CLIENT */
10183 
10184 
10185 
10186 #ifndef NO_WOLFSSL_SERVER
10187 
10188 #ifndef NO_OLD_TLS
10189     #ifdef WOLFSSL_ALLOW_TLSV10
10190     WOLFSSL_METHOD* wolfTLSv1_server_method(void)
10191     {
10192         return wolfTLSv1_server_method_ex(NULL);
10193     }
10194 
10195     WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap)
10196     {
10197         WOLFSSL_METHOD* method =
10198                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10199                                                      heap, DYNAMIC_TYPE_METHOD);
10200         (void)heap;
10201         if (method) {
10202             InitSSL_Method(method, MakeTLSv1());
10203             method->side = WOLFSSL_SERVER_END;
10204         }
10205         return method;
10206     }
10207     #endif /* WOLFSSL_ALLOW_TLSV10 */
10208     
10209     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
10210     /* Gets a WOLFSL_METHOD type that is not set as client or server
10211      *
10212      * Returns a pointer to a WOLFSSL_METHOD struct
10213      */
10214     WOLFSSL_METHOD* wolfTLSv1_1_method(void) {
10215         WOLFSSL_METHOD* m;
10216         WOLFSSL_ENTER("wolfTLSv1_1_method");
10217     #ifndef NO_WOLFSSL_CLIENT
10218         m = wolfTLSv1_1_client_method();
10219     #else
10220         m = wolfTLSv1_1_server_method();
10221     #endif
10222         if (m != NULL) {
10223             m->side = WOLFSSL_NEITHER_END;
10224         }
10225         return m;
10226     }
10227     #endif /* OPENSSL_EXTRA || OPENSSL_ALL */
10228 
10229     WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
10230     {
10231         return wolfTLSv1_1_server_method_ex(NULL);
10232     }
10233 
10234     WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap)
10235     {
10236         WOLFSSL_METHOD* method =
10237                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10238                                                      heap, DYNAMIC_TYPE_METHOD);
10239         (void)heap;
10240         if (method) {
10241             InitSSL_Method(method, MakeTLSv1_1());
10242             method->side = WOLFSSL_SERVER_END;
10243         }
10244         return method;
10245     }
10246 #endif /* !NO_OLD_TLS */
10247 
10248 #ifndef WOLFSSL_NO_TLS12
10249 
10250     #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
10251     /* Gets a WOLFSL_METHOD type that is not set as client or server
10252      *
10253      * Returns a pointer to a WOLFSSL_METHOD struct
10254      */
10255     WOLFSSL_METHOD* wolfTLSv1_2_method(void) {
10256         WOLFSSL_METHOD* m;
10257         WOLFSSL_ENTER("wolfTLSv1_2_method");
10258     #ifndef NO_WOLFSSL_CLIENT
10259         m = wolfTLSv1_2_client_method();
10260     #else
10261         m = wolfTLSv1_2_server_method();
10262     #endif
10263         if (m != NULL) {
10264             m->side = WOLFSSL_NEITHER_END;
10265         }
10266         return m;
10267     }
10268     #endif /* OPENSSL_EXTRA || OPENSSL_ALL */
10269 
10270     WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
10271     {
10272         return wolfTLSv1_2_server_method_ex(NULL);
10273     }
10274 
10275     WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap)
10276     {
10277         WOLFSSL_METHOD* method =
10278                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10279                                                      heap, DYNAMIC_TYPE_METHOD);
10280         (void)heap;
10281         if (method) {
10282             InitSSL_Method(method, MakeTLSv1_2());
10283             method->side = WOLFSSL_SERVER_END;
10284         }
10285         return method;
10286     }
10287 
10288 #endif /* !WOLFSSL_NO_TLS12 */
10289 
10290 #ifdef WOLFSSL_TLS13
10291     /* The TLS v1.3 server method data.
10292      *
10293      * returns the method data for a TLS v1.3 server.
10294      */
10295     WOLFSSL_METHOD* wolfTLSv1_3_server_method(void)
10296     {
10297         return wolfTLSv1_3_server_method_ex(NULL);
10298     }
10299 
10300     /* The TLS v1.3 server method data.
10301      *
10302      * heap  The heap used for allocation.
10303      * returns the method data for a TLS v1.3 server.
10304      */
10305     WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap)
10306     {
10307         WOLFSSL_METHOD* method =
10308                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10309                                                      heap, DYNAMIC_TYPE_METHOD);
10310         (void)heap;
10311         if (method) {
10312             InitSSL_Method(method, MakeTLSv1_3());
10313             method->side = WOLFSSL_SERVER_END;
10314         }
10315         return method;
10316     }
10317 #endif /* WOLFSSL_TLS13 */
10318 
10319     WOLFSSL_METHOD* wolfSSLv23_server_method(void)
10320     {
10321         return wolfSSLv23_server_method_ex(NULL);
10322     }
10323 
10324     WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
10325     {
10326         WOLFSSL_METHOD* method =
10327                               (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
10328                                                      heap, DYNAMIC_TYPE_METHOD);
10329         (void)heap;
10330         if (method) {
10331 #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
10332 #ifdef WOLFSSL_TLS13
10333             InitSSL_Method(method, MakeTLSv1_3());
10334 #else
10335             InitSSL_Method(method, MakeTLSv1_2());
10336 #endif
10337 #else
10338     #ifndef NO_OLD_TLS
10339             InitSSL_Method(method, MakeTLSv1_1());
10340     #else
10341             #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
10342     #endif
10343 #endif
10344 #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
10345             method->downgrade = 1;
10346 #endif
10347             method->side      = WOLFSSL_SERVER_END;
10348         }
10349         return method;
10350     }
10351 
10352 
10353 #endif /* NO_WOLFSSL_SERVER */
10354 #endif /* NO_TLS */
10355 #endif /* WOLFCRYPT_ONLY */
10356