wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers internal.c Source File

internal.c

00001 /* internal.c
00002  *
00003  * Copyright (C) 2006-2016 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 <wolfssl/wolfcrypt/settings.h>
00029 
00030 #ifndef WOLFCRYPT_ONLY
00031 
00032 #include <wolfssl/internal.h>
00033 #include <wolfssl/error-ssl.h>
00034 #include <wolfssl/wolfcrypt/asn.h>
00035 #include <wolfssl/wolfcrypt/dh.h>
00036 #ifdef NO_INLINE
00037     #include <wolfssl/wolfcrypt/misc.h>
00038 #else
00039     #define WOLFSSL_MISC_INCLUDED
00040     #include <wolfcrypt/src/misc.c>
00041 #endif
00042 
00043 #ifdef HAVE_LIBZ
00044     #include "zlib.h"
00045 #endif
00046 
00047 #ifdef HAVE_NTRU
00048     #include "libntruencrypt/ntru_crypto.h"
00049 #endif
00050 
00051 #if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || \
00052     defined(CHACHA_AEAD_TEST) || defined(WOLFSSL_SESSION_EXPORT_DEBUG)
00053     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00054         #if MQX_USE_IO_OLD
00055             #include <fio.h>
00056         #else
00057             #include <nio.h>
00058         #endif
00059     #else
00060         #include <stdio.h>
00061     #endif
00062 #endif
00063 
00064 #ifdef __sun
00065     #include <sys/filio.h>
00066 #endif
00067 
00068 
00069 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
00070 
00071 #ifdef _MSC_VER
00072     /* disable for while(0) cases at the .c level for now */
00073     #pragma warning(disable:4127)
00074 #endif
00075 
00076 #if defined(WOLFSSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
00077     #error \
00078 WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
00079 #endif
00080 
00081 #if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
00082     #error Cannot use both secure-renegotiation and renegotiation-indication
00083 #endif
00084 
00085 #ifndef NO_WOLFSSL_CLIENT
00086     static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
00087                                                                         word32);
00088     static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32*,
00089                                                                         word32);
00090     #ifndef NO_CERTS
00091         static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*,
00092                                                                         word32);
00093     #endif
00094     #ifdef HAVE_SESSION_TICKET
00095         static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32*,
00096                                                                         word32);
00097     #endif
00098 #endif
00099 
00100 
00101 #ifndef NO_WOLFSSL_SERVER
00102     static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32);
00103     #if !defined(NO_RSA) || defined(HAVE_ECC)
00104         static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
00105     #endif
00106     #ifdef WOLFSSL_DTLS
00107         static int SendHelloVerifyRequest(WOLFSSL*, const byte*, byte);
00108     #endif /* WOLFSSL_DTLS */
00109 #endif
00110 
00111 
00112 #ifdef WOLFSSL_DTLS
00113     static INLINE int DtlsCheckWindow(WOLFSSL* ssl);
00114     static INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
00115 #endif
00116 
00117 
00118 enum processReply {
00119     doProcessInit = 0,
00120 #ifndef NO_WOLFSSL_SERVER
00121     runProcessOldClientHello,
00122 #endif
00123     getRecordLayerHeader,
00124     getData,
00125     decryptMessage,
00126     verifyMessage,
00127     runProcessingOneMessage
00128 };
00129 
00130 /* sub-states for build message */
00131 enum buildMsgState {
00132     BUILD_MSG_BEGIN = 0,
00133     BUILD_MSG_SIZE,
00134     BUILD_MSG_HASH,
00135     BUILD_MSG_VERIFY_MAC,
00136     BUILD_MSG_ENCRYPT,
00137 };
00138 
00139 /* sub-states for cipher operations */
00140 enum cipherState {
00141     CIPHER_STATE_BEGIN = 0,
00142     CIPHER_STATE_DO,
00143     CIPHER_STATE_END,
00144 };
00145 
00146 
00147 #ifndef NO_OLD_TLS
00148 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
00149                     int content, int verify);
00150 
00151 #endif
00152 
00153 #ifdef HAVE_QSH
00154     int QSH_Init(WOLFSSL* ssl);
00155 #endif
00156 
00157 
00158 int IsTLS(const WOLFSSL* ssl)
00159 {
00160     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
00161         return 1;
00162 
00163     return 0;
00164 }
00165 
00166 
00167 int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
00168 {
00169     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
00170         return 1;
00171     if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
00172         return 1;
00173 
00174     return 0;
00175 }
00176 
00177 int IsAtLeastTLSv1_3(const ProtocolVersion pv)
00178 {
00179     return (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR);
00180 }
00181 
00182 
00183 static INLINE int IsEncryptionOn(WOLFSSL* ssl, int isSend)
00184 {
00185     (void)isSend;
00186 
00187     #ifdef WOLFSSL_DTLS
00188     /* For DTLS, epoch 0 is always not encrypted. */
00189     if (ssl->options.dtls && !isSend && ssl->keys.curEpoch == 0)
00190         return 0;
00191     #endif /* WOLFSSL_DTLS */
00192 
00193     return ssl->keys.encryptionOn;
00194 }
00195 
00196 
00197 /* If SCTP is not enabled returns the state of the dtls option.
00198  * If SCTP is enabled returns dtls && !sctp. */
00199 static INLINE int IsDtlsNotSctpMode(WOLFSSL* ssl)
00200 {
00201     int result = ssl->options.dtls;
00202 
00203     if (result) {
00204 #ifdef WOLFSSL_SCTP
00205         result = !ssl->options.dtlsSctp;
00206 #endif
00207     }
00208 
00209     return result;
00210 }
00211 
00212 
00213 #ifdef HAVE_QSH
00214 /* free all structs that where used with QSH */
00215 static int QSH_FreeAll(WOLFSSL* ssl)
00216 {
00217     QSHKey* key        = ssl->QSH_Key;
00218     QSHKey* preKey     = NULL;
00219     QSHSecret* secret  = ssl->QSH_secret;
00220     QSHScheme* list    = NULL;
00221     QSHScheme* preList = NULL;
00222 
00223     /* free elements in struct */
00224     while (key) {
00225         preKey = key;
00226         if (key->pri.buffer) {
00227             ForceZero(key->pri.buffer, key->pri.length);
00228             XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00229         }
00230         if (key->pub.buffer)
00231             XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00232         key = (QSHKey*)key->next;
00233 
00234         /* free struct */
00235         XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00236     }
00237     key = NULL;
00238 
00239 
00240     /* free all of peers QSH keys */
00241     key = ssl->peerQSHKey;
00242     while (key) {
00243         preKey = key;
00244         if (key->pri.buffer) {
00245             ForceZero(key->pri.buffer, key->pri.length);
00246             XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00247         }
00248         if (key->pub.buffer)
00249             XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00250         key = (QSHKey*)key->next;
00251 
00252         /* free struct */
00253         XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00254     }
00255     key = NULL;
00256 
00257     /* free secret information */
00258     if (secret) {
00259         /* free up the QSHScheme list in QSHSecret */
00260         if (secret->list)
00261             list = secret->list;
00262         while (list) {
00263             preList = list;
00264             if (list->PK)
00265                 XFREE(list->PK, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00266             list = (QSHScheme*)list->next;
00267             XFREE(preList, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00268         }
00269 
00270         /* free secret buffers */
00271         if (secret->SerSi) {
00272             if (secret->SerSi->buffer) {
00273                 /* clear extra secret material that supplemented Master Secret*/
00274                 ForceZero(secret->SerSi->buffer, secret->SerSi->length);
00275                 XFREE(secret->SerSi->buffer, ssl->heap,DYNAMIC_TYPE_TMP_BUFFER);
00276             }
00277             XFREE(secret->SerSi, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00278         }
00279         if (secret->CliSi) {
00280             if (secret->CliSi->buffer) {
00281                 /* clear extra secret material that supplemented Master Secret*/
00282                 ForceZero(secret->CliSi->buffer, secret->CliSi->length);
00283                 XFREE(secret->CliSi->buffer, ssl->heap,DYNAMIC_TYPE_TMP_BUFFER);
00284             }
00285             XFREE(secret->CliSi, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00286         }
00287     }
00288     XFREE(secret, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
00289     secret = NULL;
00290 
00291     return 0;
00292 }
00293 #endif
00294 
00295 
00296 #ifdef HAVE_NTRU
00297 static WC_RNG* rng;
00298 static wolfSSL_Mutex* rngMutex;
00299 
00300 static word32 GetEntropy(unsigned char* out, word32 num_bytes)
00301 {
00302     int ret = 0;
00303 
00304     if (rng == NULL) {
00305         if ((rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), 0,
00306                                                     DYNAMIC_TYPE_TLSX)) == NULL)
00307             return DRBG_OUT_OF_MEMORY;
00308         wc_InitRng(rng);
00309     }
00310 
00311     if (rngMutex == NULL) {
00312         if ((rngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), 0,
00313                         DYNAMIC_TYPE_TLSX)) == NULL)
00314             return DRBG_OUT_OF_MEMORY;
00315         wc_InitMutex(rngMutex);
00316     }
00317 
00318     ret |= wc_LockMutex(rngMutex);
00319     ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
00320     ret |= wc_UnLockMutex(rngMutex);
00321 
00322     if (ret != 0)
00323         return DRBG_ENTROPY_FAIL;
00324 
00325     return DRBG_OK;
00326 }
00327 #endif /* HAVE_NTRU */
00328 
00329 /* used by ssl.c too */
00330 void c32to24(word32 in, word24 out)
00331 {
00332     out[0] = (in >> 16) & 0xff;
00333     out[1] = (in >>  8) & 0xff;
00334     out[2] =  in & 0xff;
00335 }
00336 
00337 
00338 /* convert 16 bit integer to opaque */
00339 static INLINE void c16toa(word16 u16, byte* c)
00340 {
00341     c[0] = (u16 >> 8) & 0xff;
00342     c[1] =  u16 & 0xff;
00343 }
00344 
00345 
00346 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
00347     || defined(HAVE_AESGCM) || defined(WOLFSSL_SESSION_EXPORT) \
00348     || defined(WOLFSSL_DTLS) || defined(HAVE_SESSION_TICKET)
00349 /* convert 32 bit integer to opaque */
00350 static INLINE void c32toa(word32 u32, byte* c)
00351 {
00352     c[0] = (u32 >> 24) & 0xff;
00353     c[1] = (u32 >> 16) & 0xff;
00354     c[2] = (u32 >>  8) & 0xff;
00355     c[3] =  u32 & 0xff;
00356 }
00357 
00358 #endif
00359 
00360 
00361 /* convert a 24 bit integer into a 32 bit one */
00362 static INLINE void c24to32(const word24 u24, word32* u32)
00363 {
00364     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00365 }
00366 
00367 
00368 /* convert opaque to 16 bit integer */
00369 static INLINE void ato16(const byte* c, word16* u16)
00370 {
00371     *u16 = (word16) ((c[0] << 8) | (c[1]));
00372 }
00373 
00374 
00375 #if defined(WOLFSSL_DTLS) || defined(HAVE_SESSION_TICKET) || \
00376     defined(WOLFSSL_SESSION_EXPORT)
00377 
00378 /* convert opaque to 32 bit integer */
00379 static INLINE void ato32(const byte* c, word32* u32)
00380 {
00381     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
00382 }
00383 
00384 #endif /* WOLFSSL_DTLS */
00385 
00386 
00387 #ifdef HAVE_LIBZ
00388 
00389     /* alloc user allocs to work with zlib */
00390     static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00391     {
00392         (void)opaque;
00393         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00394     }
00395 
00396 
00397     static void myFree(void* opaque, void* memory)
00398     {
00399         (void)opaque;
00400         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00401     }
00402 
00403 
00404     /* init zlib comp/decomp streams, 0 on success */
00405     static int InitStreams(WOLFSSL* ssl)
00406     {
00407         ssl->c_stream.zalloc = (alloc_func)myAlloc;
00408         ssl->c_stream.zfree  = (free_func)myFree;
00409         ssl->c_stream.opaque = (voidpf)ssl->heap;
00410 
00411         if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
00412             return ZLIB_INIT_ERROR;
00413 
00414         ssl->didStreamInit = 1;
00415 
00416         ssl->d_stream.zalloc = (alloc_func)myAlloc;
00417         ssl->d_stream.zfree  = (free_func)myFree;
00418         ssl->d_stream.opaque = (voidpf)ssl->heap;
00419 
00420         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
00421 
00422         return 0;
00423     }
00424 
00425 
00426     static void FreeStreams(WOLFSSL* ssl)
00427     {
00428         if (ssl->didStreamInit) {
00429             deflateEnd(&ssl->c_stream);
00430             inflateEnd(&ssl->d_stream);
00431         }
00432     }
00433 
00434 
00435     /* compress in to out, return out size or error */
00436     static int myCompress(WOLFSSL* ssl, byte* in, int inSz, byte* out, int outSz)
00437     {
00438         int    err;
00439         int    currTotal = (int)ssl->c_stream.total_out;
00440 
00441         ssl->c_stream.next_in   = in;
00442         ssl->c_stream.avail_in  = inSz;
00443         ssl->c_stream.next_out  = out;
00444         ssl->c_stream.avail_out = outSz;
00445 
00446         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
00447         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
00448 
00449         return (int)ssl->c_stream.total_out - currTotal;
00450     }
00451 
00452 
00453     /* decompress in to out, return out size or error */
00454     static int myDeCompress(WOLFSSL* ssl, byte* in,int inSz, byte* out,int outSz)
00455     {
00456         int    err;
00457         int    currTotal = (int)ssl->d_stream.total_out;
00458 
00459         ssl->d_stream.next_in   = in;
00460         ssl->d_stream.avail_in  = inSz;
00461         ssl->d_stream.next_out  = out;
00462         ssl->d_stream.avail_out = outSz;
00463 
00464         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
00465         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
00466 
00467         return (int)ssl->d_stream.total_out - currTotal;
00468     }
00469 
00470 #endif /* HAVE_LIBZ */
00471 
00472 
00473 #ifdef WOLFSSL_SESSION_EXPORT
00474 #ifdef WOLFSSL_DTLS
00475 /* serializes the cipher specs struct for exporting */
00476 static int ExportCipherSpecState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00477 {
00478     word32 idx = 0;
00479     CipherSpecs* specs;
00480 
00481     WOLFSSL_ENTER("ExportCipherSpecState");
00482 
00483     if (exp == NULL || ssl == NULL) {
00484         return BAD_FUNC_ARG;
00485     }
00486 
00487     specs= &(ssl->specs);
00488 
00489     if (DTLS_EXPORT_SPC_SZ > len) {
00490         return BUFFER_E;
00491     }
00492 
00493     XMEMSET(exp, 0, DTLS_EXPORT_SPC_SZ);
00494 
00495     c16toa(specs->key_size, exp + idx);      idx += OPAQUE16_LEN;
00496     c16toa(specs->iv_size, exp + idx);       idx += OPAQUE16_LEN;
00497     c16toa(specs->block_size, exp + idx);    idx += OPAQUE16_LEN;
00498     c16toa(specs->aead_mac_size, exp + idx); idx += OPAQUE16_LEN;
00499     exp[idx++] = specs->bulk_cipher_algorithm;
00500     exp[idx++] = specs->cipher_type;
00501     exp[idx++] = specs->mac_algorithm;
00502     exp[idx++] = specs->kea;
00503     exp[idx++] = specs->sig_algo;
00504     exp[idx++] = specs->hash_size;
00505     exp[idx++] = specs->pad_size;
00506     exp[idx++] = specs->static_ecdh;
00507 
00508     if (idx != DTLS_EXPORT_SPC_SZ) {
00509         WOLFSSL_MSG("DTLS_EXPORT_SPC_SZ needs updated and export version");
00510         return DTLS_EXPORT_VER_E;
00511     }
00512 
00513     WOLFSSL_LEAVE("ExportCipherSpecState", idx);
00514     (void)ver;
00515     return idx;
00516 }
00517 
00518 
00519 /* serializes the key struct for exporting */
00520 static int ExportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00521 {
00522     word32 idx = 0;
00523     byte   sz;
00524     Keys* keys;
00525 
00526     WOLFSSL_ENTER("ExportKeyState");
00527 
00528     if (exp == NULL || ssl == NULL) {
00529         return BAD_FUNC_ARG;
00530     }
00531 
00532     keys = &(ssl->keys);
00533 
00534     if (DTLS_EXPORT_KEY_SZ > len) {
00535         WOLFSSL_MSG("Buffer not large enough for max key struct size");
00536         return BUFFER_E;
00537     }
00538 
00539     XMEMSET(exp, 0, DTLS_EXPORT_KEY_SZ);
00540 
00541     c32toa(keys->peer_sequence_number_hi, exp + idx); idx += OPAQUE32_LEN;
00542     c32toa(keys->peer_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN;
00543     c32toa(keys->sequence_number_hi, exp + idx);      idx += OPAQUE32_LEN;
00544     c32toa(keys->sequence_number_lo, exp + idx);      idx += OPAQUE32_LEN;
00545 
00546     c16toa(keys->nextEpoch, exp + idx);  idx += OPAQUE16_LEN;
00547     c16toa(keys->nextSeq_hi, exp + idx); idx += OPAQUE16_LEN;
00548     c32toa(keys->nextSeq_lo, exp + idx); idx += OPAQUE32_LEN;
00549     c16toa(keys->curEpoch, exp + idx);   idx += OPAQUE16_LEN;
00550     c16toa(keys->curSeq_hi, exp + idx);  idx += OPAQUE16_LEN;
00551     c32toa(keys->curSeq_lo, exp + idx);  idx += OPAQUE32_LEN;
00552     c16toa(keys->prevSeq_hi, exp + idx); idx += OPAQUE16_LEN;
00553     c32toa(keys->prevSeq_lo, exp + idx); idx += OPAQUE32_LEN;
00554 
00555     c16toa(keys->dtls_peer_handshake_number, exp + idx); idx += OPAQUE16_LEN;
00556     c16toa(keys->dtls_expected_peer_handshake_number, exp + idx);
00557     idx += OPAQUE16_LEN;
00558 
00559     c16toa(keys->dtls_sequence_number_hi, exp + idx);      idx += OPAQUE16_LEN;
00560     c32toa(keys->dtls_sequence_number_lo, exp + idx);      idx += OPAQUE32_LEN;
00561     c16toa(keys->dtls_prev_sequence_number_hi, exp + idx); idx += OPAQUE16_LEN;
00562     c32toa(keys->dtls_prev_sequence_number_lo, exp + idx); idx += OPAQUE32_LEN;
00563     c16toa(keys->dtls_epoch, exp + idx);                   idx += OPAQUE16_LEN;
00564     c16toa(keys->dtls_handshake_number, exp + idx);        idx += OPAQUE16_LEN;
00565     c32toa(keys->encryptSz, exp + idx);                    idx += OPAQUE32_LEN;
00566     c32toa(keys->padSz, exp + idx);                        idx += OPAQUE32_LEN;
00567     exp[idx++] = keys->encryptionOn;
00568     exp[idx++] = keys->decryptedCur;
00569 
00570     {
00571         word32 i;
00572 
00573         c16toa(WOLFSSL_DTLS_WINDOW_WORDS, exp + idx); idx += OPAQUE16_LEN;
00574         for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
00575             c32toa(keys->window[i], exp + idx);
00576             idx += OPAQUE32_LEN;
00577         }
00578         c16toa(WOLFSSL_DTLS_WINDOW_WORDS, exp + idx); idx += OPAQUE16_LEN;
00579         for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
00580             c32toa(keys->prevWindow[i], exp + idx);
00581             idx += OPAQUE32_LEN;
00582         }
00583     }
00584 
00585 #ifdef HAVE_TRUNCATED_HMAC
00586     sz         = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ: ssl->specs.hash_size;
00587     exp[idx++] = ssl->truncated_hmac;
00588 #else
00589     sz         = ssl->specs.hash_size;
00590     exp[idx++] = 0; /* no truncated hmac */
00591 #endif
00592     exp[idx++] = sz;
00593     XMEMCPY(exp + idx, keys->client_write_MAC_secret, sz); idx += sz;
00594     XMEMCPY(exp + idx, keys->server_write_MAC_secret, sz); idx += sz;
00595 
00596     sz         = ssl->specs.key_size;
00597     exp[idx++] = sz;
00598     XMEMCPY(exp + idx, keys->client_write_key, sz); idx += sz;
00599     XMEMCPY(exp + idx, keys->server_write_key, sz); idx += sz;
00600 
00601     sz         = ssl->specs.iv_size;
00602     exp[idx++] = sz;
00603     XMEMCPY(exp + idx, keys->client_write_IV, sz); idx += sz;
00604     XMEMCPY(exp + idx, keys->server_write_IV, sz); idx += sz;
00605     XMEMCPY(exp + idx, keys->aead_exp_IV, AEAD_MAX_EXP_SZ);
00606     idx += AEAD_MAX_EXP_SZ;
00607 
00608     sz         = AEAD_MAX_IMP_SZ;
00609     exp[idx++] = sz;
00610     XMEMCPY(exp + idx, keys->aead_enc_imp_IV, sz); idx += sz;
00611     XMEMCPY(exp + idx, keys->aead_dec_imp_IV, sz); idx += sz;
00612 
00613     /* DTLS_EXPORT_KEY_SZ is max value. idx size can vary */
00614     if (idx > DTLS_EXPORT_KEY_SZ) {
00615         WOLFSSL_MSG("DTLS_EXPORT_KEY_SZ needs updated and export version");
00616         return DTLS_EXPORT_VER_E;
00617     }
00618 
00619     WOLFSSL_LEAVE("ExportKeyState", idx);
00620     (void)ver;
00621     return idx;
00622 }
00623 
00624 static int ImportCipherSpecState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00625 {
00626     word32 idx = 0;
00627     CipherSpecs* specs;
00628 
00629     WOLFSSL_ENTER("ImportCipherSpecState");
00630 
00631     if (exp == NULL || ssl == NULL) {
00632         return BAD_FUNC_ARG;
00633     }
00634 
00635     specs= &(ssl->specs);
00636 
00637     if (DTLS_EXPORT_SPC_SZ > len) {
00638         WOLFSSL_MSG("Buffer not large enough for max spec struct size");
00639         return BUFFER_E;
00640     }
00641 
00642     ato16(exp + idx, &specs->key_size);      idx += OPAQUE16_LEN;
00643     ato16(exp + idx, &specs->iv_size);       idx += OPAQUE16_LEN;
00644     ato16(exp + idx, &specs->block_size);    idx += OPAQUE16_LEN;
00645     ato16(exp + idx, &specs->aead_mac_size); idx += OPAQUE16_LEN;
00646     specs->bulk_cipher_algorithm = exp[idx++];
00647     specs->cipher_type           = exp[idx++];
00648     specs->mac_algorithm         = exp[idx++];
00649     specs->kea                   = exp[idx++];
00650     specs->sig_algo              = exp[idx++];
00651     specs->hash_size             = exp[idx++];
00652     specs->pad_size              = exp[idx++];
00653     specs->static_ecdh           = exp[idx++];
00654 
00655     WOLFSSL_LEAVE("ImportCipherSpecState", idx);
00656     (void)ver;
00657     return idx;
00658 }
00659 
00660 
00661 static int ImportKeyState(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00662 {
00663     word32 idx = 0;
00664     byte  sz;
00665     Keys* keys;
00666 
00667     WOLFSSL_ENTER("ImportKeyState");
00668 
00669     if (exp == NULL || ssl == NULL) {
00670         return BAD_FUNC_ARG;
00671     }
00672 
00673     keys = &(ssl->keys);
00674 
00675     /* check minimum length -- includes byte used for size indicators */
00676     if (len < DTLS_EXPORT_MIN_KEY_SZ) {
00677         return BUFFER_E;
00678     }
00679     ato32(exp + idx, &keys->peer_sequence_number_hi); idx += OPAQUE32_LEN;
00680     ato32(exp + idx, &keys->peer_sequence_number_lo); idx += OPAQUE32_LEN;
00681     ato32(exp + idx, &keys->sequence_number_hi);      idx += OPAQUE32_LEN;
00682     ato32(exp + idx, &keys->sequence_number_lo);      idx += OPAQUE32_LEN;
00683 
00684     ato16(exp + idx, &keys->nextEpoch);  idx += OPAQUE16_LEN;
00685     ato16(exp + idx, &keys->nextSeq_hi); idx += OPAQUE16_LEN;
00686     ato32(exp + idx, &keys->nextSeq_lo); idx += OPAQUE32_LEN;
00687     ato16(exp + idx, &keys->curEpoch);   idx += OPAQUE16_LEN;
00688     ato16(exp + idx, &keys->curSeq_hi);  idx += OPAQUE16_LEN;
00689     ato32(exp + idx, &keys->curSeq_lo);  idx += OPAQUE32_LEN;
00690     ato16(exp + idx, &keys->prevSeq_hi); idx += OPAQUE16_LEN;
00691     ato32(exp + idx, &keys->prevSeq_lo); idx += OPAQUE32_LEN;
00692 
00693     ato16(exp + idx, &keys->dtls_peer_handshake_number); idx += OPAQUE16_LEN;
00694     ato16(exp + idx, &keys->dtls_expected_peer_handshake_number);
00695     idx += OPAQUE16_LEN;
00696 
00697     ato16(exp + idx, &keys->dtls_sequence_number_hi);      idx += OPAQUE16_LEN;
00698     ato32(exp + idx, &keys->dtls_sequence_number_lo);      idx += OPAQUE32_LEN;
00699     ato16(exp + idx, &keys->dtls_prev_sequence_number_hi); idx += OPAQUE16_LEN;
00700     ato32(exp + idx, &keys->dtls_prev_sequence_number_lo); idx += OPAQUE32_LEN;
00701     ato16(exp + idx, &keys->dtls_epoch);                   idx += OPAQUE16_LEN;
00702     ato16(exp + idx, &keys->dtls_handshake_number);        idx += OPAQUE16_LEN;
00703     ato32(exp + idx, &keys->encryptSz);                    idx += OPAQUE32_LEN;
00704     ato32(exp + idx, &keys->padSz);                        idx += OPAQUE32_LEN;
00705     keys->encryptionOn = exp[idx++];
00706     keys->decryptedCur = exp[idx++];
00707 
00708     {
00709         word16 i, wordCount, wordAdj = 0;
00710 
00711         /* do window */
00712         ato16(exp + idx, &wordCount);
00713         idx += OPAQUE16_LEN;
00714 
00715         if (wordCount > WOLFSSL_DTLS_WINDOW_WORDS) {
00716             wordCount = WOLFSSL_DTLS_WINDOW_WORDS;
00717             wordAdj = (WOLFSSL_DTLS_WINDOW_WORDS - wordCount) * sizeof(word32);
00718         }
00719 
00720         XMEMSET(keys->window, 0xFF, DTLS_SEQ_SZ);
00721         for (i = 0; i < wordCount; i++) {
00722             ato32(exp + idx, &keys->window[i]);
00723             idx += OPAQUE32_LEN;
00724         }
00725         idx += wordAdj;
00726 
00727         /* do prevWindow */
00728         ato16(exp + idx, &wordCount);
00729         idx += OPAQUE16_LEN;
00730 
00731         if (wordCount > WOLFSSL_DTLS_WINDOW_WORDS) {
00732             wordCount = WOLFSSL_DTLS_WINDOW_WORDS;
00733             wordAdj = (WOLFSSL_DTLS_WINDOW_WORDS - wordCount) * sizeof(word32);
00734         }
00735 
00736         XMEMSET(keys->prevWindow, 0xFF, DTLS_SEQ_SZ);
00737         for (i = 0; i < wordCount; i++) {
00738             ato32(exp + idx, &keys->prevWindow[i]);
00739             idx += OPAQUE32_LEN;
00740         }
00741         idx += wordAdj;
00742 
00743     }
00744 
00745 #ifdef HAVE_TRUNCATED_HMAC
00746     ssl->truncated_hmac = exp[idx++];
00747 #else
00748     idx++; /* no truncated hmac */
00749 #endif
00750     sz = exp[idx++];
00751     if (sz > MAX_DIGEST_SIZE || sz + idx > len) {
00752         return BUFFER_E;
00753     }
00754     XMEMCPY(keys->client_write_MAC_secret, exp + idx, sz); idx += sz;
00755     XMEMCPY(keys->server_write_MAC_secret, exp + idx, sz); idx += sz;
00756 
00757     sz = exp[idx++];
00758     if (sz > AES_256_KEY_SIZE || sz + idx > len) {
00759         return BUFFER_E;
00760     }
00761     XMEMCPY(keys->client_write_key, exp + idx, sz); idx += sz;
00762     XMEMCPY(keys->server_write_key, exp + idx, sz); idx += sz;
00763 
00764     sz = exp[idx++];
00765     if (sz > MAX_WRITE_IV_SZ || sz + idx > len) {
00766         return BUFFER_E;
00767     }
00768     XMEMCPY(keys->client_write_IV, exp + idx, sz); idx += sz;
00769     XMEMCPY(keys->server_write_IV, exp + idx, sz); idx += sz;
00770     XMEMCPY(keys->aead_exp_IV, exp + idx, AEAD_MAX_EXP_SZ);
00771     idx += AEAD_MAX_EXP_SZ;
00772 
00773     sz = exp[idx++];
00774     if (sz > AEAD_MAX_IMP_SZ || sz + idx > len) {
00775         return BUFFER_E;
00776     }
00777     XMEMCPY(keys->aead_enc_imp_IV, exp + idx, sz); idx += sz;
00778     XMEMCPY(keys->aead_dec_imp_IV, exp + idx, sz); idx += sz;
00779 
00780     WOLFSSL_LEAVE("ImportKeyState", idx);
00781     (void)ver;
00782     return idx;
00783 }
00784 
00785 
00786 /* copy over necessary information from Options struct to buffer
00787  * On success returns size of buffer used on failure returns a negative value */
00788 static int dtls_export_new(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00789 {
00790     int idx = 0;
00791     word16 zero = 0;
00792     Options* options = &ssl->options;
00793 
00794     WOLFSSL_ENTER("dtls_export_new");
00795 
00796     if (exp == NULL || options == NULL || len < DTLS_EXPORT_OPT_SZ) {
00797         return BAD_FUNC_ARG;
00798     }
00799 
00800     XMEMSET(exp, 0, DTLS_EXPORT_OPT_SZ);
00801 
00802     /* these options are kept and sent to indicate verify status and strength
00803      * of handshake */
00804     exp[idx++] = options->sendVerify;
00805     exp[idx++] = options->verifyPeer;
00806     exp[idx++] = options->verifyNone;
00807     exp[idx++] = options->downgrade;
00808 #ifndef NO_DH
00809     c16toa(options->minDhKeySz, exp + idx); idx += OPAQUE16_LEN;
00810     c16toa(options->dhKeySz, exp + idx);    idx += OPAQUE16_LEN;
00811 #else
00812     c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
00813     c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
00814 #endif
00815 #ifndef NO_RSA
00816     c16toa((word16)(options->minRsaKeySz), exp + idx); idx += OPAQUE16_LEN;
00817 #else
00818     c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
00819 #endif
00820 #ifdef HAVE_ECC
00821     c16toa((word16)(options->minEccKeySz), exp + idx); idx += OPAQUE16_LEN;
00822 #else
00823     c16toa(zero, exp + idx); idx += OPAQUE16_LEN;
00824 #endif
00825 
00826     /* these options are kept to indicate state and behavior */
00827 #ifndef NO_PSK
00828     exp[idx++] = options->havePSK;
00829 #else
00830     exp[idx++] = 0;
00831 #endif
00832     exp[idx++] = options->sessionCacheOff;
00833     exp[idx++] = options->sessionCacheFlushOff;
00834     exp[idx++] = options->side;
00835     exp[idx++] = options->resuming;
00836     exp[idx++] = options->haveSessionId;
00837     exp[idx++] = options->tls;
00838     exp[idx++] = options->tls1_1;
00839     exp[idx++] = options->dtls;
00840     exp[idx++] = options->connReset;
00841     exp[idx++] = options->isClosed;
00842     exp[idx++] = options->closeNotify;
00843     exp[idx++] = options->sentNotify;
00844     exp[idx++] = options->usingCompression;
00845     exp[idx++] = options->haveRSA;
00846     exp[idx++] = options->haveECC;
00847     exp[idx++] = options->haveDH;
00848     exp[idx++] = options->haveNTRU;
00849     exp[idx++] = options->haveQSH;
00850     exp[idx++] = options->haveECDSAsig;
00851     exp[idx++] = options->haveStaticECC;
00852     exp[idx++] = options->havePeerVerify;
00853     exp[idx++] = options->usingPSK_cipher;
00854     exp[idx++] = options->usingAnon_cipher;
00855     exp[idx++] = options->sendAlertState;
00856     exp[idx++] = options->partialWrite;
00857     exp[idx++] = options->quietShutdown;
00858     exp[idx++] = options->groupMessages;
00859 #ifdef HAVE_POLY1305
00860     exp[idx++] = options->oldPoly;
00861 #else
00862     exp[idx++] = 0;
00863 #endif
00864 #ifdef HAVE_ANON
00865     exp[idx++] = options->haveAnon;
00866 #else
00867     exp[idx++] = 0;
00868 #endif
00869 #ifdef HAVE_SESSION_TICKET
00870     exp[idx++] = options->createTicket;
00871     exp[idx++] = options->useTicket;
00872 #ifdef WOLFSSL_TLS13
00873     exp[idx++] = options->noTicketTls13;
00874 #endif
00875 #else
00876     exp[idx++] = 0;
00877     exp[idx++] = 0;
00878 #ifdef WOLFSSL_TLS13
00879     exp[idx++] = 0;
00880 #endif
00881 #endif
00882     exp[idx++] = options->processReply;
00883     exp[idx++] = options->cipherSuite0;
00884     exp[idx++] = options->cipherSuite;
00885     exp[idx++] = options->serverState;
00886     exp[idx++] = options->clientState;
00887     exp[idx++] = options->handShakeState;
00888     exp[idx++] = options->handShakeDone;
00889     exp[idx++] = options->minDowngrade;
00890     exp[idx++] = options->connectState;
00891     exp[idx++] = options->acceptState;
00892     exp[idx++] = options->asyncState;
00893 
00894     /* version of connection */
00895     exp[idx++] = ssl->version.major;
00896     exp[idx++] = ssl->version.minor;
00897 
00898     (void)zero;
00899     (void)ver;
00900 
00901     /* check if changes were made and notify of need to update export version */
00902     if (idx != DTLS_EXPORT_OPT_SZ) {
00903         WOLFSSL_MSG("Update DTLS_EXPORT_OPT_SZ and version of wolfSSL export");
00904         return DTLS_EXPORT_VER_E;
00905     }
00906 
00907     WOLFSSL_LEAVE("dtls_export_new", idx);
00908 
00909     return idx;
00910 }
00911 
00912 
00913 /* copy items from Export struct to Options struct
00914  * On success returns size of buffer used on failure returns a negative value */
00915 static int dtls_export_load(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
00916 {
00917     int idx = 0;
00918     Options* options = &ssl->options;
00919 
00920     if (ver != DTLS_EXPORT_VERSION) {
00921         WOLFSSL_MSG("Export version not supported");
00922         return BAD_FUNC_ARG;
00923     }
00924 
00925     if (exp == NULL || options == NULL || len < DTLS_EXPORT_OPT_SZ) {
00926         return BAD_FUNC_ARG;
00927     }
00928 
00929     /* these options are kept and sent to indicate verify status and strength
00930      * of handshake */
00931     options->sendVerify = exp[idx++];
00932     options->verifyPeer = exp[idx++];
00933     options->verifyNone = exp[idx++];
00934     options->downgrade  = exp[idx++];
00935 #ifndef NO_DH
00936     ato16(exp + idx, &(options->minDhKeySz)); idx += OPAQUE16_LEN;
00937     ato16(exp + idx, &(options->dhKeySz));    idx += OPAQUE16_LEN;
00938 #else
00939     idx += OPAQUE16_LEN;
00940     idx += OPAQUE16_LEN;
00941 #endif
00942 #ifndef NO_RSA
00943     ato16(exp + idx, (word16*)&(options->minRsaKeySz)); idx += OPAQUE16_LEN;
00944 #else
00945     idx += OPAQUE16_LEN;
00946 #endif
00947 #ifdef HAVE_ECC
00948     ato16(exp + idx, (word16*)&(options->minEccKeySz)); idx += OPAQUE16_LEN;
00949 #else
00950     idx += OPAQUE16_LEN;
00951 #endif
00952 
00953     /* these options are kept to indicate state and behavior */
00954 #ifndef NO_PSK
00955     options->havePSK = exp[idx++];
00956 #else
00957     idx++;
00958 #endif
00959     options->sessionCacheOff      = exp[idx++];
00960     options->sessionCacheFlushOff = exp[idx++];
00961     options->side                 = exp[idx++];
00962     options->resuming             = exp[idx++];
00963     options->haveSessionId    = exp[idx++];
00964     options->tls              = exp[idx++];
00965     options->tls1_1           = exp[idx++];
00966     options->dtls             = exp[idx++];
00967     options->connReset        = exp[idx++];
00968     options->isClosed         = exp[idx++];
00969     options->closeNotify      = exp[idx++];
00970     options->sentNotify       = exp[idx++];
00971     options->usingCompression = exp[idx++];
00972     options->haveRSA          = exp[idx++];
00973     options->haveECC          = exp[idx++];
00974     options->haveDH           = exp[idx++];
00975     options->haveNTRU         = exp[idx++];
00976     options->haveQSH          = exp[idx++];
00977     options->haveECDSAsig     = exp[idx++];
00978     options->haveStaticECC    = exp[idx++];
00979     options->havePeerVerify   = exp[idx++];
00980     options->usingPSK_cipher  = exp[idx++];
00981     options->usingAnon_cipher = exp[idx++];
00982     options->sendAlertState   = exp[idx++];
00983     options->partialWrite     = exp[idx++];
00984     options->quietShutdown    = exp[idx++];
00985     options->groupMessages    = exp[idx++];
00986 #ifdef HAVE_POLY1305
00987     options->oldPoly = exp[idx++];      /* set when to use old rfc way of poly*/
00988 #else
00989     idx++;
00990 #endif
00991 #ifdef HAVE_ANON
00992     options->haveAnon = exp[idx++];     /* User wants to allow Anon suites */
00993 #else
00994     idx++;
00995 #endif
00996 #ifdef HAVE_SESSION_TICKET
00997     options->createTicket  = exp[idx++]; /* Server to create new Ticket */
00998     options->useTicket     = exp[idx++]; /* Use Ticket not session cache */
00999 #ifdef WOLFSSL_TLS13
01000     options->noTicketTls13 = exp[idx++]; /* Server won't create new Ticket */
01001 #endif
01002 #else
01003     idx++;
01004     idx++;
01005 #ifdef WOLFSSL_TLS13
01006     idx++;
01007 #endif
01008 #endif
01009     options->processReply   = exp[idx++];
01010     options->cipherSuite0   = exp[idx++];
01011     options->cipherSuite    = exp[idx++];
01012     options->serverState    = exp[idx++];
01013     options->clientState    = exp[idx++];
01014     options->handShakeState = exp[idx++];
01015     options->handShakeDone  = exp[idx++];
01016     options->minDowngrade   = exp[idx++];
01017     options->connectState   = exp[idx++];
01018     options->acceptState    = exp[idx++];
01019     options->asyncState     = exp[idx++];
01020 
01021     /* version of connection */
01022     if (ssl->version.major != exp[idx++] || ssl->version.minor != exp[idx++]) {
01023         WOLFSSL_MSG("Version mismatch ie DTLS v1 vs v1.2");
01024         return VERSION_ERROR;
01025     }
01026 
01027     return idx;
01028 }
01029 
01030 static int ExportPeerInfo(WOLFSSL* ssl, byte* exp, word32 len, byte ver)
01031 {
01032     int    idx  = 0;
01033     int    ipSz = DTLS_EXPORT_IP; /* start as max size */
01034     int    fam  = 0;
01035     word16 port = 0;
01036     char   ip[DTLS_EXPORT_IP];
01037 
01038     if (ver != DTLS_EXPORT_VERSION) {
01039         WOLFSSL_MSG("Export version not supported");
01040         return BAD_FUNC_ARG;
01041     }
01042 
01043     if (ssl == NULL || exp == NULL || len < sizeof(ip) + 3 * DTLS_EXPORT_LEN) {
01044         return BAD_FUNC_ARG;
01045     }
01046 
01047     if (ssl->ctx->CBGetPeer == NULL) {
01048         WOLFSSL_MSG("No get peer call back set");
01049         return BAD_FUNC_ARG;
01050     }
01051     if (ssl->ctx->CBGetPeer(ssl, ip, &ipSz, &port, &fam) != SSL_SUCCESS) {
01052         WOLFSSL_MSG("Get peer callback error");
01053         return SOCKET_ERROR_E;
01054     }
01055 
01056     /* check that ipSz/fam is not negative or too large since user can set cb */
01057     if (ipSz < 0 || ipSz > DTLS_EXPORT_IP || fam < 0) {
01058         WOLFSSL_MSG("Bad ipSz or fam returned from get peer callback");
01059         return SOCKET_ERROR_E;
01060     }
01061 
01062     c16toa((word16)fam, exp + idx);  idx += DTLS_EXPORT_LEN;
01063     c16toa((word16)ipSz, exp + idx); idx += DTLS_EXPORT_LEN;
01064     XMEMCPY(exp + idx, ip, ipSz);    idx += ipSz;
01065     c16toa(port, exp + idx);         idx += DTLS_EXPORT_LEN;
01066 
01067     return idx;
01068 }
01069 
01070 
01071 static int ImportPeerInfo(WOLFSSL* ssl, byte* buf, word32 len, byte ver)
01072 {
01073     word16 idx = 0;
01074     word16 ipSz;
01075     word16 fam;
01076     word16 port;
01077     char   ip[DTLS_EXPORT_IP];
01078 
01079     if (ver != DTLS_EXPORT_VERSION) {
01080         WOLFSSL_MSG("Export version not supported");
01081         return BAD_FUNC_ARG;
01082     }
01083 
01084     if (ssl == NULL || buf == NULL || len < 3 * DTLS_EXPORT_LEN) {
01085         return BAD_FUNC_ARG;
01086     }
01087 
01088     /* import sin family */
01089     ato16(buf + idx, &fam); idx += DTLS_EXPORT_LEN;
01090 
01091     /* import ip address idx, and ipSz are unsigned but cast for enum */
01092     ato16(buf + idx, &ipSz); idx += DTLS_EXPORT_LEN;
01093     if (ipSz >= sizeof(ip) || (word16)(idx + ipSz + DTLS_EXPORT_LEN) > len) {
01094         return BUFFER_E;
01095     }
01096     XMEMSET(ip, 0, sizeof(ip));
01097     XMEMCPY(ip, buf + idx, ipSz); idx += ipSz;
01098     ip[ipSz] = '\0'; /* with check that ipSz less than ip this is valid */
01099     ato16(buf + idx, &port); idx += DTLS_EXPORT_LEN;
01100 
01101     /* sanity check for a function to call, then use it to import peer info */
01102     if (ssl->ctx->CBSetPeer == NULL) {
01103         WOLFSSL_MSG("No set peer function");
01104         return BAD_FUNC_ARG;
01105     }
01106     if (ssl->ctx->CBSetPeer(ssl, ip, ipSz, port, fam) != SSL_SUCCESS) {
01107         WOLFSSL_MSG("Error setting peer info");
01108         return SOCKET_ERROR_E;
01109     }
01110 
01111     return idx;
01112 }
01113 
01114 
01115 /* WOLFSSL_LOCAL function that serializes the current WOLFSSL session
01116  * buf is used to hold the serialized WOLFSSL struct and sz is the size of buf
01117  * passed in.
01118  * On success returns the size of serialized session.*/
01119 int wolfSSL_dtls_export_internal(WOLFSSL* ssl, byte* buf, word32 sz)
01120 {
01121     int ret;
01122     word32 idx      = 0;
01123     word32 totalLen = 0;
01124 
01125     WOLFSSL_ENTER("wolfSSL_dtls_export_internal");
01126 
01127     if (buf == NULL || ssl == NULL) {
01128         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BAD_FUNC_ARG);
01129         return BAD_FUNC_ARG;
01130     }
01131 
01132     totalLen += DTLS_EXPORT_LEN * 2; /* 2 protocol bytes and 2 length bytes */
01133     /* each of the following have a 2 byte length before data */
01134     totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_OPT_SZ;
01135     totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_KEY_SZ;
01136     totalLen += DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ;
01137     totalLen += DTLS_EXPORT_LEN + ssl->buffers.dtlsCtx.peer.sz;
01138 
01139     if (totalLen > sz) {
01140         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", BUFFER_E);
01141         return BUFFER_E;
01142     }
01143 
01144     buf[idx++] =  (byte)DTLS_EXPORT_PRO;
01145     buf[idx++] = ((byte)DTLS_EXPORT_PRO & 0xF0) |
01146                  ((byte)DTLS_EXPORT_VERSION & 0X0F);
01147 
01148     idx += DTLS_EXPORT_LEN; /* leave spot for length */
01149 
01150     c16toa((word16)DTLS_EXPORT_OPT_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
01151     if ((ret = dtls_export_new(ssl, buf + idx, sz - idx,
01152                                                     DTLS_EXPORT_VERSION)) < 0) {
01153         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
01154         return ret;
01155     }
01156     idx += ret;
01157 
01158     /* export keys struct and dtls state -- variable length stored in ret */
01159     idx += DTLS_EXPORT_LEN; /* leave room for length */
01160     if ((ret = ExportKeyState(ssl, buf + idx, sz - idx,
01161                                                     DTLS_EXPORT_VERSION)) < 0) {
01162         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
01163         return ret;
01164     }
01165     c16toa((word16)ret, buf + idx - DTLS_EXPORT_LEN); idx += ret;
01166 
01167     /* export of cipher specs struct */
01168     c16toa((word16)DTLS_EXPORT_SPC_SZ, buf + idx); idx += DTLS_EXPORT_LEN;
01169     if ((ret = ExportCipherSpecState(ssl, buf + idx, sz - idx,
01170                                                     DTLS_EXPORT_VERSION)) < 0) {
01171         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
01172         return ret;
01173     }
01174     idx += ret;
01175 
01176     /* export of dtls peer information */
01177     idx += DTLS_EXPORT_LEN;
01178     if ((ret = ExportPeerInfo(ssl, buf + idx, sz - idx,
01179                                                     DTLS_EXPORT_VERSION)) < 0) {
01180         WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", ret);
01181         return ret;
01182     }
01183     c16toa(ret, buf + idx - DTLS_EXPORT_LEN);
01184     idx += ret;
01185 
01186     /* place total length of exported buffer minus 2 bytes protocol/version */
01187     c16toa((word16)(idx - DTLS_EXPORT_LEN), buf + DTLS_EXPORT_LEN);
01188 
01189     /* if compiled with debug options then print the version, protocol, size */
01190 #ifdef WOLFSSL_SESSION_EXPORT_DEBUG
01191     {
01192         char debug[256];
01193         snprintf(debug, sizeof(debug), "Exporting DTLS session\n"
01194                    "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
01195                , (int)DTLS_EXPORT_VERSION, buf[0], (buf[1] >> 4), idx - 2);
01196         WOLFSSL_MSG(debug);
01197     }
01198 #endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
01199 
01200     WOLFSSL_LEAVE("wolfSSL_dtls_export_internal", idx);
01201     return idx;
01202 }
01203 
01204 
01205 /* On success return amount of buffer consumed */
01206 int wolfSSL_dtls_import_internal(WOLFSSL* ssl, byte* buf, word32 sz)
01207 {
01208     word32 idx    = 0;
01209     word16 length = 0;
01210     int version;
01211     int ret;
01212 
01213     WOLFSSL_ENTER("wolfSSL_dtls_import_internal");
01214     /* check at least enough room for protocol and length */
01215     if (sz < DTLS_EXPORT_LEN * 2 || ssl == NULL) {
01216         return BAD_FUNC_ARG;
01217     }
01218 
01219     /* sanity check on protocol ID and size of buffer */
01220     if (buf[idx++]       !=  (byte)DTLS_EXPORT_PRO ||
01221        (buf[idx] & 0xF0) != ((byte)DTLS_EXPORT_PRO & 0xF0)) {
01222         /* don't increment on second idx to next get version */
01223         WOLFSSL_MSG("Incorrect protocol");
01224         return BAD_FUNC_ARG;
01225     }
01226     version = buf[idx++] & 0x0F;
01227 
01228     ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
01229     if (length > sz - DTLS_EXPORT_LEN) { /* subtract 2 for protocol */
01230         return BUFFER_E;
01231     }
01232 
01233     /* if compiled with debug options then print the version, protocol, size */
01234 #ifdef WOLFSSL_SESSION_EXPORT_DEBUG
01235     {
01236         char debug[256];
01237         snprintf(debug, sizeof(debug), "Importing DTLS session\n"
01238                    "\tVersion  : %d\n\tProtocol : %02X%01X\n\tLength of: %d\n\n"
01239                , (int)version, buf[0], (buf[1] >> 4), length);
01240         WOLFSSL_MSG(debug);
01241     }
01242 #endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
01243 
01244     /* perform sanity checks and extract Options information used */
01245     if (DTLS_EXPORT_LEN + DTLS_EXPORT_OPT_SZ + idx > sz) {
01246         WOLFSSL_MSG("Import Options struct error");
01247         return BUFFER_E;
01248     }
01249     ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
01250     if (length != DTLS_EXPORT_OPT_SZ) {
01251         WOLFSSL_MSG("Import Options struct error");
01252         return BUFFER_E;
01253     }
01254     if ((ret = dtls_export_load(ssl, buf + idx, length, version)) < 0) {
01255         WOLFSSL_MSG("Import Options struct error");
01256         return ret;
01257     }
01258     idx += length;
01259 
01260     /* perform sanity checks and extract Keys struct */
01261     if (DTLS_EXPORT_LEN + idx > sz) {
01262         WOLFSSL_MSG("Import Key struct error");
01263         return BUFFER_E;
01264     }
01265     ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
01266     if (length > DTLS_EXPORT_KEY_SZ || length + idx > sz) {
01267         WOLFSSL_MSG("Import Key struct error");
01268         return BUFFER_E;
01269     }
01270     if ((ret = ImportKeyState(ssl, buf + idx, length, version)) < 0) {
01271         WOLFSSL_MSG("Import Key struct error");
01272         return ret;
01273     }
01274     idx += ret;
01275 
01276     /* perform sanity checks and extract CipherSpecs struct */
01277     if (DTLS_EXPORT_LEN + DTLS_EXPORT_SPC_SZ + idx > sz) {
01278         WOLFSSL_MSG("Import CipherSpecs struct error");
01279         return BUFFER_E;
01280     }
01281     ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
01282     if ( length != DTLS_EXPORT_SPC_SZ) {
01283         WOLFSSL_MSG("Import CipherSpecs struct error");
01284         return BUFFER_E;
01285     }
01286     if ((ret = ImportCipherSpecState(ssl, buf + idx, length, version)) < 0) {
01287         WOLFSSL_MSG("Import CipherSpecs struct error");
01288         return ret;
01289     }
01290     idx += ret;
01291 
01292     /* perform sanity checks and extract DTLS peer info */
01293     if (DTLS_EXPORT_LEN + idx > sz) {
01294         WOLFSSL_MSG("Import DTLS peer info error");
01295         return BUFFER_E;
01296     }
01297     ato16(buf + idx, &length); idx += DTLS_EXPORT_LEN;
01298     if (idx + length > sz) {
01299         WOLFSSL_MSG("Import DTLS peer info error");
01300         return BUFFER_E;
01301     }
01302     if ((ret = ImportPeerInfo(ssl, buf + idx, length, version)) < 0) {
01303         WOLFSSL_MSG("Import Peer Addr error");
01304         return ret;
01305     }
01306     idx += ret;
01307 
01308     SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
01309 
01310     /* set hmac function to use when verifying */
01311     if (ssl->options.tls == 1 || ssl->options.tls1_1 == 1 ||
01312             ssl->options.dtls == 1) {
01313         ssl->hmac = TLS_hmac;
01314     }
01315 
01316     /* make sure is a valid suite used */
01317     if (wolfSSL_get_cipher(ssl) == NULL) {
01318         WOLFSSL_MSG("Can not match cipher suite imported");
01319         return MATCH_SUITE_ERROR;
01320     }
01321 
01322     /* do not allow stream ciphers with DTLS */
01323     if (ssl->specs.cipher_type == stream) {
01324         WOLFSSL_MSG("Can not import stream ciphers for DTLS");
01325         return SANITY_CIPHER_E;
01326     }
01327 
01328     return idx;
01329 }
01330 #endif /* WOLFSSL_DTLS */
01331 #endif /* WOLFSSL_SESSION_EXPORT */
01332 
01333 
01334 void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv)
01335 {
01336     method->version    = pv;
01337     method->side       = WOLFSSL_CLIENT_END;
01338     method->downgrade  = 0;
01339 }
01340 
01341 
01342 /* Initialize SSL context, return 0 on success */
01343 int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
01344 {
01345     int ret = 0;
01346 
01347     XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX));
01348 
01349     ctx->method   = method;
01350     ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
01351     ctx->heap     = ctx;        /* defaults to self */
01352     ctx->timeout  = WOLFSSL_SESSION_TIMEOUT;
01353     ctx->minDowngrade = TLSv1_MINOR;     /* current default */
01354 
01355     if (wc_InitMutex(&ctx->countMutex) < 0) {
01356         WOLFSSL_MSG("Mutex error on CTX init");
01357         ctx->err = CTX_INIT_MUTEX_E;
01358         return BAD_MUTEX_E;
01359     }
01360 
01361 #ifndef NO_DH
01362     ctx->minDhKeySz  = MIN_DHKEY_SZ;
01363 #endif
01364 #ifndef NO_RSA
01365     ctx->minRsaKeySz = MIN_RSAKEY_SZ;
01366 #endif
01367 #ifdef HAVE_ECC
01368     ctx->minEccKeySz  = MIN_ECCKEY_SZ;
01369     ctx->eccTempKeySz = ECDHE_SIZE;
01370 #endif
01371 
01372 #ifndef WOLFSSL_USER_IO
01373     ctx->CBIORecv = EmbedReceive;
01374     ctx->CBIOSend = EmbedSend;
01375     #ifdef WOLFSSL_DTLS
01376         if (method->version.major == DTLS_MAJOR) {
01377             ctx->CBIORecv   = EmbedReceiveFrom;
01378             ctx->CBIOSend   = EmbedSendTo;
01379         }
01380         #ifdef WOLFSSL_SESSION_EXPORT
01381         ctx->CBGetPeer = EmbedGetPeer;
01382         ctx->CBSetPeer = EmbedSetPeer;
01383         #endif
01384     #endif
01385 #endif /* WOLFSSL_USER_IO */
01386 
01387 #ifdef HAVE_NETX
01388     ctx->CBIORecv = NetX_Receive;
01389     ctx->CBIOSend = NetX_Send;
01390 #endif
01391 
01392 #ifdef HAVE_NTRU
01393     if (method->side == WOLFSSL_CLIENT_END)
01394         ctx->haveNTRU = 1;           /* always on cliet side */
01395                                      /* server can turn on by loading key */
01396 #endif
01397 #ifdef HAVE_ECC
01398     if (method->side == WOLFSSL_CLIENT_END) {
01399         ctx->haveECDSAsig  = 1;        /* always on cliet side */
01400         ctx->haveECC  = 1;             /* server turns on with ECC key cert */
01401         ctx->haveStaticECC = 1;        /* server can turn on by loading key */
01402     }
01403 #endif
01404 
01405     ctx->devId = INVALID_DEVID;
01406 
01407 #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SCTP)
01408     ctx->dtlsMtuSz = MAX_RECORD_SIZE;
01409 #endif
01410 
01411 #ifndef NO_CERTS
01412     ctx->cm = wolfSSL_CertManagerNew_ex(heap);
01413     if (ctx->cm == NULL) {
01414         WOLFSSL_MSG("Bad Cert Manager New");
01415         return BAD_CERT_MANAGER_ERROR;
01416     }
01417     #ifdef OPENSSL_EXTRA
01418     /* setup WOLFSSL_X509_STORE */
01419     ctx->x509_store.cm = ctx->cm;
01420     #endif
01421 #endif
01422 
01423 #if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT)
01424     if (method->side == WOLFSSL_CLIENT_END) {
01425         if ((method->version.major == SSLv3_MAJOR) &&
01426              (method->version.minor >= TLSv1_MINOR)) {
01427 
01428             ctx->haveEMS = 1;
01429         }
01430 #ifdef WOLFSSL_DTLS
01431         if (method->version.major == DTLS_MAJOR)
01432             ctx->haveEMS = 1;
01433 #endif /* WOLFSSL_DTLS */
01434     }
01435 #endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */
01436 
01437 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
01438     ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
01439 #endif
01440 
01441 #ifdef HAVE_WOLF_EVENT
01442     ret = wolfEventQueue_Init(&ctx->event_queue);
01443 #endif /* HAVE_WOLF_EVENT */
01444 
01445     ctx->heap = heap; /* wolfSSL_CTX_load_static_memory sets */
01446 
01447     return ret;
01448 }
01449 
01450 
01451 /* In case contexts are held in array and don't want to free actual ctx */
01452 void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
01453 {
01454 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
01455     int i;
01456 #endif
01457 
01458 #ifdef HAVE_WOLF_EVENT
01459     wolfEventQueue_Free(&ctx->event_queue);
01460 #endif /* HAVE_WOLF_EVENT */
01461 
01462     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
01463     if (ctx->suites)
01464         XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
01465 
01466 #ifndef NO_DH
01467     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01468     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH_BUFFER);
01469 #endif /* !NO_DH */
01470 
01471 #ifdef SINGLE_THREADED
01472     if (ctx->rng) {
01473         wc_FreeRng(ctx->rng);
01474         XFREE(ctx->rng, ctx->heap, DYNAMIC_TYPE_RNG);
01475     }
01476 #endif /* SINGLE_THREADED */
01477 
01478 #ifndef NO_CERTS
01479     FreeDer(&ctx->privateKey);
01480     FreeDer(&ctx->certificate);
01481     #ifdef KEEP_OUR_CERT
01482         if (ctx->ourCert && ctx->ownOurCert) {
01483             FreeX509(ctx->ourCert);
01484             XFREE(ctx->ourCert, ctx->heap, DYNAMIC_TYPE_X509);
01485         }
01486     #endif /* KEEP_OUR_CERT */
01487     FreeDer(&ctx->certChain);
01488     wolfSSL_CertManagerFree(ctx->cm);
01489     #ifdef OPENSSL_EXTRA
01490         while (ctx->ca_names != NULL) {
01491             WOLFSSL_STACK *next = ctx->ca_names->next;
01492             wolfSSL_X509_NAME_free(ctx->ca_names->data.name);
01493             XFREE(ctx->ca_names->data.name, NULL, DYNAMIC_TYPE_OPENSSL);
01494             XFREE(ctx->ca_names, NULL, DYNAMIC_TYPE_OPENSSL);
01495             ctx->ca_names = next;
01496         }
01497     #endif
01498     #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
01499         while (ctx->x509Chain != NULL) {
01500             WOLFSSL_STACK *next = ctx->x509Chain->next;
01501             wolfSSL_X509_free(ctx->x509Chain->data.x509);
01502             XFREE(ctx->x509Chain, NULL, DYNAMIC_TYPE_OPENSSL);
01503             ctx->x509Chain = next;
01504         }
01505     #endif
01506 #endif /* !NO_CERTS */
01507 
01508 #ifdef HAVE_TLS_EXTENSIONS
01509     TLSX_FreeAll(ctx->extensions, ctx->heap);
01510 
01511 #ifndef NO_WOLFSSL_SERVER
01512 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
01513  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
01514     if (ctx->certOcspRequest) {
01515         FreeOcspRequest(ctx->certOcspRequest);
01516         XFREE(ctx->certOcspRequest, ctx->heap, DYNAMIC_TYPE_OCSP_REQUEST);
01517     }
01518 #endif
01519 
01520 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
01521     for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
01522         if (ctx->chainOcspRequest[i]) {
01523             FreeOcspRequest(ctx->chainOcspRequest[i]);
01524             XFREE(ctx->chainOcspRequest[i], ctx->heap, DYNAMIC_TYPE_OCSP_REQUEST);
01525         }
01526     }
01527 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
01528 #endif /* !NO_WOLFSSL_SERVER */
01529 
01530 #endif /* HAVE_TLS_EXTENSIONS */
01531 
01532 #ifdef WOLFSSL_STATIC_MEMORY
01533     if (ctx->heap != NULL) {
01534 #ifdef WOLFSSL_HEAP_TEST
01535         /* avoid derefrencing a test value */
01536         if (ctx->heap != (void*)WOLFSSL_HEAP_TEST)
01537 #endif
01538         {
01539             WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)(ctx->heap);
01540             wc_FreeMutex(&((WOLFSSL_HEAP*)(hint->memory))->memory_mutex);
01541         }
01542     }
01543 #endif /* WOLFSSL_STATIC_MEMORY */
01544 }
01545 
01546 
01547 void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
01548 {
01549     int doFree = 0;
01550 
01551     if (wc_LockMutex(&ctx->countMutex) != 0) {
01552         WOLFSSL_MSG("Couldn't lock count mutex");
01553 
01554         /* check error state, if mutex error code then mutex init failed but
01555          * CTX was still malloc'd */
01556         if (ctx->err == CTX_INIT_MUTEX_E) {
01557             SSL_CtxResourceFree(ctx);
01558             XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
01559         }
01560         return;
01561     }
01562     ctx->refCount--;
01563     if (ctx->refCount == 0)
01564         doFree = 1;
01565     wc_UnLockMutex(&ctx->countMutex);
01566 
01567     if (doFree) {
01568         WOLFSSL_MSG("CTX ref count down to 0, doing full free");
01569         SSL_CtxResourceFree(ctx);
01570         wc_FreeMutex(&ctx->countMutex);
01571         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
01572     }
01573     else {
01574         (void)ctx;
01575         WOLFSSL_MSG("CTX ref count not 0 yet, no free");
01576     }
01577 }
01578 
01579 
01580 /* Set cipher pointers to null */
01581 void InitCiphers(WOLFSSL* ssl)
01582 {
01583 #ifdef BUILD_ARC4
01584     ssl->encrypt.arc4 = NULL;
01585     ssl->decrypt.arc4 = NULL;
01586 #endif
01587 #ifdef BUILD_DES3
01588     ssl->encrypt.des3 = NULL;
01589     ssl->decrypt.des3 = NULL;
01590 #endif
01591 #ifdef BUILD_AES
01592     ssl->encrypt.aes = NULL;
01593     ssl->decrypt.aes = NULL;
01594 #endif
01595 #ifdef HAVE_CAMELLIA
01596     ssl->encrypt.cam = NULL;
01597     ssl->decrypt.cam = NULL;
01598 #endif
01599 #ifdef HAVE_HC128
01600     ssl->encrypt.hc128 = NULL;
01601     ssl->decrypt.hc128 = NULL;
01602 #endif
01603 #ifdef BUILD_RABBIT
01604     ssl->encrypt.rabbit = NULL;
01605     ssl->decrypt.rabbit = NULL;
01606 #endif
01607 #ifdef HAVE_CHACHA
01608     ssl->encrypt.chacha = NULL;
01609     ssl->decrypt.chacha = NULL;
01610 #endif
01611 #ifdef HAVE_POLY1305
01612     ssl->auth.poly1305 = NULL;
01613 #endif
01614     ssl->encrypt.setup = 0;
01615     ssl->decrypt.setup = 0;
01616 #ifdef HAVE_ONE_TIME_AUTH
01617     ssl->auth.setup    = 0;
01618 #endif
01619 #ifdef HAVE_IDEA
01620     ssl->encrypt.idea = NULL;
01621     ssl->decrypt.idea = NULL;
01622 #endif
01623 }
01624 
01625 
01626 /* Free ciphers */
01627 void FreeCiphers(WOLFSSL* ssl)
01628 {
01629     (void)ssl;
01630 #ifdef BUILD_ARC4
01631     wc_Arc4Free(ssl->encrypt.arc4);
01632     wc_Arc4Free(ssl->decrypt.arc4);
01633     XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
01634     XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
01635 #endif
01636 #ifdef BUILD_DES3
01637     wc_Des3Free(ssl->encrypt.des3);
01638     wc_Des3Free(ssl->decrypt.des3);
01639     XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
01640     XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
01641 #endif
01642 #ifdef BUILD_AES
01643     wc_AesFree(ssl->encrypt.aes);
01644     wc_AesFree(ssl->decrypt.aes);
01645     #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
01646         XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_AES);
01647         XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES);
01648         XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_AES);
01649         XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES);
01650     #endif
01651     XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
01652     XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
01653 #endif
01654 #ifdef HAVE_CAMELLIA
01655     XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
01656     XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
01657 #endif
01658 #ifdef HAVE_HC128
01659     XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
01660     XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
01661 #endif
01662 #ifdef BUILD_RABBIT
01663     XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
01664     XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
01665 #endif
01666 #ifdef HAVE_CHACHA
01667     XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
01668     XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
01669 #endif
01670 #ifdef HAVE_POLY1305
01671     XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
01672 #endif
01673 #ifdef HAVE_IDEA
01674     XFREE(ssl->encrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
01675     XFREE(ssl->decrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
01676 #endif
01677 }
01678 
01679 
01680 void InitCipherSpecs(CipherSpecs* cs)
01681 {
01682     cs->bulk_cipher_algorithm = INVALID_BYTE;
01683     cs->cipher_type           = INVALID_BYTE;
01684     cs->mac_algorithm         = INVALID_BYTE;
01685     cs->kea                   = INVALID_BYTE;
01686     cs->sig_algo              = INVALID_BYTE;
01687 
01688     cs->hash_size   = 0;
01689     cs->static_ecdh = 0;
01690     cs->key_size    = 0;
01691     cs->iv_size     = 0;
01692     cs->block_size  = 0;
01693 }
01694 
01695 static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
01696                                                   int haveRSAsig, int haveAnon)
01697 {
01698     int idx = 0;
01699 
01700     if (haveECDSAsig) {
01701         #ifdef WOLFSSL_SHA512
01702             suites->hashSigAlgo[idx++] = sha512_mac;
01703             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01704         #endif
01705         #ifdef WOLFSSL_SHA384
01706             suites->hashSigAlgo[idx++] = sha384_mac;
01707             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01708         #endif
01709         #ifndef NO_SHA256
01710             suites->hashSigAlgo[idx++] = sha256_mac;
01711             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01712         #endif
01713         #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
01714                                                 defined(WOLFSSL_ALLOW_TLS_SHA1))
01715             suites->hashSigAlgo[idx++] = sha_mac;
01716             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
01717         #endif
01718     }
01719 
01720     if (haveRSAsig) {
01721         #ifdef WOLFSSL_SHA512
01722             suites->hashSigAlgo[idx++] = sha512_mac;
01723             suites->hashSigAlgo[idx++] = rsa_sa_algo;
01724         #endif
01725         #ifdef WOLFSSL_SHA384
01726             suites->hashSigAlgo[idx++] = sha384_mac;
01727             suites->hashSigAlgo[idx++] = rsa_sa_algo;
01728         #endif
01729         #ifndef NO_SHA256
01730             suites->hashSigAlgo[idx++] = sha256_mac;
01731             suites->hashSigAlgo[idx++] = rsa_sa_algo;
01732         #endif
01733         #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
01734                                                 defined(WOLFSSL_ALLOW_TLS_SHA1))
01735             suites->hashSigAlgo[idx++] = sha_mac;
01736             suites->hashSigAlgo[idx++] = rsa_sa_algo;
01737         #endif
01738     }
01739 
01740     if (haveAnon) {
01741         #ifdef HAVE_ANON
01742             suites->hashSigAlgo[idx++] = sha_mac;
01743             suites->hashSigAlgo[idx++] = anonymous_sa_algo;
01744         #endif
01745     }
01746 
01747     suites->hashSigAlgoSz = (word16)idx;
01748 }
01749 
01750 void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA,
01751                 word16 havePSK, word16 haveDH, word16 haveNTRU,
01752                 word16 haveECDSAsig, word16 haveECC,
01753                 word16 haveStaticECC, int side)
01754 {
01755     word16 idx = 0;
01756     int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
01757     int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
01758 #ifdef WOLFSSL_TLS13
01759     int    tls1_3 = IsAtLeastTLSv1_3(pv);
01760 #endif
01761     int    dtls   = 0;
01762     int    haveRSAsig = 1;
01763 
01764     (void)tls;  /* shut up compiler */
01765     (void)tls1_2;
01766     (void)dtls;
01767     (void)haveDH;
01768     (void)havePSK;
01769     (void)haveNTRU;
01770     (void)haveStaticECC;
01771     (void)haveECC;
01772 
01773     if (suites == NULL) {
01774         WOLFSSL_MSG("InitSuites pointer error");
01775         return;
01776     }
01777 
01778     if (suites->setSuites)
01779         return;      /* trust user settings, don't override */
01780 
01781     if (side == WOLFSSL_SERVER_END && haveStaticECC) {
01782         haveRSA = 0;   /* can't do RSA with ECDSA key */
01783         (void)haveRSA; /* some builds won't read */
01784     }
01785 
01786     if (side == WOLFSSL_SERVER_END && haveECDSAsig) {
01787         haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
01788         (void)haveRSAsig;   /* non ecc builds won't read */
01789     }
01790 
01791 #ifdef WOLFSSL_DTLS
01792     if (pv.major == DTLS_MAJOR) {
01793         dtls   = 1;
01794         tls    = 1;
01795         /* May be dead assignments dependant upon configuration */
01796         (void) dtls;
01797         (void) tls;
01798         tls1_2 = pv.minor <= DTLSv1_2_MINOR;
01799     }
01800 #endif
01801 
01802 #ifdef HAVE_RENEGOTIATION_INDICATION
01803     if (side == WOLFSSL_CLIENT_END) {
01804         suites->suites[idx++] = 0;
01805         suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
01806     }
01807 #endif
01808 
01809 #ifdef BUILD_TLS_QSH
01810     if (tls) {
01811         suites->suites[idx++] = QSH_BYTE;
01812         suites->suites[idx++] = TLS_QSH;
01813     }
01814 #endif
01815 
01816 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
01817    if (tls && haveNTRU && haveRSA) {
01818         suites->suites[idx++] = 0;
01819         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
01820    }
01821 #endif
01822 
01823 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
01824     if (tls && haveNTRU && haveRSA) {
01825         suites->suites[idx++] = 0;
01826         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
01827     }
01828 #endif
01829 
01830 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
01831     if (!dtls && tls && haveNTRU && haveRSA) {
01832         suites->suites[idx++] = 0;
01833         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
01834     }
01835 #endif
01836 
01837 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
01838     if (tls && haveNTRU && haveRSA) {
01839         suites->suites[idx++] = 0;
01840         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
01841     }
01842 #endif
01843 
01844 #ifdef WOLFSSL_TLS13
01845 #ifdef BUILD_TLS_AES_128_GCM_SHA256
01846     if (tls1_3) {
01847         suites->suites[idx++] = TLS13_BYTE;
01848         suites->suites[idx++] = TLS_AES_128_GCM_SHA256;
01849     }
01850 #endif
01851 
01852 #ifdef BUILD_TLS_AES_256_GCM_SHA384
01853     if (tls1_3) {
01854         suites->suites[idx++] = TLS13_BYTE;
01855         suites->suites[idx++] = TLS_AES_256_GCM_SHA384;
01856     }
01857 #endif
01858 
01859 #ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
01860     if (tls1_3) {
01861         suites->suites[idx++] = TLS13_BYTE;
01862         suites->suites[idx++] = TLS_CHACHA20_POLY1305_SHA256;
01863     }
01864 #endif
01865 
01866 #ifdef BUILD_TLS_AES_128_CCM_SHA256
01867     if (tls1_3) {
01868         suites->suites[idx++] = TLS13_BYTE;
01869         suites->suites[idx++] = TLS_AES_128_CCM_SHA256;
01870     }
01871 #endif
01872 
01873 #ifdef BUILD_TLS_AES_128_CCM_8_SHA256
01874     if (tls1_3) {
01875         suites->suites[idx++] = TLS13_BYTE;
01876         suites->suites[idx++] = TLS_AES_128_CCM_8_SHA256;
01877     }
01878 #endif
01879 #endif /* WOLFSSL_TLS13 */
01880 
01881 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
01882     if (tls1_2 && haveECC) {
01883         suites->suites[idx++] = ECC_BYTE;
01884         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
01885     }
01886 #endif
01887 
01888 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
01889     if (tls1_2 && haveECC) {
01890         suites->suites[idx++] = ECC_BYTE;
01891         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
01892     }
01893 #endif
01894 
01895 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
01896     if (tls1_2 && haveRSA) {
01897         suites->suites[idx++] = ECC_BYTE;
01898         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
01899     }
01900 #endif
01901 
01902 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
01903     if (tls1_2 && haveRSA) {
01904         suites->suites[idx++] = ECC_BYTE;
01905         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
01906     }
01907 #endif
01908 
01909 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
01910     if (tls1_2 && haveDH && haveRSA) {
01911         suites->suites[idx++] = 0;
01912         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
01913     }
01914 #endif
01915 
01916 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
01917     if (tls1_2 && haveDH && haveRSA) {
01918         suites->suites[idx++] = 0;
01919         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
01920     }
01921 #endif
01922 
01923 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
01924     if (tls1_2 && haveRSA) {
01925         suites->suites[idx++] = 0;
01926         suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
01927     }
01928 #endif
01929 
01930 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
01931     if (tls1_2 && haveRSA) {
01932         suites->suites[idx++] = 0;
01933         suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
01934     }
01935 #endif
01936 
01937 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
01938     if (tls1_2 && haveECC && haveStaticECC) {
01939         suites->suites[idx++] = ECC_BYTE;
01940         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
01941     }
01942 #endif
01943 
01944 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
01945     if (tls1_2 && haveECC && haveStaticECC) {
01946         suites->suites[idx++] = ECC_BYTE;
01947         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
01948     }
01949 #endif
01950 
01951 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
01952     if (tls1_2 && haveRSAsig && haveStaticECC) {
01953         suites->suites[idx++] = ECC_BYTE;
01954         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
01955     }
01956 #endif
01957 
01958 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
01959     if (tls1_2 && haveRSAsig && haveStaticECC) {
01960         suites->suites[idx++] = ECC_BYTE;
01961         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
01962     }
01963 #endif
01964 
01965 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
01966     if (tls1_2 && haveDH && havePSK) {
01967         suites->suites[idx++] = 0;
01968         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
01969     }
01970 #endif
01971 
01972 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
01973     if (tls1_2 && haveDH && havePSK) {
01974         suites->suites[idx++] = 0;
01975         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
01976     }
01977 #endif
01978 
01979 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
01980     if (tls1_2 && havePSK) {
01981         suites->suites[idx++] = 0;
01982         suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
01983     }
01984 #endif
01985 
01986 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
01987     if (tls1_2 && havePSK) {
01988         suites->suites[idx++] = 0;
01989         suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
01990     }
01991 #endif
01992 
01993 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
01994     if (tls1_2 && haveECC) {
01995         suites->suites[idx++] = CHACHA_BYTE;
01996         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
01997     }
01998 #endif
01999 
02000 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
02001     if (tls1_2 && haveRSA) {
02002         suites->suites[idx++] = CHACHA_BYTE;
02003         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
02004     }
02005 #endif
02006 
02007 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
02008     if (tls1_2 && haveRSA) {
02009         suites->suites[idx++] = CHACHA_BYTE;
02010         suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
02011     }
02012 #endif
02013 
02014 /* Place as higher priority for MYSQL */
02015 #if defined(WOLFSSL_MYSQL_COMPATIBLE)
02016 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
02017     if (tls && haveDH && haveRSA) {
02018         suites->suites[idx++] = 0;
02019         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
02020     }
02021 #endif
02022 #endif
02023 
02024 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
02025     if (tls1_2 && haveRSA) {
02026         suites->suites[idx++] = ECC_BYTE;
02027         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
02028     }
02029 #endif
02030 
02031 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
02032     if (tls1_2 && haveECC) {
02033         suites->suites[idx++] = ECC_BYTE;
02034         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
02035     }
02036 #endif
02037 
02038 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
02039     if (tls1_2 && haveRSAsig && haveStaticECC) {
02040         suites->suites[idx++] = ECC_BYTE;
02041         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
02042     }
02043 #endif
02044 
02045 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
02046     if (tls1_2 && haveECC && haveStaticECC) {
02047         suites->suites[idx++] = ECC_BYTE;
02048         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
02049     }
02050 #endif
02051 
02052 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
02053     if (tls1_2 && haveRSA) {
02054         suites->suites[idx++] = ECC_BYTE;
02055         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
02056     }
02057 #endif
02058 
02059 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
02060     if (tls1_2 && haveECC) {
02061         suites->suites[idx++] = ECC_BYTE;
02062         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
02063     }
02064 #endif
02065 
02066 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
02067     if (tls1_2 && haveRSAsig && haveStaticECC) {
02068         suites->suites[idx++] = ECC_BYTE;
02069         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
02070     }
02071 #endif
02072 
02073 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
02074     if (tls1_2 && haveECC && haveStaticECC) {
02075         suites->suites[idx++] = ECC_BYTE;
02076         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
02077     }
02078 #endif
02079 
02080 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
02081     if (tls && haveECC) {
02082         suites->suites[idx++] = ECC_BYTE;
02083         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
02084     }
02085 #endif
02086 
02087 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
02088     if (tls && haveECC && haveStaticECC) {
02089         suites->suites[idx++] = ECC_BYTE;
02090         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
02091     }
02092 #endif
02093 
02094 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
02095     if (tls && haveECC) {
02096         suites->suites[idx++] = ECC_BYTE;
02097         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
02098     }
02099 #endif
02100 
02101 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
02102     if (tls && haveECC && haveStaticECC) {
02103         suites->suites[idx++] = ECC_BYTE;
02104         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
02105     }
02106 #endif
02107 
02108 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
02109     if (!dtls && tls && haveECC) {
02110         suites->suites[idx++] = ECC_BYTE;
02111         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
02112     }
02113 #endif
02114 
02115 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
02116     if (!dtls && tls && haveECC && haveStaticECC) {
02117         suites->suites[idx++] = ECC_BYTE;
02118         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
02119     }
02120 #endif
02121 
02122 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
02123     if (tls && haveECC) {
02124         suites->suites[idx++] = ECC_BYTE;
02125         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
02126     }
02127 #endif
02128 
02129 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
02130     if (tls && haveECC && haveStaticECC) {
02131         suites->suites[idx++] = ECC_BYTE;
02132         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
02133     }
02134 #endif
02135 
02136 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
02137     if (tls && haveRSA) {
02138         suites->suites[idx++] = ECC_BYTE;
02139         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
02140     }
02141 #endif
02142 
02143 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
02144     if (tls && haveRSAsig && haveStaticECC) {
02145         suites->suites[idx++] = ECC_BYTE;
02146         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
02147     }
02148 #endif
02149 
02150 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
02151     if (tls && haveRSA) {
02152         suites->suites[idx++] = ECC_BYTE;
02153         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
02154     }
02155 #endif
02156 
02157 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
02158     if (tls && haveRSAsig && haveStaticECC) {
02159         suites->suites[idx++] = ECC_BYTE;
02160         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
02161     }
02162 #endif
02163 
02164 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
02165     if (!dtls && tls && haveRSA) {
02166         suites->suites[idx++] = ECC_BYTE;
02167         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
02168     }
02169 #endif
02170 
02171 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
02172     if (!dtls && tls && haveRSAsig && haveStaticECC) {
02173         suites->suites[idx++] = ECC_BYTE;
02174         suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
02175     }
02176 #endif
02177 
02178 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
02179     if (tls && haveRSA) {
02180         suites->suites[idx++] = ECC_BYTE;
02181         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
02182     }
02183 #endif
02184 
02185 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
02186     if (tls && haveRSAsig && haveStaticECC) {
02187         suites->suites[idx++] = ECC_BYTE;
02188         suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
02189     }
02190 #endif
02191 
02192 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
02193     if (tls1_2 && haveECC) {
02194         suites->suites[idx++] = ECC_BYTE;
02195         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM;
02196     }
02197 #endif
02198 
02199 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
02200     if (tls1_2 && haveECC) {
02201         suites->suites[idx++] = ECC_BYTE;
02202         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
02203     }
02204 #endif
02205 
02206 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
02207     if (tls1_2 && haveECC) {
02208         suites->suites[idx++] = ECC_BYTE;
02209         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
02210     }
02211 #endif
02212 
02213 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
02214     if (tls1_2 && haveRSA) {
02215         suites->suites[idx++] = ECC_BYTE;
02216         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
02217     }
02218 #endif
02219 
02220 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
02221     if (tls1_2 && haveRSA) {
02222         suites->suites[idx++] = ECC_BYTE;
02223         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
02224     }
02225 #endif
02226 
02227 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
02228     if (tls && haveDH && haveRSA) {
02229         suites->suites[idx++] = 0;
02230         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
02231     }
02232 #endif
02233 
02234 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
02235     if (tls && haveDH && haveRSA) {
02236         suites->suites[idx++] = 0;
02237         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
02238     }
02239 #endif
02240 
02241 /* Place as higher priority for MYSQL testing */
02242 #if !defined(WOLFSSL_MYSQL_COMPATIBLE)
02243 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
02244     if (tls && haveDH && haveRSA) {
02245         suites->suites[idx++] = 0;
02246         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
02247     }
02248 #endif
02249 #endif
02250 
02251 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
02252     if (tls && haveDH && haveRSA) {
02253         suites->suites[idx++] = 0;
02254         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
02255     }
02256 #endif
02257 
02258 #ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
02259     if (tls && haveDH && haveRSA) {
02260         suites->suites[idx++] = 0;
02261         suites->suites[idx++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
02262     }
02263 #endif
02264 
02265 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
02266     if (tls && haveRSA) {
02267         suites->suites[idx++] = 0;
02268         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
02269     }
02270 #endif
02271 
02272 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
02273     if (tls && haveRSA) {
02274         suites->suites[idx++] = 0;
02275         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
02276     }
02277 #endif
02278 
02279 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
02280     if (tls && haveRSA) {
02281         suites->suites[idx++] = 0;
02282         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
02283     }
02284 #endif
02285 
02286 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
02287     if (tls && haveRSA) {
02288         suites->suites[idx++] = 0;
02289         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
02290     }
02291 #endif
02292 
02293 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
02294     if (tls1_2 && haveECC) {
02295         suites->suites[idx++] = CHACHA_BYTE;
02296         suites->suites[idx++] =
02297                               TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
02298     }
02299 #endif
02300 
02301 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
02302     if (tls1_2 && haveRSA) {
02303         suites->suites[idx++] = CHACHA_BYTE;
02304         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
02305     }
02306 #endif
02307 
02308 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
02309     if (tls1_2 && haveRSA) {
02310         suites->suites[idx++] = CHACHA_BYTE;
02311         suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
02312     }
02313 #endif
02314 
02315 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
02316     if (tls && haveECC) {
02317         suites->suites[idx++] = ECC_BYTE;
02318         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_NULL_SHA;
02319     }
02320 #endif
02321 
02322 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
02323     if (tls && haveRSA) {
02324         suites->suites[idx++] = 0;
02325         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
02326     }
02327 #endif
02328 
02329 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
02330     if (tls && haveRSA) {
02331         suites->suites[idx++] = 0;
02332         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
02333     }
02334 #endif
02335 
02336 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
02337     if (tls && havePSK) {
02338         suites->suites[idx++] = 0;
02339         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
02340     }
02341 #endif
02342 
02343 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
02344     if (tls && haveDH && havePSK) {
02345         suites->suites[idx++] = 0;
02346         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
02347     }
02348 #endif
02349 
02350 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
02351     if (tls && havePSK) {
02352         suites->suites[idx++] = 0;
02353         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
02354     }
02355 #endif
02356 
02357 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
02358     if (tls && haveDH && havePSK) {
02359         suites->suites[idx++] = 0;
02360         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
02361     }
02362 #endif
02363 
02364 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
02365     if (tls && havePSK) {
02366         suites->suites[idx++] = 0;
02367         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
02368     }
02369 #endif
02370 
02371 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
02372     if (tls && havePSK) {
02373         suites->suites[idx++] = 0;
02374         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
02375     }
02376 #endif
02377 
02378 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
02379     if (tls && haveDH && havePSK) {
02380         suites->suites[idx++] = ECC_BYTE;
02381         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
02382     }
02383 #endif
02384 
02385 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
02386     if (tls && haveDH && havePSK) {
02387         suites->suites[idx++] = ECC_BYTE;
02388         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
02389     }
02390 #endif
02391 
02392 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
02393     if (tls && havePSK) {
02394         suites->suites[idx++] = CHACHA_BYTE;
02395         suites->suites[idx++] = TLS_PSK_WITH_CHACHA20_POLY1305_SHA256;
02396     }
02397 #endif
02398 
02399 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
02400     if (tls && havePSK) {
02401         suites->suites[idx++] = CHACHA_BYTE;
02402         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
02403     }
02404 #endif
02405 
02406 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
02407     if (tls && havePSK) {
02408         suites->suites[idx++] = CHACHA_BYTE;
02409         suites->suites[idx++] = TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
02410     }
02411 #endif
02412 
02413 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
02414     if (tls && havePSK) {
02415         suites->suites[idx++] = ECC_BYTE;
02416         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
02417     }
02418 #endif
02419 
02420 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
02421     if (tls && havePSK) {
02422         suites->suites[idx++] = ECC_BYTE;
02423         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
02424     }
02425 #endif
02426 
02427 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
02428     if (tls && havePSK) {
02429         suites->suites[idx++] = ECC_BYTE;
02430         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
02431     }
02432 #endif
02433 
02434 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
02435     if (tls && havePSK) {
02436         suites->suites[idx++] = ECC_BYTE;
02437         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
02438     }
02439 #endif
02440 
02441 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
02442     if (tls && havePSK) {
02443         suites->suites[idx++] = ECC_BYTE;
02444         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
02445     }
02446 #endif
02447 
02448 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
02449     if (tls && haveDH && havePSK) {
02450         suites->suites[idx++] = 0;
02451         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
02452     }
02453 #endif
02454 
02455 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
02456     if (tls && havePSK) {
02457         suites->suites[idx++] = 0;
02458         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
02459     }
02460 #endif
02461 
02462 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
02463     if (tls && havePSK) {
02464         suites->suites[idx++] = ECC_BYTE;
02465         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_NULL_SHA256;
02466     }
02467 #endif
02468 
02469 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
02470     if (tls && haveDH && havePSK) {
02471         suites->suites[idx++] = 0;
02472         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
02473     }
02474 #endif
02475 
02476 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
02477     if (tls && havePSK) {
02478         suites->suites[idx++] = 0;
02479         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
02480     }
02481 #endif
02482 
02483 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
02484     if (tls && havePSK) {
02485         suites->suites[idx++] = 0;
02486         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
02487     }
02488 #endif
02489 
02490 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
02491     if (!dtls && haveRSA) {
02492         suites->suites[idx++] = 0;
02493         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
02494     }
02495 #endif
02496 
02497 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
02498     if (!dtls && haveRSA) {
02499         suites->suites[idx++] = 0;
02500         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
02501     }
02502 #endif
02503 
02504 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
02505     if (haveRSA ) {
02506         suites->suites[idx++] = 0;
02507         suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
02508     }
02509 #endif
02510 
02511 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
02512     if (!dtls && tls && haveRSA) {
02513         suites->suites[idx++] = 0;
02514         suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
02515     }
02516 #endif
02517 
02518 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
02519     if (!dtls && tls && haveRSA) {
02520         suites->suites[idx++] = 0;
02521         suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
02522     }
02523 #endif
02524 
02525 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
02526     if (!dtls && tls && haveRSA) {
02527         suites->suites[idx++] = 0;
02528         suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
02529     }
02530 #endif
02531 
02532 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
02533     if (tls && haveRSA) {
02534         suites->suites[idx++] = 0;
02535         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
02536     }
02537 #endif
02538 
02539 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
02540     if (tls && haveRSA) {
02541         suites->suites[idx++] = 0;
02542         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
02543     }
02544 #endif
02545 
02546 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
02547     if (!dtls && tls && haveRSA) {
02548         suites->suites[idx++] = 0;
02549         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
02550     }
02551 #endif
02552 
02553 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
02554     if (tls && haveRSA) {
02555         suites->suites[idx++] = 0;
02556         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
02557     }
02558 #endif
02559 
02560 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
02561     if (tls && haveDH && haveRSA) {
02562         suites->suites[idx++] = 0;
02563         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
02564     }
02565 #endif
02566 
02567 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
02568     if (tls && haveRSA) {
02569         suites->suites[idx++] = 0;
02570         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
02571     }
02572 #endif
02573 
02574 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
02575     if (tls && haveDH && haveRSA) {
02576         suites->suites[idx++] = 0;
02577         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
02578     }
02579 #endif
02580 
02581 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
02582     if (tls && haveRSA) {
02583         suites->suites[idx++] = 0;
02584         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
02585     }
02586 #endif
02587 
02588 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
02589     if (tls && haveDH && haveRSA) {
02590         suites->suites[idx++] = 0;
02591         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
02592     }
02593 #endif
02594 
02595 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
02596     if (tls && haveRSA) {
02597         suites->suites[idx++] = 0;
02598         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
02599     }
02600 #endif
02601 
02602 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
02603     if (tls && haveDH && haveRSA) {
02604         suites->suites[idx++] = 0;
02605         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
02606     }
02607 #endif
02608 
02609 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
02610     if (haveRSA) {
02611         suites->suites[idx++] = 0;
02612         suites->suites[idx++] = SSL_RSA_WITH_IDEA_CBC_SHA;
02613     }
02614 #endif
02615 
02616     suites->suiteSz = idx;
02617 
02618     InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
02619 }
02620 
02621 
02622 #ifndef NO_CERTS
02623 
02624 
02625 void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
02626 {
02627     (void)dynamicFlag;
02628 
02629     if (name != NULL) {
02630         name->name        = name->staticName;
02631         name->dynamicName = 0;
02632 #ifdef OPENSSL_EXTRA
02633         XMEMSET(&name->fullName, 0, sizeof(DecodedName));
02634         XMEMSET(&name->cnEntry,  0, sizeof(WOLFSSL_X509_NAME_ENTRY));
02635         name->cnEntry.value = &(name->cnEntry.data); /* point to internal data*/
02636         name->x509 = NULL;
02637 #endif /* OPENSSL_EXTRA */
02638     }
02639 }
02640 
02641 
02642 void FreeX509Name(WOLFSSL_X509_NAME* name, void* heap)
02643 {
02644     if (name != NULL) {
02645         if (name->dynamicName)
02646             XFREE(name->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
02647 #ifdef OPENSSL_EXTRA
02648         if (name->fullName.fullName != NULL)
02649             XFREE(name->fullName.fullName, heap, DYNAMIC_TYPE_X509);
02650 #endif /* OPENSSL_EXTRA */
02651     }
02652     (void)heap;
02653 }
02654 
02655 
02656 /* Initialize wolfSSL X509 type */
02657 void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap)
02658 {
02659     if (x509 == NULL) {
02660         WOLFSSL_MSG("Null parameter passed in!");
02661         return;
02662     }
02663 
02664     XMEMSET(x509, 0, sizeof(WOLFSSL_X509));
02665 
02666     x509->heap = heap;
02667     InitX509Name(&x509->issuer, 0);
02668     InitX509Name(&x509->subject, 0);
02669     x509->version        = 0;
02670     x509->pubKey.buffer  = NULL;
02671     x509->sig.buffer     = NULL;
02672     x509->derCert        = NULL;
02673     x509->altNames       = NULL;
02674     x509->altNamesNext   = NULL;
02675     x509->dynamicMemory  = (byte)dynamicFlag;
02676     x509->isCa           = 0;
02677 #ifdef HAVE_ECC
02678     x509->pkCurveOID = 0;
02679 #endif /* HAVE_ECC */
02680 #ifdef OPENSSL_EXTRA
02681     x509->pathLength     = 0;
02682     x509->basicConstSet  = 0;
02683     x509->basicConstCrit = 0;
02684     x509->basicConstPlSet = 0;
02685     x509->subjAltNameSet = 0;
02686     x509->subjAltNameCrit = 0;
02687     x509->authKeyIdSet   = 0;
02688     x509->authKeyIdCrit  = 0;
02689     x509->authKeyId      = NULL;
02690     x509->authKeyIdSz    = 0;
02691     x509->subjKeyIdSet   = 0;
02692     x509->subjKeyIdCrit  = 0;
02693     x509->subjKeyId      = NULL;
02694     x509->subjKeyIdSz    = 0;
02695     x509->keyUsageSet    = 0;
02696     x509->keyUsageCrit   = 0;
02697     x509->keyUsage       = 0;
02698     #ifdef WOLFSSL_SEP
02699         x509->certPolicySet  = 0;
02700         x509->certPolicyCrit = 0;
02701     #endif /* WOLFSSL_SEP */
02702 #endif /* OPENSSL_EXTRA */
02703 }
02704 
02705 
02706 /* Free wolfSSL X509 type */
02707 void FreeX509(WOLFSSL_X509* x509)
02708 {
02709     if (x509 == NULL)
02710         return;
02711 
02712     FreeX509Name(&x509->issuer, x509->heap);
02713     FreeX509Name(&x509->subject, x509->heap);
02714     if (x509->pubKey.buffer)
02715         XFREE(x509->pubKey.buffer, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
02716     FreeDer(&x509->derCert);
02717     XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
02718     #ifdef OPENSSL_EXTRA
02719         XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
02720         XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
02721         if (x509->authInfo != NULL) {
02722             XFREE(x509->authInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
02723         }
02724         if (x509->extKeyUsageSrc != NULL) {
02725             XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
02726         }
02727     #endif /* OPENSSL_EXTRA */
02728     if (x509->altNames)
02729         FreeAltNames(x509->altNames, NULL);
02730 }
02731 
02732 
02733 #ifndef NO_RSA
02734 
02735 int RsaSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
02736     word32* outSz, RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx)
02737 {
02738     int ret;
02739 
02740     (void)ssl;
02741     (void)keyBuf;
02742     (void)keySz;
02743     (void)ctx;
02744 
02745     WOLFSSL_ENTER("RsaSign");
02746 
02747 #if defined(HAVE_PK_CALLBACKS)
02748     if (ssl->ctx->RsaSignCb) {
02749         ret = ssl->ctx->RsaSignCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
02750                                                                           ctx);
02751     }
02752     else
02753 #endif /*HAVE_PK_CALLBACKS */
02754     {
02755         ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, key, ssl->rng);
02756     }
02757 
02758     /* Handle async pending response */
02759 #if defined(WOLFSSL_ASYNC_CRYPT)
02760     if (ret == WC_PENDING_E) {
02761         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02762     }
02763 #endif /* WOLFSSL_ASYNC_CRYPT */
02764 
02765     /* For positive response return in outSz */
02766     if (ret > 0) {
02767         *outSz = ret;
02768         ret = 0;
02769     }
02770 
02771     WOLFSSL_LEAVE("RsaSign", ret);
02772 
02773     return ret;
02774 }
02775 
02776 int RsaVerify(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, int sigAlgo,
02777               int hashAlgo, RsaKey* key, const byte* keyBuf, word32 keySz,
02778               void* ctx)
02779 {
02780     int ret;
02781 
02782     (void)ssl;
02783     (void)keyBuf;
02784     (void)keySz;
02785     (void)ctx;
02786     (void)sigAlgo;
02787     (void)hashAlgo;
02788 
02789     WOLFSSL_ENTER("RsaVerify");
02790 
02791 #ifdef HAVE_PK_CALLBACKS
02792     if (ssl->ctx->RsaVerifyCb) {
02793         ret = ssl->ctx->RsaVerifyCb(ssl, in, inSz, out, keyBuf, keySz, ctx);
02794     }
02795     else
02796 #endif /*HAVE_PK_CALLBACKS */
02797     {
02798 #ifdef WOLFSSL_TLS13
02799     #ifdef WC_RSA_PSS
02800         if (sigAlgo == rsa_pss_sa_algo) {
02801             enum wc_HashType hashType = WC_HASH_TYPE_NONE;
02802             int mgf = 0;
02803             switch (hashAlgo) {
02804                 case sha512_mac:
02805                 #ifdef WOLFSSL_SHA512
02806                     hashType = WC_HASH_TYPE_SHA512;
02807                     mgf = WC_MGF1SHA512;
02808                 #endif
02809                     break;
02810                 case sha384_mac:
02811                 #ifdef WOLFSSL_SHA384
02812                     hashType = WC_HASH_TYPE_SHA384;
02813                     mgf = WC_MGF1SHA384;
02814                 #endif
02815                     break;
02816                 case sha256_mac:
02817                 #ifndef NO_SHA256
02818                     hashType = WC_HASH_TYPE_SHA256;
02819                     mgf = WC_MGF1SHA256;
02820                 #endif
02821                     break;
02822             }
02823             ret = wc_RsaPSS_VerifyInline(in, inSz, out, hashType, mgf, key);
02824         }
02825         else
02826     #endif
02827 #endif
02828             ret = wc_RsaSSL_VerifyInline(in, inSz, out, key);
02829     }
02830 
02831     /* Handle async pending response */
02832 #if defined(WOLFSSL_ASYNC_CRYPT)
02833     if (ret == WC_PENDING_E) {
02834         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02835     }
02836 #endif /* WOLFSSL_ASYNC_CRYPT */
02837 
02838     WOLFSSL_LEAVE("RsaVerify", ret);
02839 
02840     return ret;
02841 }
02842 
02843 /* Verify RSA signature, 0 on success */
02844 int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, word32 sigSz,
02845     const byte* plain, word32 plainSz, RsaKey* key)
02846 {
02847     byte* out = NULL;  /* inline result */
02848     int   ret;
02849 
02850     (void)ssl;
02851 
02852     WOLFSSL_ENTER("VerifyRsaSign");
02853 
02854     if (verifySig == NULL || plain == NULL || key == NULL) {
02855         return BAD_FUNC_ARG;
02856     }
02857 
02858     if (sigSz > ENCRYPT_LEN) {
02859         WOLFSSL_MSG("Signature buffer too big");
02860         return BUFFER_E;
02861     }
02862 
02863     ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key);
02864 
02865     if (ret > 0) {
02866         if (ret != (int)plainSz || !out ||
02867                                         XMEMCMP(plain, out, plainSz) != 0) {
02868             WOLFSSL_MSG("RSA Signature verification failed");
02869             ret = RSA_SIGN_FAULT;
02870         } else {
02871             ret = 0;  /* RSA reset */
02872         }
02873     }
02874 
02875     /* Handle async pending response */
02876 #if defined(WOLFSSL_ASYNC_CRYPT)
02877     if (ret == WC_PENDING_E) {
02878         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02879     }
02880 #endif /* WOLFSSL_ASYNC_CRYPT */
02881 
02882     WOLFSSL_LEAVE("VerifyRsaSign", ret);
02883 
02884     return ret;
02885 }
02886 
02887 int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz,
02888     RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx)
02889 {
02890     int ret;
02891 
02892     (void)ssl;
02893     (void)keyBuf;
02894     (void)keySz;
02895     (void)ctx;
02896 
02897     WOLFSSL_ENTER("RsaDec");
02898 
02899 #ifdef HAVE_PK_CALLBACKS
02900     if (ssl->ctx->RsaDecCb) {
02901             ret = ssl->ctx->RsaDecCb(ssl, in, inSz, out, keyBuf, keySz,
02902                                                                     ctx);
02903     }
02904     else
02905 #endif /* HAVE_PK_CALLBACKS */
02906     {
02907         #ifdef WC_RSA_BLINDING
02908             ret = wc_RsaSetRNG(key, ssl->rng);
02909             if (ret != 0)
02910                 return ret;
02911         #endif
02912         ret = wc_RsaPrivateDecryptInline(in, inSz, out, key);
02913     }
02914 
02915     /* Handle async pending response */
02916 #if defined(WOLFSSL_ASYNC_CRYPT)
02917     if (ret == WC_PENDING_E) {
02918         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02919     }
02920 #endif /* WOLFSSL_ASYNC_CRYPT */
02921 
02922     /* For positive response return in outSz */
02923     if (ret > 0) {
02924         *outSz = ret;
02925         ret = 0;
02926     }
02927 
02928     WOLFSSL_LEAVE("RsaDec", ret);
02929 
02930     return ret;
02931 }
02932 
02933 int RsaEnc(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz,
02934     RsaKey* key, const byte* keyBuf, word32 keySz, void* ctx)
02935 {
02936     int ret;
02937 
02938     (void)ssl;
02939     (void)keyBuf;
02940     (void)keySz;
02941     (void)ctx;
02942 
02943     WOLFSSL_ENTER("RsaEnc");
02944 
02945 #ifdef HAVE_PK_CALLBACKS
02946     if (ssl->ctx->RsaEncCb) {
02947             ret = ssl->ctx->RsaEncCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
02948                                                                         ctx);
02949     }
02950     else
02951 #endif /* HAVE_PK_CALLBACKS */
02952     {
02953         ret = wc_RsaPublicEncrypt(in, inSz, out, *outSz, key, ssl->rng);
02954     }
02955 
02956     /* Handle async pending response */
02957 #if defined(WOLFSSL_ASYNC_CRYPT)
02958     if (ret == WC_PENDING_E) {
02959         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
02960     }
02961 #endif /* WOLFSSL_ASYNC_CRYPT */
02962 
02963     /* For positive response return in outSz */
02964     if (ret > 0) {
02965         *outSz = ret;
02966         ret = 0;
02967     }
02968 
02969     WOLFSSL_LEAVE("RsaEnc", ret);
02970 
02971     return ret;
02972 }
02973 
02974 #endif /* NO_RSA */
02975 
02976 #ifdef HAVE_ECC
02977 
02978 int EccSign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out,
02979     word32* outSz, ecc_key* key, byte* keyBuf, word32 keySz, void* ctx)
02980 {
02981     int ret;
02982 
02983     (void)ssl;
02984     (void)keyBuf;
02985     (void)keySz;
02986     (void)ctx;
02987 
02988     WOLFSSL_ENTER("EccSign");
02989 
02990 #if defined(HAVE_PK_CALLBACKS)
02991     if (ssl->ctx->EccSignCb) {
02992         ret = ssl->ctx->EccSignCb(ssl, in, inSz, out, outSz, keyBuf,
02993             keySz, ctx);
02994     }
02995     else
02996 #endif /* HAVE_PK_CALLBACKS */
02997     {
02998         ret = wc_ecc_sign_hash(in, inSz, out, outSz, ssl->rng, key);
02999     }
03000 
03001     /* Handle async pending response */
03002 #if defined(WOLFSSL_ASYNC_CRYPT)
03003     if (ret == WC_PENDING_E) {
03004         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
03005     }
03006 #endif /* WOLFSSL_ASYNC_CRYPT */
03007 
03008     WOLFSSL_LEAVE("EccSign", ret);
03009 
03010     return ret;
03011 }
03012 
03013 int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
03014     word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz,
03015     void* ctx)
03016 {
03017     int ret;
03018 
03019     (void)ssl;
03020     (void)keyBuf;
03021     (void)keySz;
03022     (void)ctx;
03023 
03024     WOLFSSL_ENTER("EccVerify");
03025 
03026 #ifdef HAVE_PK_CALLBACKS
03027     if (ssl->ctx->EccVerifyCb) {
03028         ret = ssl->ctx->EccVerifyCb(ssl, in, inSz, out, outSz, keyBuf, keySz,
03029             &ssl->eccVerifyRes, ctx);
03030     }
03031     else
03032 #endif /* HAVE_PK_CALLBACKS  */
03033     {
03034         ret = wc_ecc_verify_hash(in, inSz, out, outSz, &ssl->eccVerifyRes, key);
03035     }
03036 
03037     /* Handle async pending response */
03038 #if defined(WOLFSSL_ASYNC_CRYPT)
03039     if (ret == WC_PENDING_E) {
03040         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
03041     }
03042     else
03043 #endif /* WOLFSSL_ASYNC_CRYPT */
03044     {
03045         ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0;
03046     }
03047 
03048     WOLFSSL_LEAVE("EccVerify", ret);
03049 
03050     return ret;
03051 }
03052 
03053 #ifdef HAVE_PK_CALLBACKS
03054     /* Gets ECC key for shared secret callback testing
03055      * Client side: returns peer key
03056      * Server side: returns private key
03057      */
03058     static int EccGetKey(WOLFSSL* ssl, ecc_key** otherKey)
03059     {
03060         int ret = NO_PEER_KEY;
03061         ecc_key* tmpKey = NULL;
03062 
03063         if (ssl == NULL || otherKey == NULL) {
03064             return BAD_FUNC_ARG;
03065         }
03066 
03067         if (ssl->options.side == WOLFSSL_CLIENT_END) {
03068             if (ssl->specs.static_ecdh) {
03069                 if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
03070                                            !ssl->peerEccDsaKey->dp) {
03071                     return NO_PEER_KEY;
03072                 }
03073                 tmpKey = (struct ecc_key*)ssl->peerEccDsaKey;
03074             }
03075             else {
03076                 if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
03077                                         !ssl->peerEccKey->dp) {
03078                     return NO_PEER_KEY;
03079                 }
03080                 tmpKey = (struct ecc_key*)ssl->peerEccKey;
03081             }
03082         }
03083         else if (ssl->options.side == WOLFSSL_SERVER_END) {
03084             if (ssl->specs.static_ecdh) {
03085                 if (ssl->hsKey == NULL) {
03086                     return NO_PRIVATE_KEY;
03087                 }
03088                 tmpKey = (struct ecc_key*)ssl->hsKey;
03089             }
03090             else {
03091                 if (!ssl->eccTempKeyPresent) {
03092                     return NO_PRIVATE_KEY;
03093                 }
03094                 tmpKey = (struct ecc_key*)ssl->eccTempKey;
03095             }
03096         }
03097 
03098         if (tmpKey) {
03099             *otherKey = tmpKey;
03100             ret = 0;
03101         }
03102 
03103         return ret;
03104     }
03105 #endif /* HAVE_PK_CALLBACKS */
03106 
03107 int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key,
03108         byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen,
03109         int side, void* ctx)
03110 {
03111     int ret;
03112 
03113     (void)ssl;
03114     (void)pubKeyDer;
03115     (void)pubKeySz;
03116     (void)side;
03117     (void)ctx;
03118 
03119     WOLFSSL_ENTER("EccSharedSecret");
03120 
03121 #ifdef HAVE_PK_CALLBACKS
03122     if (ssl->ctx->EccSharedSecretCb) {
03123         ecc_key* otherKey = NULL;
03124 
03125         ret = EccGetKey(ssl, &otherKey);
03126         if (ret == 0) {
03127             ret = ssl->ctx->EccSharedSecretCb(ssl, otherKey, pubKeyDer,
03128                 pubKeySz, out, outlen, side, ctx);
03129         }
03130     }
03131     else
03132 #endif
03133     {
03134         ret = wc_ecc_shared_secret(priv_key, pub_key, out, outlen);
03135     }
03136 
03137     /* Handle async pending response */
03138 #if defined(WOLFSSL_ASYNC_CRYPT)
03139     if (ret == WC_PENDING_E) {
03140         ret = wolfSSL_AsyncPush(ssl, &priv_key->asyncDev,
03141                                                     WC_ASYNC_FLAG_CALL_AGAIN);
03142     }
03143 #endif /* WOLFSSL_ASYNC_CRYPT */
03144 
03145     WOLFSSL_LEAVE("EccSharedSecret", ret);
03146 
03147     return ret;
03148 }
03149 
03150 int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
03151 {
03152     int ret = 0;
03153     int keySz = 0;
03154 
03155     WOLFSSL_ENTER("EccMakeKey");
03156 
03157     if (peer == NULL) {
03158         keySz = ssl->eccTempKeySz;
03159     }
03160     else {
03161         keySz = peer->dp->size;
03162     }
03163 
03164     if (ssl->ecdhCurveOID > 0) {
03165         ret = wc_ecc_make_key_ex(ssl->rng, keySz, key,
03166                  wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL));
03167     }
03168     else {
03169         ret = wc_ecc_make_key(ssl->rng, keySz, key);
03170         if (ret == 0)
03171             ssl->ecdhCurveOID = key->dp->oidSum;
03172     }
03173 
03174     /* Handle async pending response */
03175 #if defined(WOLFSSL_ASYNC_CRYPT)
03176     if (ret == WC_PENDING_E) {
03177         ret = wolfSSL_AsyncPush(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE);
03178     }
03179 #endif /* WOLFSSL_ASYNC_CRYPT */
03180 
03181     WOLFSSL_LEAVE("EccMakeKey", ret);
03182 
03183     return ret;
03184 }
03185 
03186 #endif /* HAVE_ECC */
03187 
03188 #endif /* !NO_CERTS */
03189 
03190 #if !defined(NO_CERTS) || !defined(NO_PSK)
03191 #if !defined(NO_DH)
03192 
03193 int DhGenKeyPair(WOLFSSL* ssl, DhKey* dhKey,
03194     byte* priv, word32* privSz,
03195     byte* pub, word32* pubSz)
03196 {
03197     int ret;
03198 
03199     WOLFSSL_ENTER("DhGenKeyPair");
03200 
03201     ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, priv, privSz, pub, pubSz);
03202 
03203     /* Handle async pending response */
03204 #if defined(WOLFSSL_ASYNC_CRYPT)
03205     if (ret == WC_PENDING_E) {
03206         ret = wolfSSL_AsyncPush(ssl, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
03207     }
03208 #endif /* WOLFSSL_ASYNC_CRYPT */
03209 
03210     WOLFSSL_LEAVE("DhGenKeyPair", ret);
03211 
03212     return ret;
03213 }
03214 
03215 int DhAgree(WOLFSSL* ssl, DhKey* dhKey,
03216     const byte* priv, word32 privSz,
03217     const byte* otherPub, word32 otherPubSz,
03218     byte* agree, word32* agreeSz)
03219 {
03220     int ret;
03221 
03222     (void)ssl;
03223 
03224     WOLFSSL_ENTER("DhAgree");
03225 
03226     ret = wc_DhAgree(dhKey, agree, agreeSz, priv, privSz, otherPub, otherPubSz);
03227 
03228     /* Handle async pending response */
03229 #if defined(WOLFSSL_ASYNC_CRYPT)
03230     if (ret == WC_PENDING_E) {
03231         ret = wolfSSL_AsyncPush(ssl, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE);
03232     }
03233 #endif /* WOLFSSL_ASYNC_CRYPT */
03234 
03235     WOLFSSL_LEAVE("DhAgree", ret);
03236 
03237     return ret;
03238 }
03239 #endif /* !NO_DH */
03240 #endif /* !NO_CERTS || !NO_PSK */
03241 
03242 
03243 /* This function inherits a WOLFSSL_CTX's fields into an SSL object.
03244    It is used during initialization and to switch an ssl's CTX with
03245    wolfSSL_Set_SSL_CTX.  Requires ssl->suites alloc and ssl-arrays with PSK
03246    unless writeDup is on.
03247 
03248    ssl      object to initialize
03249    ctx      parent factory
03250    writeDup flag indicating this is a write dup only
03251 
03252    SSL_SUCCESS return value on success */
03253 int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
03254 {
03255     byte havePSK = 0;
03256     byte haveAnon = 0;
03257     byte newSSL;
03258     byte haveRSA = 0;
03259     (void) haveAnon; /* Squash unused var warnings */
03260 
03261     if (!ssl || !ctx)
03262         return BAD_FUNC_ARG;
03263 
03264     if (ssl->suites == NULL && !writeDup)
03265         return BAD_FUNC_ARG;
03266 
03267     newSSL = ssl->ctx == NULL; /* Assign after null check */
03268 
03269 #ifndef NO_PSK
03270     if (ctx->server_hint[0] && ssl->arrays == NULL && !writeDup) {
03271         return BAD_FUNC_ARG;  /* needed for copy below */
03272     }
03273 #endif
03274 
03275 
03276 #ifndef NO_RSA
03277     haveRSA = 1;
03278 #endif
03279 #ifndef NO_PSK
03280     havePSK = ctx->havePSK;
03281 #endif /* NO_PSK */
03282 #ifdef HAVE_ANON
03283     haveAnon = ctx->haveAnon;
03284 #endif /* HAVE_ANON*/
03285 
03286     /* decrement previous CTX reference count if exists.
03287      * This should only happen if switching ctxs!*/
03288     if (!newSSL) {
03289         WOLFSSL_MSG("freeing old ctx to decrement reference count. Switching ctx.");
03290         wolfSSL_CTX_free(ssl->ctx);
03291     }
03292 
03293     /* increment CTX reference count */
03294     if (wc_LockMutex(&ctx->countMutex) != 0) {
03295         WOLFSSL_MSG("Couldn't lock CTX count mutex");
03296         return BAD_MUTEX_E;
03297     }
03298     ctx->refCount++;
03299     wc_UnLockMutex(&ctx->countMutex);
03300     ssl->ctx     = ctx; /* only for passing to calls, options could change */
03301     ssl->version = ctx->method->version;
03302 
03303 #ifdef HAVE_ECC
03304     ssl->eccTempKeySz = ctx->eccTempKeySz;
03305     ssl->pkCurveOID = ctx->pkCurveOID;
03306     ssl->ecdhCurveOID = ctx->ecdhCurveOID;
03307 #endif
03308 
03309 #ifdef OPENSSL_EXTRA
03310     ssl->options.mask = ctx->mask;
03311 #endif
03312     ssl->timeout = ctx->timeout;
03313     ssl->verifyCallback    = ctx->verifyCallback;
03314     ssl->options.side      = ctx->method->side;
03315     ssl->options.downgrade    = ctx->method->downgrade;
03316     ssl->options.minDowngrade = ctx->minDowngrade;
03317 
03318     ssl->options.haveDH        = ctx->haveDH;
03319     ssl->options.haveNTRU      = ctx->haveNTRU;
03320     ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
03321     ssl->options.haveECC       = ctx->haveECC;
03322     ssl->options.haveStaticECC = ctx->haveStaticECC;
03323 
03324 #ifndef NO_PSK
03325     ssl->options.havePSK   = ctx->havePSK;
03326     ssl->options.client_psk_cb = ctx->client_psk_cb;
03327     ssl->options.server_psk_cb = ctx->server_psk_cb;
03328 #endif /* NO_PSK */
03329 
03330 #ifdef HAVE_ANON
03331     ssl->options.haveAnon = ctx->haveAnon;
03332 #endif
03333 #ifndef NO_DH
03334     ssl->options.minDhKeySz = ctx->minDhKeySz;
03335 #endif
03336 #ifndef NO_RSA
03337     ssl->options.minRsaKeySz = ctx->minRsaKeySz;
03338 #endif
03339 #ifdef HAVE_ECC
03340     ssl->options.minEccKeySz = ctx->minEccKeySz;
03341 #endif
03342 
03343     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
03344     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
03345 #ifdef HAVE_EXT_CACHE
03346     ssl->options.internalCacheOff     = ctx->internalCacheOff;
03347 #endif
03348 
03349     ssl->options.verifyPeer     = ctx->verifyPeer;
03350     ssl->options.verifyNone     = ctx->verifyNone;
03351     ssl->options.failNoCert     = ctx->failNoCert;
03352     ssl->options.failNoCertxPSK = ctx->failNoCertxPSK;
03353     ssl->options.sendVerify     = ctx->sendVerify;
03354 
03355     ssl->options.partialWrite  = ctx->partialWrite;
03356     ssl->options.quietShutdown = ctx->quietShutdown;
03357     ssl->options.groupMessages = ctx->groupMessages;
03358 
03359 #ifndef NO_DH
03360     ssl->buffers.serverDH_P = ctx->serverDH_P;
03361     ssl->buffers.serverDH_G = ctx->serverDH_G;
03362 #endif
03363 
03364 #ifndef NO_CERTS
03365     /* ctx still owns certificate, certChain, key, dh, and cm */
03366     ssl->buffers.certificate = ctx->certificate;
03367     ssl->buffers.certChain = ctx->certChain;
03368 #ifdef WOLFSSL_TLS13
03369     ssl->buffers.certChainCnt = ctx->certChainCnt;
03370 #endif
03371     ssl->buffers.key = ctx->privateKey;
03372 #endif
03373 
03374 #ifdef WOLFSSL_ASYNC_CRYPT
03375     ssl->devId = ctx->devId;
03376 #endif
03377 
03378     if (writeDup == 0) {
03379 
03380 #ifndef NO_PSK
03381         if (ctx->server_hint[0]) {   /* set in CTX */
03382             XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint,
03383                                     sizeof(ssl->arrays->server_hint));
03384             ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
03385         }
03386 #endif /* NO_PSK */
03387 
03388         if (ctx->suites)
03389             *ssl->suites = *ctx->suites;
03390         else
03391             XMEMSET(ssl->suites, 0, sizeof(Suites));
03392 
03393         /* make sure server has DH parms, and add PSK if there, add NTRU too */
03394         if (ssl->options.side == WOLFSSL_SERVER_END)
03395             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
03396                    ssl->options.haveDH, ssl->options.haveNTRU,
03397                    ssl->options.haveECDSAsig, ssl->options.haveECC,
03398                    ssl->options.haveStaticECC, ssl->options.side);
03399         else
03400             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
03401                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
03402                    ssl->options.haveECC, ssl->options.haveStaticECC,
03403                    ssl->options.side);
03404 
03405 #if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT)
03406         /* make sure server has cert and key unless using PSK or Anon
03407         * This should be true even if just switching ssl ctx */
03408         if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
03409             if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer
03410                      || !ssl->buffers.key || !ssl->buffers.key->buffer) {
03411                 WOLFSSL_MSG("Server missing certificate and/or private key");
03412                 return NO_PRIVATE_KEY;
03413             }
03414 #endif
03415 
03416     }  /* writeDup check */
03417 
03418 #ifdef WOLFSSL_SESSION_EXPORT
03419     #ifdef WOLFSSL_DTLS
03420     ssl->dtls_export = ctx->dtls_export; /* export function for session */
03421     #endif
03422 #endif
03423 
03424 #ifdef OPENSSL_EXTRA
03425     ssl->readAhead = ctx->readAhead;
03426 #endif
03427 
03428     return SSL_SUCCESS;
03429 }
03430 
03431 int InitHandshakeHashes(WOLFSSL* ssl)
03432 {
03433     int ret;
03434 
03435     /* make sure existing handshake hashes are free'd */
03436     if (ssl->hsHashes != NULL) {
03437         FreeHandshakeHashes(ssl);
03438     }
03439 
03440     /* allocate handshake hashes */
03441     ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
03442                                                            DYNAMIC_TYPE_HASHES);
03443     if (ssl->hsHashes == NULL) {
03444         WOLFSSL_MSG("HS_Hashes Memory error");
03445         return MEMORY_E;
03446     }
03447     XMEMSET(ssl->hsHashes, 0, sizeof(HS_Hashes));
03448 
03449 #ifndef NO_OLD_TLS
03450 #ifndef NO_MD5
03451     ret = wc_InitMd5_ex(&ssl->hsHashes->hashMd5, ssl->heap, ssl->devId);
03452     if (ret != 0)
03453         return ret;
03454 #endif
03455 #ifndef NO_SHA
03456     ret = wc_InitSha_ex(&ssl->hsHashes->hashSha, ssl->heap, ssl->devId);
03457     if (ret != 0)
03458         return ret;
03459 #endif
03460 #endif /* !NO_OLD_TLS */
03461 #ifndef NO_SHA256
03462     ret = wc_InitSha256_ex(&ssl->hsHashes->hashSha256, ssl->heap, ssl->devId);
03463     if (ret != 0)
03464         return ret;
03465 #endif
03466 #ifdef WOLFSSL_SHA384
03467     ret = wc_InitSha384_ex(&ssl->hsHashes->hashSha384, ssl->heap, ssl->devId);
03468     if (ret != 0)
03469         return ret;
03470 #endif
03471 #ifdef WOLFSSL_SHA512
03472     ret = wc_InitSha512_ex(&ssl->hsHashes->hashSha512, ssl->heap, ssl->devId);
03473     if (ret != 0)
03474         return ret;
03475 #endif
03476 
03477     return ret;
03478 }
03479 
03480 void FreeHandshakeHashes(WOLFSSL* ssl)
03481 {
03482     if (ssl->hsHashes) {
03483 #ifndef NO_OLD_TLS
03484     #ifndef NO_MD5
03485         wc_Md5Free(&ssl->hsHashes->hashMd5);
03486     #endif
03487     #ifndef NO_SHA
03488         wc_ShaFree(&ssl->hsHashes->hashSha);
03489     #endif
03490 #endif /* !NO_OLD_TLS */
03491     #ifndef NO_SHA256
03492         wc_Sha256Free(&ssl->hsHashes->hashSha256);
03493     #endif
03494     #ifdef WOLFSSL_SHA384
03495         wc_Sha384Free(&ssl->hsHashes->hashSha384);
03496     #endif
03497     #ifdef WOLFSSL_SHA512
03498         wc_Sha512Free(&ssl->hsHashes->hashSha512);
03499     #endif
03500 
03501         XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
03502         ssl->hsHashes = NULL;
03503     }
03504 }
03505 
03506 
03507 /* init everything to 0, NULL, default values before calling anything that may
03508    fail so that destructor has a "good" state to cleanup
03509 
03510    ssl      object to initialize
03511    ctx      parent factory
03512    writeDup flag indicating this is a write dup only
03513 
03514    0 on success */
03515 int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
03516 {
03517     int  ret;
03518 
03519     XMEMSET(ssl, 0, sizeof(WOLFSSL));
03520 
03521 #if defined(WOLFSSL_STATIC_MEMORY)
03522     if (ctx->heap != NULL) {
03523         WOLFSSL_HEAP_HINT* ssl_hint;
03524         WOLFSSL_HEAP_HINT* ctx_hint;
03525 
03526         /* avoid derefrencing a test value */
03527     #ifdef WOLFSSL_HEAP_TEST
03528         if (ctx->heap == (void*)WOLFSSL_HEAP_TEST) {
03529             ssl->heap = ctx->heap;
03530         }
03531         else {
03532     #endif
03533         ssl->heap = (WOLFSSL_HEAP_HINT*)XMALLOC(sizeof(WOLFSSL_HEAP_HINT),
03534                                                ctx->heap, DYNAMIC_TYPE_SSL);
03535         if (ssl->heap == NULL) {
03536             return MEMORY_E;
03537         }
03538         XMEMSET(ssl->heap, 0, sizeof(WOLFSSL_HEAP_HINT));
03539         ssl_hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
03540         ctx_hint = ((WOLFSSL_HEAP_HINT*)(ctx->heap));
03541 
03542         /* lock and check IO count / handshake count */
03543         if (wc_LockMutex(&(ctx_hint->memory->memory_mutex)) != 0) {
03544             WOLFSSL_MSG("Bad memory_mutex lock");
03545             XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
03546             ssl->heap = NULL; /* free and set to NULL for IO counter */
03547             return BAD_MUTEX_E;
03548         }
03549         if (ctx_hint->memory->maxHa > 0 &&
03550                            ctx_hint->memory->maxHa <= ctx_hint->memory->curHa) {
03551             WOLFSSL_MSG("At max number of handshakes for static memory");
03552             wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03553             XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
03554             ssl->heap = NULL; /* free and set to NULL for IO counter */
03555             return MEMORY_E;
03556         }
03557 
03558         if (ctx_hint->memory->maxIO > 0 &&
03559                            ctx_hint->memory->maxIO <= ctx_hint->memory->curIO) {
03560             WOLFSSL_MSG("At max number of IO allowed for static memory");
03561             wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03562             XFREE(ssl->heap, ctx->heap, DYNAMIC_TYPE_SSL);
03563             ssl->heap = NULL; /* free and set to NULL for IO counter */
03564             return MEMORY_E;
03565         }
03566         ctx_hint->memory->curIO++;
03567         ctx_hint->memory->curHa++;
03568         ssl_hint->memory = ctx_hint->memory;
03569         ssl_hint->haFlag = 1;
03570         wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03571 
03572         /* check if tracking stats */
03573         if (ctx_hint->memory->flag & WOLFMEM_TRACK_STATS) {
03574             ssl_hint->stats = (WOLFSSL_MEM_CONN_STATS*)XMALLOC(
03575                sizeof(WOLFSSL_MEM_CONN_STATS), ctx->heap, DYNAMIC_TYPE_SSL);
03576             if (ssl_hint->stats == NULL) {
03577                 return MEMORY_E;
03578             }
03579             XMEMSET(ssl_hint->stats, 0, sizeof(WOLFSSL_MEM_CONN_STATS));
03580         }
03581 
03582         /* check if using fixed IO buffers */
03583         if (ctx_hint->memory->flag & WOLFMEM_IO_POOL_FIXED) {
03584             if (wc_LockMutex(&(ctx_hint->memory->memory_mutex)) != 0) {
03585                 WOLFSSL_MSG("Bad memory_mutex lock");
03586                 return BAD_MUTEX_E;
03587             }
03588             if (SetFixedIO(ctx_hint->memory, &(ssl_hint->inBuf)) != 1) {
03589                 wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03590                 return MEMORY_E;
03591             }
03592             if (SetFixedIO(ctx_hint->memory, &(ssl_hint->outBuf)) != 1) {
03593                 wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03594                 return MEMORY_E;
03595             }
03596             if (ssl_hint->outBuf == NULL || ssl_hint->inBuf == NULL) {
03597                 WOLFSSL_MSG("Not enough memory to create fixed IO buffers");
03598                 wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03599                 return MEMORY_E;
03600             }
03601             wc_UnLockMutex(&(ctx_hint->memory->memory_mutex));
03602         }
03603     #ifdef WOLFSSL_HEAP_TEST
03604         }
03605     #endif
03606     }
03607     else {
03608         ssl->heap = ctx->heap;
03609     }
03610 #else
03611     ssl->heap = ctx->heap; /* carry over user heap without static memory */
03612 #endif /* WOLFSSL_STATIC_MEMORY */
03613 
03614     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
03615     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
03616 
03617     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
03618     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
03619 
03620 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
03621     InitX509(&ssl->peerCert, 0, ssl->heap);
03622 #endif
03623 
03624     ssl->rfd = -1;   /* set to invalid descriptor */
03625     ssl->wfd = -1;
03626     ssl->devId = ctx->devId; /* device for async HW (from wolfAsync_DevOpen) */
03627 
03628     ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
03629     ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
03630 
03631 #ifdef HAVE_NETX
03632     ssl->IOCB_ReadCtx  = &ssl->nxCtx;  /* default NetX IO ctx, same for read */
03633     ssl->IOCB_WriteCtx = &ssl->nxCtx;  /* and write */
03634 #endif
03635 
03636     /* initialize states */
03637     ssl->options.serverState = NULL_STATE;
03638     ssl->options.clientState = NULL_STATE;
03639     ssl->options.connectState = CONNECT_BEGIN;
03640     ssl->options.acceptState  = ACCEPT_BEGIN;
03641     ssl->options.handShakeState  = NULL_STATE;
03642     ssl->options.processReply = doProcessInit;
03643     ssl->options.asyncState = TLS_ASYNC_BEGIN;
03644     ssl->options.buildMsgState = BUILD_MSG_BEGIN;
03645     ssl->encrypt.state = CIPHER_STATE_BEGIN;
03646     ssl->decrypt.state = CIPHER_STATE_BEGIN;
03647 
03648 #ifdef WOLFSSL_DTLS
03649     #ifdef WOLFSSL_SCTP
03650         ssl->options.dtlsSctp           = ctx->dtlsSctp;
03651         ssl->dtlsMtuSz                  = ctx->dtlsMtuSz;
03652         ssl->dtls_expected_rx           = ssl->dtlsMtuSz;
03653     #else
03654         ssl->dtls_expected_rx = MAX_MTU;
03655     #endif
03656     ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
03657     ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
03658     ssl->dtls_timeout                   = ssl->dtls_timeout_init;
03659     ssl->buffers.dtlsCtx.rfd            = -1;
03660     ssl->buffers.dtlsCtx.wfd            = -1;
03661 #endif
03662 
03663     #ifndef NO_OLD_TLS
03664         ssl->hmac = SSL_hmac; /* default to SSLv3 */
03665     #else
03666         ssl->hmac = TLS_hmac;
03667     #endif
03668 
03669 
03670     ssl->cipher.ssl = ssl;
03671 
03672 #ifdef HAVE_EXTENDED_MASTER
03673     ssl->options.haveEMS = ctx->haveEMS;
03674 #endif
03675     ssl->options.useClientOrder = ctx->useClientOrder;
03676 
03677 #ifdef WOLFSSL_TLS13
03678 #ifdef HAVE_SESSION_TICKET
03679     ssl->options.noTicketTls13 = ctx->noTicketTls13;
03680 #endif
03681     ssl->options.noPskDheKe = ctx->noPskDheKe;
03682 #endif
03683 
03684 #ifdef HAVE_TLS_EXTENSIONS
03685 #ifdef HAVE_MAX_FRAGMENT
03686     ssl->max_fragment = MAX_RECORD_SIZE;
03687 #endif
03688 #ifdef HAVE_ALPN
03689     ssl->alpn_client_list = NULL;
03690     #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
03691         ssl->alpnSelect    = ctx->alpnSelect;
03692         ssl->alpnSelectArg = ctx->alpnSelectArg;
03693     #endif
03694 #endif
03695 #ifdef HAVE_SUPPORTED_CURVES
03696     ssl->options.userCurves = ctx->userCurves;
03697 #endif
03698 #endif /* HAVE_TLS_EXTENSIONS */
03699 
03700     /* default alert state (none) */
03701     ssl->alert_history.last_rx.code  = -1;
03702     ssl->alert_history.last_rx.level = -1;
03703     ssl->alert_history.last_tx.code  = -1;
03704     ssl->alert_history.last_tx.level = -1;
03705 
03706     InitCiphers(ssl);
03707     InitCipherSpecs(&ssl->specs);
03708 
03709     /* all done with init, now can return errors, call other stuff */
03710 
03711     if (!writeDup) {
03712         /* arrays */
03713         ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
03714                                                            DYNAMIC_TYPE_ARRAYS);
03715         if (ssl->arrays == NULL) {
03716             WOLFSSL_MSG("Arrays Memory error");
03717             return MEMORY_E;
03718         }
03719         XMEMSET(ssl->arrays, 0, sizeof(Arrays));
03720         ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
03721             DYNAMIC_TYPE_TMP_BUFFER);
03722         if (ssl->arrays->preMasterSecret == NULL) {
03723             return MEMORY_E;
03724         }
03725         XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN);
03726 
03727         /* suites */
03728         ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
03729                                    DYNAMIC_TYPE_SUITES);
03730         if (ssl->suites == NULL) {
03731             WOLFSSL_MSG("Suites Memory error");
03732             return MEMORY_E;
03733         }
03734     }
03735 
03736     /* Initialize SSL with the appropriate fields from it's ctx */
03737     /* requires valid arrays and suites unless writeDup ing */
03738     if ((ret =  SetSSL_CTX(ssl, ctx, writeDup)) != SSL_SUCCESS)
03739         return ret;
03740 
03741     ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
03742 
03743 #ifdef SINGLE_THREADED
03744     ssl->rng = ctx->rng;   /* CTX may have one, if so use it */
03745 #endif
03746 
03747     if (ssl->rng == NULL) {
03748         /* RNG */
03749         ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG);
03750         if (ssl->rng == NULL) {
03751             WOLFSSL_MSG("RNG Memory error");
03752             return MEMORY_E;
03753         }
03754         XMEMSET(ssl->rng, 0, sizeof(WC_RNG));
03755         ssl->options.weOwnRng = 1;
03756 
03757         /* FIPS RNG API does not accept a heap hint */
03758 #ifndef HAVE_FIPS
03759         if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap, ssl->devId)) != 0) {
03760             WOLFSSL_MSG("RNG Init error");
03761             return ret;
03762         }
03763 #else
03764         if ( (ret = wc_InitRng(ssl->rng)) != 0) {
03765             WOLFSSL_MSG("RNG Init error");
03766             return ret;
03767         }
03768 #endif
03769     }
03770 
03771     if (writeDup) {
03772         /* all done */
03773         return 0;
03774     }
03775 
03776     /* hsHashes */
03777     ret = InitHandshakeHashes(ssl);
03778     if (ret != 0)
03779         return ret;
03780 
03781 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
03782     if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
03783         ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
03784         if (ret != 0) {
03785             WOLFSSL_MSG("DTLS Cookie Secret error");
03786             return ret;
03787         }
03788     }
03789 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
03790 
03791 #ifdef HAVE_SECRET_CALLBACK
03792     ssl->sessionSecretCb  = NULL;
03793     ssl->sessionSecretCtx = NULL;
03794 #endif
03795 
03796 #ifdef HAVE_SESSION_TICKET
03797     ssl->session.ticket = ssl->session.staticTicket;
03798 #endif
03799     return 0;
03800 }
03801 
03802 
03803 /* free use of temporary arrays */
03804 void FreeArrays(WOLFSSL* ssl, int keep)
03805 {
03806     if (ssl->arrays) {
03807         if (keep) {
03808             /* keeps session id for user retrieval */
03809             XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
03810             ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
03811         }
03812         if (ssl->arrays->preMasterSecret) {
03813             XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
03814             ssl->arrays->preMasterSecret = NULL;
03815         }
03816         XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
03817         ssl->arrays->pendingMsg = NULL;
03818         ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */
03819     }
03820     XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
03821     ssl->arrays = NULL;
03822 }
03823 
03824 void FreeKey(WOLFSSL* ssl, int type, void** pKey)
03825 {
03826     if (ssl && pKey && *pKey) {
03827         switch (type) {
03828         #ifndef NO_RSA
03829             case DYNAMIC_TYPE_RSA:
03830                 wc_FreeRsaKey((RsaKey*)*pKey);
03831                 break;
03832         #endif /* ! NO_RSA */
03833         #ifdef HAVE_ECC
03834             case DYNAMIC_TYPE_ECC:
03835                 wc_ecc_free((ecc_key*)*pKey);
03836                 break;
03837         #endif /* HAVE_ECC */
03838         #ifndef NO_DH
03839             case DYNAMIC_TYPE_DH:
03840                 wc_FreeDhKey((DhKey*)*pKey);
03841                 break;
03842         #endif /* !NO_DH */
03843             default:
03844                 break;
03845         }
03846         XFREE(*pKey, ssl->heap, type);
03847 
03848         /* Reset pointer */
03849         *pKey = NULL;
03850     }
03851 }
03852 
03853 int AllocKey(WOLFSSL* ssl, int type, void** pKey)
03854 {
03855     int ret = BAD_FUNC_ARG;
03856     int sz = 0;
03857 
03858     if (ssl == NULL || pKey == NULL) {
03859         return BAD_FUNC_ARG;
03860     }
03861 
03862     /* Sanity check key destination */
03863     if (*pKey != NULL) {
03864         WOLFSSL_MSG("Key already present!");
03865         return BAD_STATE_E;
03866     }
03867 
03868     /* Determine size */
03869     switch (type) {
03870         case DYNAMIC_TYPE_RSA:
03871         #ifndef NO_RSA
03872             sz = sizeof(RsaKey);
03873         #endif /* ! NO_RSA */
03874             break;
03875         case DYNAMIC_TYPE_ECC:
03876         #ifdef HAVE_ECC
03877             sz = sizeof(ecc_key);
03878         #endif /* HAVE_ECC */
03879             break;
03880         case DYNAMIC_TYPE_DH:
03881         #ifndef NO_DH
03882             sz = sizeof(DhKey);
03883         #endif /* !NO_DH */
03884             break;
03885         default:
03886             return BAD_FUNC_ARG;
03887     }
03888 
03889     if (sz == 0) {
03890         return NOT_COMPILED_IN;
03891     }
03892 
03893     /* Allocate memeory for key */
03894     *pKey = XMALLOC(sz, ssl->heap, type);
03895     if (*pKey == NULL) {
03896         return MEMORY_E;
03897     }
03898 
03899     /* Initialize key */
03900     switch (type) {
03901     #ifndef NO_RSA
03902         case DYNAMIC_TYPE_RSA:
03903             ret = wc_InitRsaKey_ex((RsaKey*)*pKey, ssl->heap, ssl->devId);
03904             break;
03905     #endif /* ! NO_RSA */
03906     #ifdef HAVE_ECC
03907         case DYNAMIC_TYPE_ECC:
03908             ret = wc_ecc_init_ex((ecc_key*)*pKey, ssl->heap, ssl->devId);
03909             break;
03910     #endif /* HAVE_ECC */
03911     #ifndef NO_DH
03912         case DYNAMIC_TYPE_DH:
03913             ret = wc_InitDhKey_ex((DhKey*)*pKey, ssl->heap, ssl->devId);
03914             break;
03915     #endif /* !NO_DH */
03916         default:
03917             return BAD_FUNC_ARG;
03918     }
03919 
03920     /* On error free handshake key */
03921     if (ret != 0) {
03922         FreeKey(ssl, type, pKey);
03923     }
03924 
03925     return ret;
03926 }
03927 
03928 void FreeKeyExchange(WOLFSSL* ssl)
03929 {
03930     /* Cleanup signature buffer */
03931     if (ssl->buffers.sig.buffer) {
03932         XFREE(ssl->buffers.sig.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
03933         ssl->buffers.sig.buffer = NULL;
03934         ssl->buffers.sig.length = 0;
03935     }
03936 
03937     /* Cleanup digest buffer */
03938     if (ssl->buffers.digest.buffer) {
03939         XFREE(ssl->buffers.digest.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
03940         ssl->buffers.digest.buffer = NULL;
03941         ssl->buffers.digest.length = 0;
03942     }
03943 
03944     /* Free handshake key */
03945     FreeKey(ssl, ssl->hsType, &ssl->hsKey);
03946 
03947 #ifndef NO_DH
03948     /* Free temp DH key */
03949     FreeKey(ssl, DYNAMIC_TYPE_DH, (void**)&ssl->buffers.serverDH_Key);
03950 #endif
03951 
03952     /* Cleanup async */
03953 #ifdef WOLFSSL_ASYNC_CRYPT
03954     if (ssl->async.freeArgs) {
03955         ssl->async.freeArgs(ssl, ssl->async.args);
03956         ssl->async.freeArgs = NULL;
03957     }
03958 #endif
03959 }
03960 
03961 /* In case holding SSL object in array and don't want to free actual ssl */
03962 void SSL_ResourceFree(WOLFSSL* ssl)
03963 {
03964     /* Note: any resources used during the handshake should be released in the
03965      * function FreeHandshakeResources(). Be careful with the special cases
03966      * like the RNG which may optionally be kept for the whole session. (For
03967      * example with the RNG, it isn't used beyond the handshake except when
03968      * using stream ciphers where it is retained. */
03969 
03970     FreeCiphers(ssl);
03971     FreeArrays(ssl, 0);
03972     FreeKeyExchange(ssl);
03973     if (ssl->options.weOwnRng) {
03974         wc_FreeRng(ssl->rng);
03975         XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
03976     }
03977     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
03978     FreeHandshakeHashes(ssl);
03979     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
03980 
03981     /* clear keys struct after session */
03982     ForceZero(&ssl->keys, sizeof(Keys));
03983 
03984 #ifndef NO_DH
03985     if (ssl->buffers.serverDH_Priv.buffer) {
03986         ForceZero(ssl->buffers.serverDH_Priv.buffer,
03987                                              ssl->buffers.serverDH_Priv.length);
03988     }
03989     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
03990     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
03991     /* parameters (p,g) may be owned by ctx */
03992     if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
03993         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
03994         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
03995     }
03996 #endif /* !NO_DH */
03997 #ifndef NO_CERTS
03998     ssl->keepCert = 0; /* make sure certificate is free'd */
03999     wolfSSL_UnloadCertsKeys(ssl);
04000 #endif
04001 #ifndef NO_RSA
04002     FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
04003     ssl->peerRsaKeyPresent = 0;
04004 #endif
04005     if (ssl->buffers.inputBuffer.dynamicFlag)
04006         ShrinkInputBuffer(ssl, FORCED_FREE);
04007     if (ssl->buffers.outputBuffer.dynamicFlag)
04008         ShrinkOutputBuffer(ssl);
04009 #ifdef WOLFSSL_DTLS
04010     DtlsMsgPoolReset(ssl);
04011     if (ssl->dtls_rx_msg_list != NULL) {
04012         DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
04013         ssl->dtls_rx_msg_list = NULL;
04014         ssl->dtls_rx_msg_list_sz = 0;
04015     }
04016     XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
04017     ssl->buffers.dtlsCtx.peer.sa = NULL;
04018 #ifndef NO_WOLFSSL_SERVER
04019     XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
04020           DYNAMIC_TYPE_COOKIE_PWD);
04021 #endif
04022 #endif /* WOLFSSL_DTLS */
04023 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
04024     if (ssl->biord != ssl->biowr)        /* only free write if different */
04025         wolfSSL_BIO_free(ssl->biowr);
04026     wolfSSL_BIO_free(ssl->biord);        /* always free read bio */
04027 #endif
04028 #ifdef HAVE_LIBZ
04029     FreeStreams(ssl);
04030 #endif
04031 #ifdef HAVE_ECC
04032     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccKey);
04033     ssl->peerEccKeyPresent = 0;
04034     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
04035     ssl->peerEccDsaKeyPresent = 0;
04036     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->eccTempKey);
04037     ssl->eccTempKeyPresent = 0;
04038 #endif /* HAVE_ECC */
04039 #ifdef HAVE_PK_CALLBACKS
04040     #ifdef HAVE_ECC
04041         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
04042     #endif /* HAVE_ECC */
04043     #ifndef NO_RSA
04044         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
04045     #endif /* NO_RSA */
04046 #endif /* HAVE_PK_CALLBACKS */
04047 #ifdef HAVE_TLS_EXTENSIONS
04048     TLSX_FreeAll(ssl->extensions, ssl->heap);
04049 
04050 #ifdef HAVE_ALPN
04051     if (ssl->alpn_client_list != NULL) {
04052         XFREE(ssl->alpn_client_list, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
04053         ssl->alpn_client_list = NULL;
04054     }
04055 #endif
04056 #endif /* HAVE_TLS_EXTENSIONS */
04057 #ifdef HAVE_NETX
04058     if (ssl->nxCtx.nxPacket)
04059         nx_packet_release(ssl->nxCtx.nxPacket);
04060 #endif
04061 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
04062     FreeX509(&ssl->peerCert);
04063 #endif
04064 
04065 #ifdef HAVE_SESSION_TICKET
04066     if (ssl->session.isDynamic) {
04067         XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
04068         ssl->session.ticket = ssl->session.staticTicket;
04069         ssl->session.isDynamic = 0;
04070         ssl->session.ticketLen = 0;
04071     }
04072 #endif
04073 #ifdef HAVE_EXT_CACHE
04074     wolfSSL_SESSION_free(ssl->extSession);
04075 #endif
04076 #ifdef HAVE_WRITE_DUP
04077     if (ssl->dupWrite) {
04078         FreeWriteDup(ssl);
04079     }
04080 #endif
04081 
04082 #ifdef WOLFSSL_STATIC_MEMORY
04083     /* check if using fixed io buffers and free them */
04084     if (ssl->heap != NULL) {
04085     #ifdef WOLFSSL_HEAP_TEST
04086     /* avoid dereferencing a test value */
04087     if (ssl->heap != (void*)WOLFSSL_HEAP_TEST) {
04088     #endif
04089         WOLFSSL_HEAP_HINT* ssl_hint = (WOLFSSL_HEAP_HINT*)ssl->heap;
04090         WOLFSSL_HEAP*      ctx_heap;
04091 
04092         ctx_heap = ssl_hint->memory;
04093         if (wc_LockMutex(&(ctx_heap->memory_mutex)) != 0) {
04094             WOLFSSL_MSG("Bad memory_mutex lock");
04095         }
04096         ctx_heap->curIO--;
04097         if (FreeFixedIO(ctx_heap, &(ssl_hint->outBuf)) != 1) {
04098             WOLFSSL_MSG("Error freeing fixed output buffer");
04099         }
04100         if (FreeFixedIO(ctx_heap, &(ssl_hint->inBuf)) != 1) {
04101             WOLFSSL_MSG("Error freeing fixed output buffer");
04102         }
04103         if (ssl_hint->haFlag) { /* check if handshake count has been decreased*/
04104             ctx_heap->curHa--;
04105         }
04106         wc_UnLockMutex(&(ctx_heap->memory_mutex));
04107 
04108         /* check if tracking stats */
04109         if (ctx_heap->flag & WOLFMEM_TRACK_STATS) {
04110             XFREE(ssl_hint->stats, ssl->ctx->heap, DYNAMIC_TYPE_SSL);
04111         }
04112         XFREE(ssl->heap, ssl->ctx->heap, DYNAMIC_TYPE_SSL);
04113     #ifdef WOLFSSL_HEAP_TEST
04114     }
04115     #endif
04116     }
04117 #endif /* WOLFSSL_STATIC_MEMORY */
04118 }
04119 
04120 /* Free any handshake resources no longer needed */
04121 void FreeHandshakeResources(WOLFSSL* ssl)
04122 {
04123 
04124 #ifdef HAVE_SECURE_RENEGOTIATION
04125     if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
04126         WOLFSSL_MSG("Secure Renegotiation needs to retain handshake resources");
04127         return;
04128     }
04129 #endif
04130 
04131     /* input buffer */
04132     if (ssl->buffers.inputBuffer.dynamicFlag)
04133         ShrinkInputBuffer(ssl, NO_FORCED_FREE);
04134 
04135     /* suites */
04136     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
04137     ssl->suites = NULL;
04138 
04139     /* hsHashes */
04140     FreeHandshakeHashes(ssl);
04141 
04142     /* RNG */
04143     if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
04144         if (ssl->options.weOwnRng) {
04145             wc_FreeRng(ssl->rng);
04146             XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
04147             ssl->rng = NULL;
04148             ssl->options.weOwnRng = 0;
04149         }
04150     }
04151 
04152 #ifdef WOLFSSL_DTLS
04153     /* DTLS_POOL */
04154     if (ssl->options.dtls) {
04155         DtlsMsgPoolReset(ssl);
04156         DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
04157         ssl->dtls_rx_msg_list = NULL;
04158         ssl->dtls_rx_msg_list_sz = 0;
04159     }
04160 #endif
04161 
04162     /* arrays */
04163     if (ssl->options.saveArrays == 0)
04164         FreeArrays(ssl, 1);
04165 
04166 #ifndef NO_RSA
04167     /* peerRsaKey */
04168     FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey);
04169     ssl->peerRsaKeyPresent = 0;
04170 #endif
04171 
04172 #ifdef HAVE_ECC
04173     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccKey);
04174     ssl->peerEccKeyPresent = 0;
04175     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey);
04176     ssl->peerEccDsaKeyPresent = 0;
04177     FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->eccTempKey);
04178     ssl->eccTempKeyPresent = 0;
04179 #endif /* HAVE_ECC */
04180 #ifndef NO_DH
04181     if (ssl->buffers.serverDH_Priv.buffer) {
04182         ForceZero(ssl->buffers.serverDH_Priv.buffer,
04183                                              ssl->buffers.serverDH_Priv.length);
04184     }
04185     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
04186     ssl->buffers.serverDH_Priv.buffer = NULL;
04187     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
04188     ssl->buffers.serverDH_Pub.buffer = NULL;
04189     /* parameters (p,g) may be owned by ctx */
04190     if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
04191         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
04192         ssl->buffers.serverDH_G.buffer = NULL;
04193         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
04194         ssl->buffers.serverDH_P.buffer = NULL;
04195     }
04196 #endif /* !NO_DH */
04197 #ifndef NO_CERTS
04198     wolfSSL_UnloadCertsKeys(ssl);
04199 #endif
04200 #ifdef HAVE_PK_CALLBACKS
04201     #ifdef HAVE_ECC
04202         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
04203         ssl->buffers.peerEccDsaKey.buffer = NULL;
04204     #endif /* HAVE_ECC */
04205     #ifndef NO_RSA
04206         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
04207         ssl->buffers.peerRsaKey.buffer = NULL;
04208     #endif /* NO_RSA */
04209 #endif /* HAVE_PK_CALLBACKS */
04210 
04211 #ifdef HAVE_QSH
04212     QSH_FreeAll(ssl);
04213 #endif
04214 
04215 #ifdef HAVE_SESSION_TICKET
04216     if (ssl->session.isDynamic) {
04217         XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
04218         ssl->session.ticket = ssl->session.staticTicket;
04219         ssl->session.isDynamic = 0;
04220         ssl->session.ticketLen = 0;
04221     }
04222 #endif
04223 
04224 #ifdef WOLFSSL_STATIC_MEMORY
04225     /* when done with handshake decrement current handshake count */
04226     if (ssl->heap != NULL) {
04227     #ifdef WOLFSSL_HEAP_TEST
04228     /* avoid dereferencing a test value */
04229     if (ssl->heap != (void*)WOLFSSL_HEAP_TEST) {
04230     #endif
04231         WOLFSSL_HEAP_HINT* ssl_hint = (WOLFSSL_HEAP_HINT*)ssl->heap;
04232         WOLFSSL_HEAP*      ctx_heap;
04233 
04234         ctx_heap = ssl_hint->memory;
04235         if (wc_LockMutex(&(ctx_heap->memory_mutex)) != 0) {
04236             WOLFSSL_MSG("Bad memory_mutex lock");
04237         }
04238         ctx_heap->curHa--;
04239         ssl_hint->haFlag = 0; /* set to zero since handshake has been dec */
04240         wc_UnLockMutex(&(ctx_heap->memory_mutex));
04241     #ifdef WOLFSSL_HEAP_TEST
04242     }
04243     #endif
04244     }
04245 #endif /* WOLFSSL_STATIC_MEMORY */
04246 }
04247 
04248 
04249 /* heap argument is the heap hint used when creating SSL */
04250 void FreeSSL(WOLFSSL* ssl, void* heap)
04251 {
04252     if (ssl->ctx) {
04253         FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
04254     }
04255     SSL_ResourceFree(ssl);
04256     XFREE(ssl, heap, DYNAMIC_TYPE_SSL);
04257     (void)heap;
04258 }
04259 
04260 
04261 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
04262     || defined(HAVE_AESGCM) || defined(WOLFSSL_DTLS)
04263 static INLINE void GetSEQIncrement(WOLFSSL* ssl, int verify, word32 seq[2])
04264 {
04265     if (verify) {
04266         seq[0] = ssl->keys.peer_sequence_number_hi;
04267         seq[1] = ssl->keys.peer_sequence_number_lo++;
04268         if (seq[1] > ssl->keys.peer_sequence_number_lo) {
04269             /* handle rollover */
04270             ssl->keys.peer_sequence_number_hi++;
04271         }
04272     }
04273     else {
04274         seq[0] = ssl->keys.sequence_number_hi;
04275         seq[1] = ssl->keys.sequence_number_lo++;
04276         if (seq[1] > ssl->keys.sequence_number_lo) {
04277             /* handle rollover */
04278             ssl->keys.sequence_number_hi++;
04279         }
04280     }
04281 }
04282 
04283 
04284 #ifdef WOLFSSL_DTLS
04285 static INLINE void DtlsGetSEQ(WOLFSSL* ssl, int order, word32 seq[2])
04286 {
04287     if (order == PREV_ORDER) {
04288         /* Previous epoch case */
04289         seq[0] = ((ssl->keys.dtls_epoch - 1) << 16) |
04290                  (ssl->keys.dtls_prev_sequence_number_hi & 0xFFFF);
04291         seq[1] = ssl->keys.dtls_prev_sequence_number_lo;
04292     }
04293     else if (order == PEER_ORDER) {
04294         seq[0] = (ssl->keys.curEpoch << 16) |
04295                  (ssl->keys.curSeq_hi & 0xFFFF);
04296         seq[1] = ssl->keys.curSeq_lo; /* explicit from peer */
04297     }
04298     else {
04299         seq[0] = (ssl->keys.dtls_epoch << 16) |
04300                  (ssl->keys.dtls_sequence_number_hi & 0xFFFF);
04301         seq[1] = ssl->keys.dtls_sequence_number_lo;
04302     }
04303 }
04304 
04305 static INLINE void DtlsSEQIncrement(WOLFSSL* ssl, int order)
04306 {
04307     word32 seq;
04308 
04309     if (order == PREV_ORDER) {
04310         seq = ssl->keys.dtls_prev_sequence_number_lo++;
04311         if (seq > ssl->keys.dtls_prev_sequence_number_lo) {
04312             /* handle rollover */
04313             ssl->keys.dtls_prev_sequence_number_hi++;
04314         }
04315     }
04316     else if (order == PEER_ORDER) {
04317         seq = ssl->keys.peer_sequence_number_lo++;
04318         if (seq > ssl->keys.peer_sequence_number_lo) {
04319             /* handle rollover */
04320             ssl->keys.peer_sequence_number_hi++;
04321         }
04322     }
04323     else {
04324         seq = ssl->keys.dtls_sequence_number_lo++;
04325         if (seq > ssl->keys.dtls_sequence_number_lo) {
04326             /* handle rollover */
04327             ssl->keys.dtls_sequence_number_hi++;
04328         }
04329     }
04330 }
04331 #endif /* WOLFSSL_DTLS */
04332 
04333 
04334 static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
04335 {
04336     word32 seq[2] = {0, 0};
04337 
04338     if (!ssl->options.dtls) {
04339         GetSEQIncrement(ssl, verifyOrder, seq);
04340     }
04341     else {
04342 #ifdef WOLFSSL_DTLS
04343         DtlsGetSEQ(ssl, verifyOrder, seq);
04344 #endif
04345     }
04346 
04347     c32toa(seq[0], out);
04348     c32toa(seq[1], out + OPAQUE32_LEN);
04349 }
04350 #endif
04351 
04352 
04353 #ifdef WOLFSSL_DTLS
04354 
04355 /* functions for managing DTLS datagram reordering */
04356 
04357 /* Need to allocate space for the handshake message header. The hashing
04358  * routines assume the message pointer is still within the buffer that
04359  * has the headers, and will include those headers in the hash. The store
04360  * routines need to take that into account as well. New will allocate
04361  * extra space for the headers. */
04362 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
04363 {
04364     DtlsMsg* msg = NULL;
04365 
04366     (void)heap;
04367     msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
04368 
04369     if (msg != NULL) {
04370         XMEMSET(msg, 0, sizeof(DtlsMsg));
04371         msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
04372                                                 heap, DYNAMIC_TYPE_DTLS_BUFFER);
04373         if (msg->buf != NULL) {
04374             msg->sz = sz;
04375             msg->type = no_shake;
04376             msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
04377         }
04378         else {
04379             XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
04380             msg = NULL;
04381         }
04382     }
04383 
04384     return msg;
04385 }
04386 
04387 void DtlsMsgDelete(DtlsMsg* item, void* heap)
04388 {
04389     (void)heap;
04390 
04391     if (item != NULL) {
04392         DtlsFrag* cur = item->fragList;
04393         while (cur != NULL) {
04394             DtlsFrag* next = cur->next;
04395             XFREE(cur, heap, DYNAMIC_TYPE_DTLS_FRAG);
04396             cur = next;
04397         }
04398         if (item->buf != NULL)
04399             XFREE(item->buf, heap, DYNAMIC_TYPE_DTLS_BUFFER);
04400         XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
04401     }
04402 }
04403 
04404 
04405 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
04406 {
04407     DtlsMsg* next;
04408     while (head) {
04409         next = head->next;
04410         DtlsMsgDelete(head, heap);
04411         head = next;
04412     }
04413 }
04414 
04415 
04416 /* Create a DTLS Fragment from *begin - end, adjust new *begin and bytesLeft */
04417 static DtlsFrag* CreateFragment(word32* begin, word32 end, const byte* data,
04418                                 byte* buf, word32* bytesLeft, void* heap)
04419 {
04420     DtlsFrag* newFrag;
04421     word32 added = end - *begin + 1;
04422 
04423     (void)heap;
04424     newFrag = (DtlsFrag*)XMALLOC(sizeof(DtlsFrag), heap,
04425                                  DYNAMIC_TYPE_DTLS_FRAG);
04426     if (newFrag != NULL) {
04427         newFrag->next = NULL;
04428         newFrag->begin = *begin;
04429         newFrag->end = end;
04430 
04431         XMEMCPY(buf + *begin, data, added);
04432         *bytesLeft -= added;
04433         *begin = newFrag->end + 1;
04434     }
04435 
04436     return newFrag;
04437 }
04438 
04439 
04440 int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
04441                                    word32 fragOffset, word32 fragSz, void* heap)
04442 {
04443     if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
04444                                              (fragOffset + fragSz) <= msg->sz) {
04445         DtlsFrag* cur = msg->fragList;
04446         DtlsFrag* prev = cur;
04447         DtlsFrag* newFrag;
04448         word32 bytesLeft = fragSz; /* could be overlapping fragment */
04449         word32 startOffset = fragOffset;
04450         word32 added;
04451 
04452         msg->seq = seq;
04453         msg->type = type;
04454 
04455         if (fragOffset == 0) {
04456             XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
04457                     DTLS_HANDSHAKE_HEADER_SZ);
04458             c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
04459         }
04460 
04461         /* if no mesage data, just return */
04462         if (fragSz == 0)
04463             return 0;
04464 
04465         /* if list is empty add full fragment to front */
04466         if (cur == NULL) {
04467             newFrag = CreateFragment(&fragOffset, fragOffset + fragSz - 1, data,
04468                                      msg->msg, &bytesLeft, heap);
04469             if (newFrag == NULL)
04470                 return MEMORY_E;
04471 
04472             msg->fragSz = fragSz;
04473             msg->fragList = newFrag;
04474 
04475             return 0;
04476         }
04477 
04478         /* add to front if before current front, up to next->begin */
04479         if (fragOffset < cur->begin) {
04480             word32 end = fragOffset + fragSz - 1;
04481 
04482             if (end >= cur->begin)
04483                 end = cur->begin - 1;
04484 
04485             added = end - fragOffset + 1;
04486             newFrag = CreateFragment(&fragOffset, end, data, msg->msg,
04487                                      &bytesLeft, heap);
04488             if (newFrag == NULL)
04489                 return MEMORY_E;
04490 
04491             msg->fragSz += added;
04492 
04493             newFrag->next = cur;
04494             msg->fragList = newFrag;
04495         }
04496 
04497         /* while we have bytes left, try to find a gap to fill */
04498         while (bytesLeft > 0) {
04499             /* get previous packet in list */
04500             while (cur && (fragOffset >= cur->begin)) {
04501                 prev = cur;
04502                 cur = cur->next;
04503             }
04504 
04505             /* don't add duplicate data */
04506             if (prev->end >= fragOffset) {
04507                 if ( (fragOffset + bytesLeft - 1) <= prev->end)
04508                     return 0;
04509                 fragOffset = prev->end + 1;
04510                 bytesLeft = startOffset + fragSz - fragOffset;
04511             }
04512 
04513             if (cur == NULL)
04514                 /* we're at the end */
04515                 added = bytesLeft;
04516             else
04517                 /* we're in between two frames */
04518                 added = min(bytesLeft, cur->begin - fragOffset);
04519 
04520             /* data already there */
04521             if (added == 0)
04522                 continue;
04523 
04524             newFrag = CreateFragment(&fragOffset, fragOffset + added - 1,
04525                                      data + fragOffset - startOffset,
04526                                      msg->msg, &bytesLeft, heap);
04527             if (newFrag == NULL)
04528                 return MEMORY_E;
04529 
04530             msg->fragSz += added;
04531 
04532             newFrag->next = prev->next;
04533             prev->next = newFrag;
04534         }
04535     }
04536 
04537     return 0;
04538 }
04539 
04540 
04541 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
04542 {
04543     while (head != NULL && head->seq != seq) {
04544         head = head->next;
04545     }
04546     return head;
04547 }
04548 
04549 
04550 void DtlsMsgStore(WOLFSSL* ssl, word32 seq, const byte* data,
04551         word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
04552 {
04553     /* See if seq exists in the list. If it isn't in the list, make
04554      * a new item of size dataSz, copy fragSz bytes from data to msg->msg
04555      * starting at offset fragOffset, and add fragSz to msg->fragSz. If
04556      * the seq is in the list and it isn't full, copy fragSz bytes from
04557      * data to msg->msg starting at offset fragOffset, and add fragSz to
04558      * msg->fragSz. Insertions take into account data already in the list
04559      * in case there are overlaps in the handshake message due to retransmit
04560      * messages. The new item should be inserted into the list in its
04561      * proper position.
04562      *
04563      * 1. Find seq in list, or where seq should go in list. If seq not in
04564      *    list, create new item and insert into list. Either case, keep
04565      *    pointer to item.
04566      * 2. Copy the data from the message to the stored message where it
04567      *    belongs without overlaps.
04568      */
04569 
04570     DtlsMsg* head = ssl->dtls_rx_msg_list;
04571 
04572     if (head != NULL) {
04573         DtlsMsg* cur = DtlsMsgFind(head, seq);
04574         if (cur == NULL) {
04575             cur = DtlsMsgNew(dataSz, heap);
04576             if (cur != NULL) {
04577                 if (DtlsMsgSet(cur, seq, data, type,
04578                                                 fragOffset, fragSz, heap) < 0) {
04579                     DtlsMsgDelete(cur, heap);
04580                 }
04581                 else {
04582                     ssl->dtls_rx_msg_list_sz++;
04583                     head = DtlsMsgInsert(head, cur);
04584                 }
04585             }
04586         }
04587         else {
04588             /* If this fails, the data is just dropped. */
04589             DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap);
04590         }
04591     }
04592     else {
04593         head = DtlsMsgNew(dataSz, heap);
04594         if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) {
04595             DtlsMsgDelete(head, heap);
04596             head = NULL;
04597         }
04598         else {
04599             ssl->dtls_rx_msg_list_sz++;
04600         }
04601     }
04602 
04603     ssl->dtls_rx_msg_list = head;
04604 }
04605 
04606 
04607 /* DtlsMsgInsert() is an in-order insert. */
04608 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
04609 {
04610     if (head == NULL || item->seq < head->seq) {
04611         item->next = head;
04612         head = item;
04613     }
04614     else if (head->next == NULL) {
04615         head->next = item;
04616     }
04617     else {
04618         DtlsMsg* cur = head->next;
04619         DtlsMsg* prev = head;
04620         while (cur) {
04621             if (item->seq < cur->seq) {
04622                 item->next = cur;
04623                 prev->next = item;
04624                 break;
04625             }
04626             prev = cur;
04627             cur = cur->next;
04628         }
04629         if (cur == NULL) {
04630             prev->next = item;
04631         }
04632     }
04633 
04634     return head;
04635 }
04636 
04637 
04638 /* DtlsMsgPoolSave() adds the message to the end of the stored transmit list. */
04639 int DtlsMsgPoolSave(WOLFSSL* ssl, const byte* data, word32 dataSz)
04640 {
04641     DtlsMsg* item;
04642     int ret = 0;
04643 
04644     if (ssl->dtls_tx_msg_list_sz > DTLS_POOL_SZ)
04645         return DTLS_POOL_SZ_E;
04646 
04647     item = DtlsMsgNew(dataSz, ssl->heap);
04648 
04649     if (item != NULL) {
04650         DtlsMsg* cur = ssl->dtls_tx_msg_list;
04651 
04652         XMEMCPY(item->buf, data, dataSz);
04653         item->sz = dataSz;
04654         item->seq = ssl->keys.dtls_epoch;
04655 
04656         if (cur == NULL)
04657             ssl->dtls_tx_msg_list = item;
04658         else {
04659             while (cur->next)
04660                 cur = cur->next;
04661             cur->next = item;
04662         }
04663         ssl->dtls_tx_msg_list_sz++;
04664     }
04665     else
04666         ret = MEMORY_E;
04667 
04668     return ret;
04669 }
04670 
04671 
04672 /* DtlsMsgPoolTimeout() updates the timeout time. */
04673 int DtlsMsgPoolTimeout(WOLFSSL* ssl)
04674 {
04675     int result = -1;
04676     if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
04677         ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
04678         result = 0;
04679     }
04680     return result;
04681 }
04682 
04683 
04684 /* DtlsMsgPoolReset() deletes the stored transmit list and resets the timeout
04685  * value. */
04686 void DtlsMsgPoolReset(WOLFSSL* ssl)
04687 {
04688     if (ssl->dtls_tx_msg_list) {
04689         DtlsMsgListDelete(ssl->dtls_tx_msg_list, ssl->heap);
04690         ssl->dtls_tx_msg_list = NULL;
04691         ssl->dtls_tx_msg_list_sz = 0;
04692         ssl->dtls_timeout = ssl->dtls_timeout_init;
04693     }
04694 }
04695 
04696 
04697 int VerifyForDtlsMsgPoolSend(WOLFSSL* ssl, byte type, word32 fragOffset)
04698 {
04699     /**
04700      * only the first message from previous flight should be valid
04701      * to be used for triggering retransmission of whole DtlsMsgPool.
04702      * change cipher suite type is not verified here
04703      */
04704     return ((fragOffset == 0) &&
04705            (((ssl->options.side == WOLFSSL_SERVER_END) &&
04706              ((type == client_hello) ||
04707              ((ssl->options.verifyPeer) && (type == certificate)) ||
04708              ((!ssl->options.verifyPeer) && (type == client_key_exchange)))) ||
04709             ((ssl->options.side == WOLFSSL_CLIENT_END) &&
04710              (type == server_hello))));
04711 }
04712 
04713 
04714 /* DtlsMsgPoolSend() will send the stored transmit list. The stored list is
04715  * updated with new sequence numbers, and will be re-encrypted if needed. */
04716 int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
04717 {
04718     int ret = 0;
04719     DtlsMsg* pool = ssl->dtls_tx_msg_list;
04720 
04721     if (pool != NULL) {
04722 
04723         while (pool != NULL) {
04724             if (pool->seq == 0) {
04725                 DtlsRecordLayerHeader* dtls;
04726                 int epochOrder;
04727 
04728                 dtls = (DtlsRecordLayerHeader*)pool->buf;
04729                 /* If the stored record's epoch is 0, and the currently set
04730                  * epoch is 0, use the "current order" sequence number.
04731                  * If the stored record's epoch is 0 and the currently set
04732                  * epoch is not 0, the stored record is considered a "previous
04733                  * order" sequence number. */
04734                 epochOrder = (ssl->keys.dtls_epoch == 0) ?
04735                              CUR_ORDER : PREV_ORDER;
04736 
04737                 WriteSEQ(ssl, epochOrder, dtls->sequence_number);
04738                 DtlsSEQIncrement(ssl, epochOrder);
04739                 if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0)
04740                     return ret;
04741 
04742                 XMEMCPY(ssl->buffers.outputBuffer.buffer,
04743                         pool->buf, pool->sz);
04744                 ssl->buffers.outputBuffer.idx = 0;
04745                 ssl->buffers.outputBuffer.length = pool->sz;
04746             }
04747             else if (pool->seq == ssl->keys.dtls_epoch) {
04748                 byte*  input;
04749                 byte*  output;
04750                 int    inputSz, sendSz;
04751 
04752                 input = pool->buf;
04753                 inputSz = pool->sz;
04754                 sendSz = inputSz + MAX_MSG_EXTRA;
04755 
04756                 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
04757                     return ret;
04758 
04759                 output = ssl->buffers.outputBuffer.buffer +
04760                          ssl->buffers.outputBuffer.length;
04761                 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
04762                                       handshake, 0, 0, 0);
04763                 if (sendSz < 0)
04764                     return BUILD_MSG_ERROR;
04765 
04766                 ssl->buffers.outputBuffer.length += sendSz;
04767             }
04768 
04769             ret = SendBuffered(ssl);
04770             if (ret < 0) {
04771                 return ret;
04772             }
04773 
04774             /**
04775              * on server side, retranmission is being triggered only by sending
04776              * first message of given flight, in order to trigger client
04777              * to retransmit its whole flight. Sending the whole previous flight
04778              * could lead to retranmission of previous client flight for each
04779              * server message from previous flight. Therefore one message should
04780              * be enough to do the trick.
04781              */
04782             if (sendOnlyFirstPacket &&
04783                 ssl->options.side == WOLFSSL_SERVER_END) {
04784 
04785                 pool = NULL;
04786             }
04787             else
04788                 pool = pool->next;
04789         }
04790     }
04791 
04792     return ret;
04793 }
04794 
04795 #endif /* WOLFSSL_DTLS */
04796 
04797 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
04798 
04799 ProtocolVersion MakeSSLv3(void)
04800 {
04801     ProtocolVersion pv;
04802     pv.major = SSLv3_MAJOR;
04803     pv.minor = SSLv3_MINOR;
04804 
04805     return pv;
04806 }
04807 
04808 #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
04809 
04810 
04811 #ifdef WOLFSSL_DTLS
04812 
04813 ProtocolVersion MakeDTLSv1(void)
04814 {
04815     ProtocolVersion pv;
04816     pv.major = DTLS_MAJOR;
04817     pv.minor = DTLS_MINOR;
04818 
04819     return pv;
04820 }
04821 
04822 ProtocolVersion MakeDTLSv1_2(void)
04823 {
04824     ProtocolVersion pv;
04825     pv.major = DTLS_MAJOR;
04826     pv.minor = DTLSv1_2_MINOR;
04827 
04828     return pv;
04829 }
04830 
04831 #endif /* WOLFSSL_DTLS */
04832 
04833 
04834 
04835 
04836 #if defined(USER_TICKS)
04837 #if 0
04838     word32 LowResTimer(void)
04839     {
04840         /*
04841         write your own clock tick function if don't want time(0)
04842         needs second accuracy but doesn't have to correlated to EPOCH
04843         */
04844     }
04845 #endif
04846 
04847 #elif defined(TIME_OVERRIDES)
04848 
04849     /* use same asn time overrides unless user wants tick override above */
04850 
04851     #ifndef HAVE_TIME_T_TYPE
04852         typedef long time_t;
04853     #endif
04854     extern time_t XTIME(time_t * timer);
04855 
04856     word32 LowResTimer(void)
04857     {
04858         return (word32) XTIME(0);
04859     }
04860 
04861 #elif defined(USE_WINDOWS_API)
04862 
04863     word32 LowResTimer(void)
04864     {
04865         static int           init = 0;
04866         static LARGE_INTEGER freq;
04867         LARGE_INTEGER        count;
04868 
04869         if (!init) {
04870             QueryPerformanceFrequency(&freq);
04871             init = 1;
04872         }
04873 
04874         QueryPerformanceCounter(&count);
04875 
04876         return (word32)(count.QuadPart / freq.QuadPart);
04877     }
04878 
04879 #elif defined(HAVE_RTP_SYS)
04880 
04881     #include "rtptime.h"
04882 
04883     word32 LowResTimer(void)
04884     {
04885         return (word32)rtp_get_system_sec();
04886     }
04887 
04888 
04889 #elif defined(MICRIUM)
04890 
04891     word32 LowResTimer(void)
04892     {
04893         NET_SECURE_OS_TICK  clk = 0;
04894 
04895         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
04896             clk = NetSecure_OS_TimeGet();
04897         #endif
04898         return (word32)clk;
04899     }
04900 
04901 
04902 #elif defined(MICROCHIP_TCPIP_V5)
04903 
04904     word32 LowResTimer(void)
04905     {
04906         return (word32) (TickGet() / TICKS_PER_SECOND);
04907     }
04908 
04909 
04910 #elif defined(MICROCHIP_TCPIP)
04911 
04912     #if defined(MICROCHIP_MPLAB_HARMONY)
04913 
04914         #include <system/tmr/sys_tmr.h>
04915 
04916         word32 LowResTimer(void)
04917         {
04918             return (word32) (SYS_TMR_TickCountGet() /
04919                              SYS_TMR_TickCounterFrequencyGet());
04920         }
04921 
04922     #else
04923 
04924         word32 LowResTimer(void)
04925         {
04926             return (word32) (SYS_TICK_Get() / SYS_TICK_TicksPerSecondGet());
04927         }
04928 
04929     #endif
04930 
04931 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
04932 
04933     word32 LowResTimer(void)
04934     {
04935         TIME_STRUCT mqxTime;
04936 
04937         _time_get_elapsed(&mqxTime);
04938 
04939         return (word32) mqxTime.SECONDS;
04940     }
04941 #elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
04942 
04943     #include "include/task.h"
04944 
04945     unsigned int LowResTimer(void)
04946     {
04947         return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ);
04948     }
04949 
04950 #elif defined(FREESCALE_KSDK_BM)
04951 
04952     #include "lwip/sys.h" /* lwIP */
04953     word32 LowResTimer(void)
04954     {
04955         return sys_now()/1000;
04956     }
04957 
04958 #elif defined(WOLFSSL_TIRTOS)
04959 
04960     word32 LowResTimer(void)
04961     {
04962         return (word32) Seconds_get();
04963     }
04964 
04965 #elif defined(WOLFSSL_UTASKER)
04966 
04967     word32 LowResTimer(void)
04968     {
04969         return (word32)(uTaskerSystemTick / TICK_RESOLUTION);
04970     }
04971 
04972 #else
04973     /* Posix style time */
04974     #include <time.h>
04975 
04976     word32 LowResTimer(void)
04977     {
04978         return (word32)time(0);
04979     }
04980 
04981 
04982 #endif
04983 
04984 
04985 #ifndef NO_CERTS
04986 int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz)
04987 {
04988     int ret = 0;
04989 
04990     (void)output;
04991     (void)sz;
04992 
04993 #ifdef HAVE_FUZZER
04994     if (ssl->fuzzerCb)
04995         ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
04996 #endif
04997 #ifndef NO_OLD_TLS
04998 #ifndef NO_SHA
04999     wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz);
05000 #endif
05001 #ifndef NO_MD5
05002     wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz);
05003 #endif
05004 #endif /* NO_OLD_TLS */
05005 
05006     if (IsAtLeastTLSv1_2(ssl)) {
05007 #ifndef NO_SHA256
05008         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, output, sz);
05009         if (ret != 0)
05010             return ret;
05011 #endif
05012 #ifdef WOLFSSL_SHA384
05013         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, output, sz);
05014         if (ret != 0)
05015             return ret;
05016 #endif
05017 #ifdef WOLFSSL_SHA512
05018         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, output, sz);
05019         if (ret != 0)
05020             return ret;
05021 #endif
05022     }
05023 
05024     return ret;
05025 }
05026 #endif /* NO_CERTS */
05027 
05028 
05029 /* add output to md5 and sha handshake hashes, exclude record header */
05030 int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
05031 {
05032     int ret = 0;
05033     const byte* adj;
05034 
05035     adj = output + RECORD_HEADER_SZ + ivSz;
05036     sz -= RECORD_HEADER_SZ;
05037 
05038 #ifdef HAVE_FUZZER
05039     if (ssl->fuzzerCb)
05040         ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
05041 #endif
05042 #ifdef WOLFSSL_DTLS
05043     if (ssl->options.dtls) {
05044         adj += DTLS_RECORD_EXTRA;
05045         sz  -= DTLS_RECORD_EXTRA;
05046     }
05047 #endif
05048 #ifndef NO_OLD_TLS
05049 #ifndef NO_SHA
05050     wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
05051 #endif
05052 #ifndef NO_MD5
05053     wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
05054 #endif
05055 #endif
05056 
05057     if (IsAtLeastTLSv1_2(ssl)) {
05058 #ifndef NO_SHA256
05059         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
05060         if (ret != 0)
05061             return ret;
05062 #endif
05063 #ifdef WOLFSSL_SHA384
05064         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
05065         if (ret != 0)
05066             return ret;
05067 #endif
05068 #ifdef WOLFSSL_SHA512
05069         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
05070         if (ret != 0)
05071             return ret;
05072 #endif
05073     }
05074 
05075     return ret;
05076 }
05077 
05078 
05079 /* add input to md5 and sha handshake hashes, include handshake header */
05080 int HashInput(WOLFSSL* ssl, const byte* input, int sz)
05081 {
05082     int ret = 0;
05083     const byte* adj;
05084 
05085     adj = input - HANDSHAKE_HEADER_SZ;
05086     sz += HANDSHAKE_HEADER_SZ;
05087 
05088     (void)adj;
05089 
05090 #ifdef WOLFSSL_DTLS
05091     if (ssl->options.dtls) {
05092         adj -= DTLS_HANDSHAKE_EXTRA;
05093         sz  += DTLS_HANDSHAKE_EXTRA;
05094     }
05095 #endif
05096 
05097 #ifndef NO_OLD_TLS
05098 #ifndef NO_SHA
05099     wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
05100 #endif
05101 #ifndef NO_MD5
05102     wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
05103 #endif
05104 #endif
05105 
05106     if (IsAtLeastTLSv1_2(ssl)) {
05107 #ifndef NO_SHA256
05108         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
05109         if (ret != 0)
05110             return ret;
05111 #endif
05112 #ifdef WOLFSSL_SHA384
05113         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
05114         if (ret != 0)
05115             return ret;
05116 #endif
05117 #ifdef WOLFSSL_SHA512
05118         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
05119         if (ret != 0)
05120             return ret;
05121 #endif
05122     }
05123 
05124     return ret;
05125 }
05126 
05127 
05128 /* add record layer header for message */
05129 static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl)
05130 {
05131     RecordLayerHeader* rl;
05132 
05133     /* record layer header */
05134     rl = (RecordLayerHeader*)output;
05135     if (rl == NULL) {
05136         return;
05137     }
05138     rl->type    = type;
05139     rl->pvMajor = ssl->version.major;       /* type and version same in each */
05140 #ifdef WOLFSSL_TLS13
05141     if (IsAtLeastTLSv1_3(ssl->version))
05142         rl->pvMinor = TLSv1_MINOR;
05143     else
05144 #endif
05145         rl->pvMinor = ssl->version.minor;
05146 
05147 #ifdef WOLFSSL_ALTERNATIVE_DOWNGRADE
05148     if (ssl->options.side == WOLFSSL_CLIENT_END
05149     &&  ssl->options.connectState == CONNECT_BEGIN
05150     && !ssl->options.resuming) {
05151         rl->pvMinor = ssl->options.downgrade ? ssl->options.minDowngrade
05152                                              : ssl->version.minor;
05153     }
05154 #endif
05155 
05156     if (!ssl->options.dtls) {
05157         c16toa((word16)length, rl->length);
05158     }
05159     else {
05160 #ifdef WOLFSSL_DTLS
05161         DtlsRecordLayerHeader* dtls;
05162 
05163         /* dtls record layer header extensions */
05164         dtls = (DtlsRecordLayerHeader*)output;
05165         WriteSEQ(ssl, 0, dtls->sequence_number);
05166         c16toa((word16)length, dtls->length);
05167 #endif
05168     }
05169 }
05170 
05171 
05172 /* add handshake header for message */
05173 static void AddHandShakeHeader(byte* output, word32 length,
05174                                word32 fragOffset, word32 fragLength,
05175                                byte type, WOLFSSL* ssl)
05176 {
05177     HandShakeHeader* hs;
05178     (void)fragOffset;
05179     (void)fragLength;
05180     (void)ssl;
05181 
05182     /* handshake header */
05183     hs = (HandShakeHeader*)output;
05184     hs->type = type;
05185     c32to24(length, hs->length);         /* type and length same for each */
05186 #ifdef WOLFSSL_DTLS
05187     if (ssl->options.dtls) {
05188         DtlsHandShakeHeader* dtls;
05189 
05190         /* dtls handshake header extensions */
05191         dtls = (DtlsHandShakeHeader*)output;
05192         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
05193         c32to24(fragOffset, dtls->fragment_offset);
05194         c32to24(fragLength, dtls->fragment_length);
05195     }
05196 #endif
05197 }
05198 
05199 
05200 /* add both headers for handshake message */
05201 static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
05202 {
05203     word32 lengthAdj = HANDSHAKE_HEADER_SZ;
05204     word32 outputAdj = RECORD_HEADER_SZ;
05205 
05206 #ifdef WOLFSSL_DTLS
05207     if (ssl->options.dtls) {
05208         lengthAdj += DTLS_HANDSHAKE_EXTRA;
05209         outputAdj += DTLS_RECORD_EXTRA;
05210     }
05211 #endif
05212 
05213     AddRecordHeader(output, length + lengthAdj, handshake, ssl);
05214     AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
05215 }
05216 
05217 
05218 #ifndef NO_CERTS
05219 static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
05220                            word32 length, byte type, WOLFSSL* ssl)
05221 {
05222     word32 lengthAdj = HANDSHAKE_HEADER_SZ;
05223     word32 outputAdj = RECORD_HEADER_SZ;
05224     (void)fragSz;
05225 
05226 #ifdef WOLFSSL_DTLS
05227     if (ssl->options.dtls) {
05228         lengthAdj += DTLS_HANDSHAKE_EXTRA;
05229         outputAdj += DTLS_RECORD_EXTRA;
05230     }
05231 #endif
05232 
05233     AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl);
05234     AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
05235 }
05236 #endif /* NO_CERTS */
05237 
05238 
05239 /* return bytes received, -1 on error */
05240 static int Receive(WOLFSSL* ssl, byte* buf, word32 sz)
05241 {
05242     int recvd;
05243 
05244     if (ssl->ctx->CBIORecv == NULL) {
05245         WOLFSSL_MSG("Your IO Recv callback is null, please set");
05246         return -1;
05247     }
05248 
05249 retry:
05250     recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
05251     if (recvd < 0)
05252         switch (recvd) {
05253             case WOLFSSL_CBIO_ERR_GENERAL:        /* general/unknown error */
05254                 return -1;
05255 
05256             case WOLFSSL_CBIO_ERR_WANT_READ:      /* want read, would block */
05257                 return WANT_READ;
05258 
05259             case WOLFSSL_CBIO_ERR_CONN_RST:       /* connection reset */
05260                 #ifdef USE_WINDOWS_API
05261                 if (ssl->options.dtls) {
05262                     goto retry;
05263                 }
05264                 #endif
05265                 ssl->options.connReset = 1;
05266                 return -1;
05267 
05268             case WOLFSSL_CBIO_ERR_ISR:            /* interrupt */
05269                 /* see if we got our timeout */
05270                 #ifdef WOLFSSL_CALLBACKS
05271                     if (ssl->toInfoOn) {
05272                         struct itimerval timeout;
05273                         getitimer(ITIMER_REAL, &timeout);
05274                         if (timeout.it_value.tv_sec == 0 &&
05275                                                 timeout.it_value.tv_usec == 0) {
05276                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
05277                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
05278                             WOLFSSL_MSG("Got our timeout");
05279                             return WANT_READ;
05280                         }
05281                     }
05282                 #endif
05283                 goto retry;
05284 
05285             case WOLFSSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
05286                 ssl->options.isClosed = 1;
05287                 return -1;
05288 
05289             case WOLFSSL_CBIO_ERR_TIMEOUT:
05290                 #ifdef WOLFSSL_DTLS
05291                 if (IsDtlsNotSctpMode(ssl) &&
05292                     !ssl->options.handShakeDone &&
05293                     DtlsMsgPoolTimeout(ssl) == 0 &&
05294                     DtlsMsgPoolSend(ssl, 0) == 0) {
05295 
05296                     goto retry;
05297                 }
05298                 #endif
05299                 return -1;
05300 
05301             default:
05302                 return recvd;
05303         }
05304 
05305     return recvd;
05306 }
05307 
05308 
05309 /* Switch dynamic output buffer back to static, buffer is assumed clear */
05310 void ShrinkOutputBuffer(WOLFSSL* ssl)
05311 {
05312     WOLFSSL_MSG("Shrinking output buffer\n");
05313     XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
05314           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
05315     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
05316     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
05317     ssl->buffers.outputBuffer.dynamicFlag = 0;
05318     ssl->buffers.outputBuffer.offset      = 0;
05319 }
05320 
05321 
05322 /* Switch dynamic input buffer back to static, keep any remaining input */
05323 /* forced free means cleaning up */
05324 void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
05325 {
05326     int usedLength = ssl->buffers.inputBuffer.length -
05327                      ssl->buffers.inputBuffer.idx;
05328     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
05329         return;
05330 
05331     WOLFSSL_MSG("Shrinking input buffer\n");
05332 
05333     if (!forcedFree && usedLength > 0)
05334         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
05335                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
05336                usedLength);
05337 
05338     XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
05339           ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
05340     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
05341     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
05342     ssl->buffers.inputBuffer.dynamicFlag = 0;
05343     ssl->buffers.inputBuffer.offset      = 0;
05344     ssl->buffers.inputBuffer.idx = 0;
05345     ssl->buffers.inputBuffer.length = usedLength;
05346 }
05347 
05348 int SendBuffered(WOLFSSL* ssl)
05349 {
05350     if (ssl->ctx->CBIOSend == NULL) {
05351         WOLFSSL_MSG("Your IO Send callback is null, please set");
05352         return SOCKET_ERROR_E;
05353     }
05354 
05355 #ifdef WOLFSSL_DEBUG_TLS
05356     if (ssl->buffers.outputBuffer.idx == 0) {
05357         WOLFSSL_MSG("Data to send");
05358         WOLFSSL_BUFFER(ssl->buffers.outputBuffer.buffer,
05359                        ssl->buffers.outputBuffer.length);
05360     }
05361 #endif
05362 
05363     while (ssl->buffers.outputBuffer.length > 0) {
05364         int sent = ssl->ctx->CBIOSend(ssl,
05365                                       (char*)ssl->buffers.outputBuffer.buffer +
05366                                       ssl->buffers.outputBuffer.idx,
05367                                       (int)ssl->buffers.outputBuffer.length,
05368                                       ssl->IOCB_WriteCtx);
05369         if (sent < 0) {
05370             switch (sent) {
05371 
05372                 case WOLFSSL_CBIO_ERR_WANT_WRITE:        /* would block */
05373                     return WANT_WRITE;
05374 
05375                 case WOLFSSL_CBIO_ERR_CONN_RST:          /* connection reset */
05376                     ssl->options.connReset = 1;
05377                     break;
05378 
05379                 case WOLFSSL_CBIO_ERR_ISR:               /* interrupt */
05380                     /* see if we got our timeout */
05381                     #ifdef WOLFSSL_CALLBACKS
05382                         if (ssl->toInfoOn) {
05383                             struct itimerval timeout;
05384                             getitimer(ITIMER_REAL, &timeout);
05385                             if (timeout.it_value.tv_sec == 0 &&
05386                                                 timeout.it_value.tv_usec == 0) {
05387                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
05388                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
05389                                 WOLFSSL_MSG("Got our timeout");
05390                                 return WANT_WRITE;
05391                             }
05392                         }
05393                     #endif
05394                     continue;
05395 
05396                 case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
05397                     ssl->options.connReset = 1;  /* treat same as reset */
05398                     break;
05399 
05400                 default:
05401                     return SOCKET_ERROR_E;
05402             }
05403 
05404             return SOCKET_ERROR_E;
05405         }
05406 
05407         if (sent > (int)ssl->buffers.outputBuffer.length) {
05408             WOLFSSL_MSG("SendBuffered() out of bounds read");
05409             return SEND_OOB_READ_E;
05410         }
05411 
05412         ssl->buffers.outputBuffer.idx += sent;
05413         ssl->buffers.outputBuffer.length -= sent;
05414     }
05415 
05416     ssl->buffers.outputBuffer.idx = 0;
05417 
05418     if (ssl->buffers.outputBuffer.dynamicFlag)
05419         ShrinkOutputBuffer(ssl);
05420 
05421     return 0;
05422 }
05423 
05424 
05425 /* Grow the output buffer */
05426 static INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
05427 {
05428     byte* tmp;
05429 #if WOLFSSL_GENERAL_ALIGNMENT > 0
05430     byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
05431                                       RECORD_HEADER_SZ;
05432     byte align = WOLFSSL_GENERAL_ALIGNMENT;
05433 #else
05434     const byte align = WOLFSSL_GENERAL_ALIGNMENT;
05435 #endif
05436 
05437 #if WOLFSSL_GENERAL_ALIGNMENT > 0
05438     /* the encrypted data will be offset from the front of the buffer by
05439        the header, if the user wants encrypted alignment they need
05440        to define their alignment requirement */
05441 
05442     if (align) {
05443        while (align < hdrSz)
05444            align *= 2;
05445     }
05446 #endif
05447 
05448     tmp = (byte*)XMALLOC(size + ssl->buffers.outputBuffer.length + align,
05449                              ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
05450     WOLFSSL_MSG("growing output buffer\n");
05451 
05452     if (tmp == NULL)
05453         return MEMORY_E;
05454 
05455 #if WOLFSSL_GENERAL_ALIGNMENT > 0
05456     if (align)
05457         tmp += align - hdrSz;
05458 #endif
05459 
05460     if (ssl->buffers.outputBuffer.length)
05461         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
05462                ssl->buffers.outputBuffer.length);
05463 
05464     if (ssl->buffers.outputBuffer.dynamicFlag)
05465         XFREE(ssl->buffers.outputBuffer.buffer -
05466               ssl->buffers.outputBuffer.offset, ssl->heap,
05467               DYNAMIC_TYPE_OUT_BUFFER);
05468     ssl->buffers.outputBuffer.dynamicFlag = 1;
05469 
05470 #if WOLFSSL_GENERAL_ALIGNMENT > 0
05471     if (align)
05472         ssl->buffers.outputBuffer.offset = align - hdrSz;
05473     else
05474 #endif
05475         ssl->buffers.outputBuffer.offset = 0;
05476 
05477     ssl->buffers.outputBuffer.buffer = tmp;
05478     ssl->buffers.outputBuffer.bufferSize = size +
05479                                            ssl->buffers.outputBuffer.length;
05480     return 0;
05481 }
05482 
05483 
05484 /* Grow the input buffer, should only be to read cert or big app data */
05485 int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
05486 {
05487     byte* tmp;
05488 #if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
05489     byte  align = ssl->options.dtls ? WOLFSSL_GENERAL_ALIGNMENT : 0;
05490     byte  hdrSz = DTLS_RECORD_HEADER_SZ;
05491 #else
05492     const byte align = WOLFSSL_GENERAL_ALIGNMENT;
05493 #endif
05494 
05495 #if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
05496     /* the encrypted data will be offset from the front of the buffer by
05497        the dtls record header, if the user wants encrypted alignment they need
05498        to define their alignment requirement. in tls we read record header
05499        to get size of record and put actual data back at front, so don't need */
05500 
05501     if (align) {
05502        while (align < hdrSz)
05503            align *= 2;
05504     }
05505 #endif
05506 
05507     if (usedLength < 0 || size < 0) {
05508         WOLFSSL_MSG("GrowInputBuffer() called with negative number");
05509         return BAD_FUNC_ARG;
05510     }
05511 
05512     tmp = (byte*)XMALLOC(size + usedLength + align,
05513                              ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
05514     WOLFSSL_MSG("growing input buffer\n");
05515 
05516     if (tmp == NULL)
05517         return MEMORY_E;
05518 
05519 #if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
05520     if (align)
05521         tmp += align - hdrSz;
05522 #endif
05523 
05524     if (usedLength)
05525         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
05526                     ssl->buffers.inputBuffer.idx, usedLength);
05527 
05528     if (ssl->buffers.inputBuffer.dynamicFlag)
05529         XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
05530               ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
05531 
05532     ssl->buffers.inputBuffer.dynamicFlag = 1;
05533 #if defined(WOLFSSL_DTLS) || WOLFSSL_GENERAL_ALIGNMENT > 0
05534     if (align)
05535         ssl->buffers.inputBuffer.offset = align - hdrSz;
05536     else
05537 #endif
05538         ssl->buffers.inputBuffer.offset = 0;
05539 
05540     ssl->buffers.inputBuffer.buffer = tmp;
05541     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
05542     ssl->buffers.inputBuffer.idx    = 0;
05543     ssl->buffers.inputBuffer.length = usedLength;
05544 
05545     return 0;
05546 }
05547 
05548 
05549 /* check available size into output buffer, make room if needed */
05550 int CheckAvailableSize(WOLFSSL *ssl, int size)
05551 {
05552     if (size < 0) {
05553         WOLFSSL_MSG("CheckAvailableSize() called with negative number");
05554         return BAD_FUNC_ARG;
05555     }
05556 
05557     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
05558                                              < (word32)size) {
05559         if (GrowOutputBuffer(ssl, size) < 0)
05560             return MEMORY_E;
05561     }
05562 
05563     return 0;
05564 }
05565 
05566 
05567 /* do all verify and sanity checks on record header */
05568 static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
05569                            RecordLayerHeader* rh, word16 *size)
05570 {
05571     if (!ssl->options.dtls) {
05572 #ifdef HAVE_FUZZER
05573         if (ssl->fuzzerCb)
05574             ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
05575                     ssl->fuzzerCtx);
05576 #endif
05577         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
05578         *inOutIdx += RECORD_HEADER_SZ;
05579         ato16(rh->length, size);
05580     }
05581     else {
05582 #ifdef WOLFSSL_DTLS
05583 #ifdef HAVE_FUZZER
05584         if (ssl->fuzzerCb)
05585             ssl->fuzzerCb(ssl, input + *inOutIdx, DTLS_RECORD_HEADER_SZ,
05586                            FUZZ_HEAD, ssl->fuzzerCtx);
05587 #endif
05588         /* type and version in same sport */
05589         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
05590         *inOutIdx += ENUM_LEN + VERSION_SZ;
05591         ato16(input + *inOutIdx, &ssl->keys.curEpoch);
05592         *inOutIdx += OPAQUE16_LEN;
05593         ato16(input + *inOutIdx, &ssl->keys.curSeq_hi);
05594         *inOutIdx += OPAQUE16_LEN;
05595         ato32(input + *inOutIdx, &ssl->keys.curSeq_lo);
05596         *inOutIdx += OPAQUE32_LEN;  /* advance past rest of seq */
05597         ato16(input + *inOutIdx, size);
05598         *inOutIdx += LENGTH_SZ;
05599 #endif
05600     }
05601 
05602 #ifdef WOLFSSL_DTLS
05603     if (IsDtlsNotSctpMode(ssl) &&
05604         (!DtlsCheckWindow(ssl) ||
05605          (ssl->options.handShakeDone && ssl->keys.curEpoch == 0))) {
05606             return SEQUENCE_ERROR;
05607     }
05608 #endif
05609 
05610 #ifdef OPENSSL_EXTRA
05611     /* case where specific protocols are turned off */
05612     if (!ssl->options.dtls && ssl->options.mask > 0) {
05613         if (rh->pvMinor == SSLv3_MINOR &&
05614             (ssl->options.mask & SSL_OP_NO_SSLv3) == SSL_OP_NO_SSLv3) {
05615             WOLFSSL_MSG("Option set to not allow SSLv3");
05616             return VERSION_ERROR;
05617         }
05618         if (rh->pvMinor == TLSv1_MINOR &&
05619             (ssl->options.mask & SSL_OP_NO_TLSv1) == SSL_OP_NO_TLSv1) {
05620             WOLFSSL_MSG("Option set to not allow TLSv1");
05621             return VERSION_ERROR;
05622         }
05623         if (rh->pvMinor == TLSv1_1_MINOR &&
05624             (ssl->options.mask & SSL_OP_NO_TLSv1_1) == SSL_OP_NO_TLSv1_1) {
05625             WOLFSSL_MSG("Option set to not allow TLSv1.1");
05626             return VERSION_ERROR;
05627         }
05628         if (rh->pvMinor == TLSv1_2_MINOR &&
05629             (ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) {
05630             WOLFSSL_MSG("Option set to not allow TLSv1.2");
05631             return VERSION_ERROR;
05632         }
05633     }
05634 #endif /* OPENSSL_EXTRA */
05635 
05636     /* catch version mismatch */
05637 #ifndef WOLFSSL_TLS13
05638     if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor)
05639 #else
05640     if (rh->pvMajor != ssl->version.major ||
05641         (rh->pvMinor != ssl->version.minor &&
05642          (!IsAtLeastTLSv1_3(ssl->version) || rh->pvMinor != TLSv1_MINOR)))
05643 #endif
05644     {
05645         if (ssl->options.side == WOLFSSL_SERVER_END &&
05646             ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)
05647 
05648             WOLFSSL_MSG("Client attempting to connect with different version");
05649         else if (ssl->options.side == WOLFSSL_CLIENT_END &&
05650                                  ssl->options.downgrade &&
05651                                  ssl->options.connectState < FIRST_REPLY_DONE)
05652             WOLFSSL_MSG("Server attempting to accept with different version");
05653         else if (ssl->options.dtls && rh->type == handshake)
05654             /* Check the DTLS handshake message RH version later. */
05655             WOLFSSL_MSG("DTLS handshake, skip RH version number check");
05656         else {
05657             WOLFSSL_MSG("SSL version error");
05658             return VERSION_ERROR;              /* only use requested version */
05659         }
05660     }
05661 
05662     /* record layer length check */
05663 #ifdef HAVE_MAX_FRAGMENT
05664     if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
05665         SendAlert(ssl, alert_fatal, record_overflow);
05666         return LENGTH_ERROR;
05667     }
05668 #else
05669     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
05670         return LENGTH_ERROR;
05671 #endif
05672 
05673     /* verify record type here as well */
05674     switch (rh->type) {
05675         case handshake:
05676         case change_cipher_spec:
05677         case application_data:
05678         case alert:
05679             break;
05680         case no_type:
05681         default:
05682             WOLFSSL_MSG("Unknown Record Type");
05683             return UNKNOWN_RECORD_TYPE;
05684     }
05685 
05686     /* haven't decrypted this record yet */
05687     ssl->keys.decryptedCur = 0;
05688 
05689     return 0;
05690 }
05691 
05692 
05693 static int GetHandShakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
05694                               byte *type, word32 *size, word32 totalSz)
05695 {
05696     const byte *ptr = input + *inOutIdx;
05697     (void)ssl;
05698 
05699     *inOutIdx += HANDSHAKE_HEADER_SZ;
05700     if (*inOutIdx > totalSz)
05701         return BUFFER_E;
05702 
05703     *type = ptr[0];
05704     c24to32(&ptr[1], size);
05705 
05706     return 0;
05707 }
05708 
05709 
05710 #ifdef WOLFSSL_DTLS
05711 static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
05712                                   word32* inOutIdx, byte *type, word32 *size,
05713                                   word32 *fragOffset, word32 *fragSz,
05714                                   word32 totalSz)
05715 {
05716     word32 idx = *inOutIdx;
05717 
05718     *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
05719     if (*inOutIdx > totalSz)
05720         return BUFFER_E;
05721 
05722     *type = input[idx++];
05723     c24to32(input + idx, size);
05724     idx += OPAQUE24_LEN;
05725 
05726     ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
05727     idx += DTLS_HANDSHAKE_SEQ_SZ;
05728 
05729     c24to32(input + idx, fragOffset);
05730     idx += DTLS_HANDSHAKE_FRAG_SZ;
05731     c24to32(input + idx, fragSz);
05732 
05733     if (ssl->curRL.pvMajor != ssl->version.major ||
05734         ssl->curRL.pvMinor != ssl->version.minor) {
05735 
05736         if (*type != client_hello && *type != hello_verify_request)
05737             return VERSION_ERROR;
05738         else {
05739             WOLFSSL_MSG("DTLS Handshake ignoring hello or verify version");
05740         }
05741     }
05742     return 0;
05743 }
05744 #endif
05745 
05746 
05747 #if !defined(NO_OLD_TLS) || \
05748     (defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLS_SHA1))
05749 /* fill with MD5 pad size since biggest required */
05750 static const byte PAD1[PAD_MD5] =
05751                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
05752                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
05753                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
05754                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
05755                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
05756                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
05757                               };
05758 static const byte PAD2[PAD_MD5] =
05759                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
05760                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
05761                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
05762                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
05763                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
05764                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
05765                               };
05766 #endif /* !NO_OLD_TLS || (NO_OLD_TLS && WOLFSSL_ALLOW_TLS_SHA1) */
05767 
05768 #ifndef NO_OLD_TLS
05769 
05770 /* calculate MD5 hash for finished */
05771 #ifdef WOLFSSL_TI_HASH
05772 #include <wolfssl/wolfcrypt/hash.h>
05773 #endif
05774 
05775 static int BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
05776 {
05777     int ret;
05778     byte md5_result[MD5_DIGEST_SIZE];
05779 #ifdef WOLFSSL_SMALL_STACK
05780     Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05781     if (md5 == NULL)
05782         return MEMORY_E;
05783 #else
05784     Md5  md5[1];
05785 #endif
05786 
05787     /* make md5 inner */
05788     ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5);
05789     if (ret == 0)
05790         ret = wc_Md5Update(md5, sender, SIZEOF_SENDER);
05791     if (ret == 0)
05792         ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
05793     if (ret == 0)
05794         ret = wc_Md5Update(md5, PAD1, PAD_MD5);
05795     if (ret == 0)
05796         ret = wc_Md5Final(md5, md5_result);
05797 
05798     /* make md5 outer */
05799     if (ret == 0) {
05800         ret = wc_InitMd5_ex(md5, ssl->heap, ssl->devId);
05801         if (ret == 0) {
05802             ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
05803             if (ret == 0)
05804                 ret = wc_Md5Update(md5, PAD2, PAD_MD5);
05805             if (ret == 0)
05806                 ret = wc_Md5Update(md5, md5_result, MD5_DIGEST_SIZE);
05807             if (ret == 0)
05808                 ret = wc_Md5Final(md5, hashes->md5);
05809             wc_Md5Free(md5);
05810         }
05811     }
05812 
05813 #ifdef WOLFSSL_SMALL_STACK
05814     XFREE(md5, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05815 #endif
05816 
05817     return ret;
05818 }
05819 
05820 
05821 /* calculate SHA hash for finished */
05822 static int BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
05823 {
05824     int ret;
05825     byte sha_result[SHA_DIGEST_SIZE];
05826 #ifdef WOLFSSL_SMALL_STACK
05827     Sha* sha = (Sha*)XMALLOC(sizeof(Sha), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05828     if (sha == NULL)
05829         return MEMORY_E;
05830 #else
05831     Sha  sha[1];
05832 #endif
05833     /* make sha inner */
05834     ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
05835     if (ret == 0)
05836         ret = wc_ShaUpdate(sha, sender, SIZEOF_SENDER);
05837     if (ret == 0)
05838         ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
05839     if (ret == 0)
05840         ret = wc_ShaUpdate(sha, PAD1, PAD_SHA);
05841     if (ret == 0)
05842         ret = wc_ShaFinal(sha, sha_result);
05843 
05844     /* make sha outer */
05845     if (ret == 0) {
05846         ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId);
05847         if (ret == 0) {
05848             ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
05849             if (ret == 0)
05850                 ret = wc_ShaUpdate(sha, PAD2, PAD_SHA);
05851             if (ret == 0)
05852                 ret = wc_ShaUpdate(sha, sha_result, SHA_DIGEST_SIZE);
05853             if (ret == 0)
05854                 ret = wc_ShaFinal(sha, hashes->sha);
05855             wc_ShaFree(sha);
05856         }
05857     }
05858 
05859 #ifdef WOLFSSL_SMALL_STACK
05860     XFREE(sha, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05861 #endif
05862 
05863     return ret;
05864 }
05865 #endif
05866 
05867 /* Finished doesn't support SHA512, not SHA512 cipher suites yet */
05868 static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
05869 {
05870     int ret = 0;
05871 #ifdef WOLFSSL_SHA384
05872 #ifdef WOLFSSL_SMALL_STACK
05873     Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), ssl->heap,
05874                                                 DYNAMIC_TYPE_TMP_BUFFER);
05875 #else
05876     Sha384 sha384[1];
05877 #endif /* WOLFSSL_SMALL_STACK */
05878 #endif /* WOLFSSL_SHA384 */
05879 
05880 #ifdef WOLFSSL_SMALL_STACK
05881     if (ssl == NULL
05882     #ifdef WOLFSSL_SHA384
05883         || sha384 == NULL
05884     #endif
05885         ) {
05886     #ifdef WOLFSSL_SHA384
05887         XFREE(sha384, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05888     #endif
05889         return MEMORY_E;
05890     }
05891 #endif
05892 
05893     /* store current states, building requires get_digest which resets state */
05894 #ifdef WOLFSSL_SHA384
05895     sha384[0] = ssl->hsHashes->hashSha384;
05896 #endif
05897 
05898 #ifndef NO_TLS
05899     if (ssl->options.tls) {
05900         ret = BuildTlsFinished(ssl, hashes, sender);
05901     }
05902 #endif
05903 #ifndef NO_OLD_TLS
05904     if (!ssl->options.tls) {
05905         ret = BuildMD5(ssl, hashes, sender);
05906         if (ret == 0) {
05907             ret = BuildSHA(ssl, hashes, sender);
05908         }
05909     }
05910 #endif
05911 
05912     /* restore */
05913     if (IsAtLeastTLSv1_2(ssl)) {
05914     #ifdef WOLFSSL_SHA384
05915         ssl->hsHashes->hashSha384 = sha384[0];
05916     #endif
05917     }
05918 
05919 #ifdef WOLFSSL_SHA384
05920 #ifdef WOLFSSL_SMALL_STACK
05921     XFREE(sha384, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
05922 #endif
05923 #endif
05924 
05925     return ret;
05926 }
05927 
05928 
05929     /* cipher requirements */
05930     enum {
05931         REQUIRES_RSA,
05932         REQUIRES_DHE,
05933         REQUIRES_ECC,
05934         REQUIRES_ECC_STATIC,
05935         REQUIRES_PSK,
05936         REQUIRES_NTRU,
05937         REQUIRES_RSA_SIG
05938     };
05939 
05940 
05941 
05942     /* Does this cipher suite (first, second) have the requirement
05943        an ephemeral key exchange will still require the key for signing
05944        the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
05945     static int CipherRequires(byte first, byte second, int requirement)
05946     {
05947 
05948         if (first == CHACHA_BYTE) {
05949 
05950         switch (second) {
05951 
05952         case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
05953             if (requirement == REQUIRES_RSA)
05954                 return 1;
05955             break;
05956 
05957         case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
05958             if (requirement == REQUIRES_ECC)
05959                 return 1;
05960             break;
05961 
05962         case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
05963             if (requirement == REQUIRES_RSA)
05964                 return 1;
05965             if (requirement == REQUIRES_DHE)
05966                 return 1;
05967             break;
05968 
05969         case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
05970             if (requirement == REQUIRES_RSA)
05971                 return 1;
05972             break;
05973 
05974         case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
05975             if (requirement == REQUIRES_ECC)
05976                 return 1;
05977             break;
05978 
05979         case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
05980             if (requirement == REQUIRES_RSA)
05981                 return 1;
05982             if (requirement == REQUIRES_DHE)
05983                 return 1;
05984             break;
05985 
05986 
05987         case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
05988             if (requirement == REQUIRES_PSK)
05989                 return 1;
05990             break;
05991 
05992         case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 :
05993             if (requirement == REQUIRES_PSK)
05994                 return 1;
05995             break;
05996 
05997         case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
05998             if (requirement == REQUIRES_PSK)
05999                 return 1;
06000             if (requirement == REQUIRES_DHE)
06001                 return 1;
06002             break;
06003             }
06004         }
06005 
06006         /* ECC extensions */
06007         if (first == ECC_BYTE) {
06008 
06009         switch (second) {
06010 
06011 #ifndef NO_RSA
06012         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
06013             if (requirement == REQUIRES_RSA)
06014                 return 1;
06015             break;
06016 
06017         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
06018             if (requirement == REQUIRES_ECC_STATIC)
06019                 return 1;
06020             if (requirement == REQUIRES_RSA_SIG)
06021                 return 1;
06022             break;
06023 
06024 #ifndef NO_DES3
06025         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
06026             if (requirement == REQUIRES_RSA)
06027                 return 1;
06028             break;
06029 
06030         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
06031             if (requirement == REQUIRES_ECC_STATIC)
06032                 return 1;
06033             if (requirement == REQUIRES_RSA_SIG)
06034                 return 1;
06035             break;
06036 #endif
06037 
06038 #ifndef NO_RC4
06039         case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
06040             if (requirement == REQUIRES_RSA)
06041                 return 1;
06042             break;
06043 
06044         case TLS_ECDH_RSA_WITH_RC4_128_SHA :
06045             if (requirement == REQUIRES_ECC_STATIC)
06046                 return 1;
06047             if (requirement == REQUIRES_RSA_SIG)
06048                 return 1;
06049             break;
06050 #endif
06051 #endif /* NO_RSA */
06052 
06053 #ifndef NO_DES3
06054         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
06055             if (requirement == REQUIRES_ECC)
06056                 return 1;
06057             break;
06058 
06059         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
06060             if (requirement == REQUIRES_ECC_STATIC)
06061                 return 1;
06062             break;
06063 #endif
06064 #ifndef NO_RC4
06065         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
06066             if (requirement == REQUIRES_ECC)
06067                 return 1;
06068             break;
06069 
06070         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
06071             if (requirement == REQUIRES_ECC_STATIC)
06072                 return 1;
06073             break;
06074 #endif
06075 #ifndef NO_RSA
06076         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
06077             if (requirement == REQUIRES_RSA)
06078                 return 1;
06079             break;
06080 
06081         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
06082             if (requirement == REQUIRES_ECC_STATIC)
06083                 return 1;
06084             if (requirement == REQUIRES_RSA_SIG)
06085                 return 1;
06086             break;
06087 #endif
06088 
06089         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
06090             if (requirement == REQUIRES_ECC)
06091                 return 1;
06092             break;
06093 
06094         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
06095             if (requirement == REQUIRES_ECC_STATIC)
06096                 return 1;
06097             break;
06098 
06099         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
06100             if (requirement == REQUIRES_ECC)
06101                 return 1;
06102             break;
06103 
06104         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
06105             if (requirement == REQUIRES_ECC_STATIC)
06106                 return 1;
06107             break;
06108 
06109         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
06110             if (requirement == REQUIRES_ECC)
06111                 return 1;
06112             break;
06113 
06114         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
06115             if (requirement == REQUIRES_ECC)
06116                 return 1;
06117             break;
06118 
06119         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
06120             if (requirement == REQUIRES_ECC_STATIC)
06121                 return 1;
06122             break;
06123 
06124         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
06125             if (requirement == REQUIRES_ECC_STATIC)
06126                 return 1;
06127             break;
06128 
06129 #ifndef NO_RSA
06130         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
06131             if (requirement == REQUIRES_RSA)
06132                 return 1;
06133             break;
06134 
06135         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
06136             if (requirement == REQUIRES_RSA)
06137                 return 1;
06138             break;
06139 
06140         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
06141             if (requirement == REQUIRES_ECC_STATIC)
06142                 return 1;
06143             if (requirement == REQUIRES_RSA_SIG)
06144                 return 1;
06145             break;
06146 
06147         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
06148             if (requirement == REQUIRES_ECC_STATIC)
06149                 return 1;
06150             if (requirement == REQUIRES_RSA_SIG)
06151                 return 1;
06152             break;
06153 
06154         case TLS_RSA_WITH_AES_128_CCM_8 :
06155         case TLS_RSA_WITH_AES_256_CCM_8 :
06156             if (requirement == REQUIRES_RSA)
06157                 return 1;
06158             if (requirement == REQUIRES_RSA_SIG)
06159                 return 1;
06160             break;
06161 
06162         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
06163         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
06164             if (requirement == REQUIRES_RSA)
06165                 return 1;
06166             break;
06167 
06168         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
06169         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
06170             if (requirement == REQUIRES_RSA_SIG)
06171                 return 1;
06172             if (requirement == REQUIRES_ECC_STATIC)
06173                 return 1;
06174             break;
06175 #endif
06176 
06177         case TLS_ECDHE_ECDSA_WITH_AES_128_CCM :
06178         case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
06179         case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
06180             if (requirement == REQUIRES_ECC)
06181                 return 1;
06182             break;
06183 
06184         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
06185         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
06186             if (requirement == REQUIRES_ECC)
06187                 return 1;
06188             break;
06189 
06190         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
06191         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
06192             if (requirement == REQUIRES_ECC)
06193                 return 1;
06194             if (requirement == REQUIRES_ECC_STATIC)
06195                 return 1;
06196             break;
06197 
06198         case TLS_PSK_WITH_AES_128_CCM:
06199         case TLS_PSK_WITH_AES_256_CCM:
06200         case TLS_PSK_WITH_AES_128_CCM_8:
06201         case TLS_PSK_WITH_AES_256_CCM_8:
06202             if (requirement == REQUIRES_PSK)
06203                 return 1;
06204             break;
06205 
06206         case TLS_DHE_PSK_WITH_AES_128_CCM:
06207         case TLS_DHE_PSK_WITH_AES_256_CCM:
06208             if (requirement == REQUIRES_PSK)
06209                 return 1;
06210             if (requirement == REQUIRES_DHE)
06211                 return 1;
06212             break;
06213 
06214         case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
06215             if (requirement == REQUIRES_ECC)
06216                 return 1;
06217             break;
06218 
06219         case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
06220             if (requirement == REQUIRES_PSK)
06221                 return 1;
06222             break;
06223 
06224         case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
06225             if (requirement == REQUIRES_PSK)
06226                 return 1;
06227             break;
06228 
06229         default:
06230             WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
06231             return 0;
06232         }   /* switch */
06233         }   /* if     */
06234 
06235         /* Distinct TLS v1.3 cipher suites with cipher and digest only. */
06236         if (first == TLS13_BYTE) {
06237 
06238             switch (second) {
06239 #ifdef WOLFSSL_TLS13
06240             case TLS_AES_128_GCM_SHA256:
06241             case TLS_AES_256_GCM_SHA384:
06242             case TLS_CHACHA20_POLY1305_SHA256:
06243             case TLS_AES_128_CCM_SHA256:
06244             case TLS_AES_128_CCM_8_SHA256:
06245                 break;
06246 #endif
06247 
06248             default:
06249                 WOLFSSL_MSG("Unsupported cipher suite, CipherRequires "
06250                             "TLS v1.3");
06251                 return 0;
06252             }
06253         }
06254 
06255         if (first != ECC_BYTE && first != CHACHA_BYTE &&
06256             first != TLS13_BYTE) {   /* normal suites */
06257         switch (second) {
06258 
06259 #ifndef NO_RSA
06260         case SSL_RSA_WITH_RC4_128_SHA :
06261             if (requirement == REQUIRES_RSA)
06262                 return 1;
06263             break;
06264 
06265         case SSL_RSA_WITH_RC4_128_MD5 :
06266             if (requirement == REQUIRES_RSA)
06267                 return 1;
06268             break;
06269 
06270         case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
06271             if (requirement == REQUIRES_RSA)
06272                 return 1;
06273             break;
06274 
06275         case TLS_NTRU_RSA_WITH_RC4_128_SHA :
06276             if (requirement == REQUIRES_NTRU)
06277                 return 1;
06278             break;
06279 
06280         case TLS_RSA_WITH_AES_128_CBC_SHA :
06281             if (requirement == REQUIRES_RSA)
06282                 return 1;
06283             break;
06284 
06285         case TLS_RSA_WITH_AES_128_CBC_SHA256 :
06286             if (requirement == REQUIRES_RSA)
06287                 return 1;
06288             break;
06289 
06290         case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
06291             if (requirement == REQUIRES_NTRU)
06292                 return 1;
06293             break;
06294 
06295         case TLS_RSA_WITH_AES_256_CBC_SHA :
06296             if (requirement == REQUIRES_RSA)
06297                 return 1;
06298             break;
06299 
06300         case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
06301             if (requirement == REQUIRES_NTRU)
06302                 return 1;
06303             break;
06304 
06305         case TLS_RSA_WITH_AES_256_CBC_SHA256 :
06306             if (requirement == REQUIRES_RSA)
06307                 return 1;
06308             break;
06309 
06310         case TLS_RSA_WITH_NULL_SHA :
06311         case TLS_RSA_WITH_NULL_SHA256 :
06312             if (requirement == REQUIRES_RSA)
06313                 return 1;
06314             break;
06315 
06316         case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
06317             if (requirement == REQUIRES_NTRU)
06318                 return 1;
06319             break;
06320 
06321         case SSL_RSA_WITH_IDEA_CBC_SHA :
06322             if (requirement == REQUIRES_RSA)
06323                 return 1;
06324             break;
06325 #endif
06326 
06327         case TLS_PSK_WITH_AES_128_GCM_SHA256 :
06328         case TLS_PSK_WITH_AES_256_GCM_SHA384 :
06329         case TLS_PSK_WITH_AES_128_CBC_SHA256 :
06330         case TLS_PSK_WITH_AES_256_CBC_SHA384 :
06331         case TLS_PSK_WITH_AES_128_CBC_SHA :
06332         case TLS_PSK_WITH_AES_256_CBC_SHA :
06333         case TLS_PSK_WITH_NULL_SHA384 :
06334         case TLS_PSK_WITH_NULL_SHA256 :
06335         case TLS_PSK_WITH_NULL_SHA :
06336             if (requirement == REQUIRES_PSK)
06337                 return 1;
06338             break;
06339 
06340         case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
06341         case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
06342         case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
06343         case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
06344         case TLS_DHE_PSK_WITH_NULL_SHA384 :
06345         case TLS_DHE_PSK_WITH_NULL_SHA256 :
06346             if (requirement == REQUIRES_DHE)
06347                 return 1;
06348             if (requirement == REQUIRES_PSK)
06349                 return 1;
06350             break;
06351 
06352 #ifndef NO_RSA
06353         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
06354             if (requirement == REQUIRES_RSA)
06355                 return 1;
06356             if (requirement == REQUIRES_DHE)
06357                 return 1;
06358             break;
06359 
06360         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
06361             if (requirement == REQUIRES_RSA)
06362                 return 1;
06363             if (requirement == REQUIRES_DHE)
06364                 return 1;
06365             break;
06366 
06367         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
06368             if (requirement == REQUIRES_RSA)
06369                 return 1;
06370             if (requirement == REQUIRES_DHE)
06371                 return 1;
06372             break;
06373 
06374         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
06375             if (requirement == REQUIRES_RSA)
06376                 return 1;
06377             if (requirement == REQUIRES_DHE)
06378                 return 1;
06379             break;
06380 
06381         case TLS_RSA_WITH_HC_128_MD5 :
06382             if (requirement == REQUIRES_RSA)
06383                 return 1;
06384             break;
06385 
06386         case TLS_RSA_WITH_HC_128_SHA :
06387             if (requirement == REQUIRES_RSA)
06388                 return 1;
06389             break;
06390 
06391         case TLS_RSA_WITH_HC_128_B2B256:
06392             if (requirement == REQUIRES_RSA)
06393                 return 1;
06394             break;
06395 
06396         case TLS_RSA_WITH_AES_128_CBC_B2B256:
06397         case TLS_RSA_WITH_AES_256_CBC_B2B256:
06398             if (requirement == REQUIRES_RSA)
06399                 return 1;
06400             break;
06401 
06402         case TLS_RSA_WITH_RABBIT_SHA :
06403             if (requirement == REQUIRES_RSA)
06404                 return 1;
06405             break;
06406 
06407         case TLS_RSA_WITH_AES_128_GCM_SHA256 :
06408         case TLS_RSA_WITH_AES_256_GCM_SHA384 :
06409             if (requirement == REQUIRES_RSA)
06410                 return 1;
06411             break;
06412 
06413         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
06414         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
06415             if (requirement == REQUIRES_RSA)
06416                 return 1;
06417             if (requirement == REQUIRES_DHE)
06418                 return 1;
06419             break;
06420 
06421         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
06422         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
06423         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
06424         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
06425             if (requirement == REQUIRES_RSA)
06426                 return 1;
06427             break;
06428 
06429         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
06430         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
06431         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
06432         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
06433             if (requirement == REQUIRES_RSA)
06434                 return 1;
06435             if (requirement == REQUIRES_RSA_SIG)
06436                 return 1;
06437             if (requirement == REQUIRES_DHE)
06438                 return 1;
06439             break;
06440 
06441         case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
06442             if (requirement == REQUIRES_RSA)
06443                 return 1;
06444             if (requirement == REQUIRES_RSA_SIG)
06445                 return 1;
06446             if (requirement == REQUIRES_DHE)
06447                 return 1;
06448             break;
06449 #endif
06450 #ifdef HAVE_ANON
06451         case TLS_DH_anon_WITH_AES_128_CBC_SHA :
06452             if (requirement == REQUIRES_DHE)
06453                 return 1;
06454             break;
06455 #endif
06456 
06457         default:
06458             WOLFSSL_MSG("Unsupported cipher suite, CipherRequires");
06459             return 0;
06460         }  /* switch */
06461         }  /* if ECC / Normal suites else */
06462 
06463         return 0;
06464     }
06465 
06466 
06467 #ifndef NO_CERTS
06468 
06469 
06470 /* Match names with wildcards, each wildcard can represent a single name
06471    component or fragment but not mulitple names, i.e.,
06472    *.z.com matches y.z.com but not x.y.z.com
06473 
06474    return 1 on success */
06475 int MatchDomainName(const char* pattern, int len, const char* str)
06476 {
06477     char p, s;
06478 
06479     if (pattern == NULL || str == NULL || len <= 0)
06480         return 0;
06481 
06482     while (len > 0) {
06483 
06484         p = (char)XTOLOWER((unsigned char)*pattern++);
06485         if (p == 0)
06486             break;
06487 
06488         if (p == '*') {
06489             while (--len > 0 &&
06490                 (p = (char)XTOLOWER((unsigned char)*pattern++)) == '*') {
06491             }
06492 
06493             if (len == 0)
06494                 p = '\0';
06495 
06496             while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
06497                 if (s == p)
06498                     break;
06499                 if (s == '.')
06500                     return 0;
06501                 str++;
06502             }
06503         }
06504         else {
06505             if (p != (char)XTOLOWER((unsigned char) *str))
06506                 return 0;
06507         }
06508 
06509         if (*str != '\0')
06510             str++;
06511 
06512         if (len > 0)
06513             len--;
06514     }
06515 
06516     return *str == '\0';
06517 }
06518 
06519 
06520 /* try to find an altName match to domain, return 1 on success */
06521 int CheckAltNames(DecodedCert* dCert, char* domain)
06522 {
06523     int        match = 0;
06524     DNS_entry* altName = NULL;
06525 
06526     WOLFSSL_MSG("Checking AltNames");
06527 
06528     if (dCert)
06529         altName = dCert->altNames;
06530 
06531     while (altName) {
06532         WOLFSSL_MSG("\tindividual AltName check");
06533 
06534         if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
06535             match = 1;
06536             break;
06537         }
06538 
06539         altName = altName->next;
06540     }
06541 
06542     return match;
06543 }
06544 
06545 
06546 #ifdef OPENSSL_EXTRA
06547 /* Check that alternative names, if they exists, match the domain.
06548  * Fail if there are wild patterns and they didn't match.
06549  * Check the common name if no alternative names matched.
06550  *
06551  * dCert    Decoded cert to get the alternative names from.
06552  * domain   Domain name to compare against.
06553  * checkCN  Whether to check the common name.
06554  * returns whether there was a problem in matching.
06555  */
06556 static int CheckForAltNames(DecodedCert* dCert, char* domain, int* checkCN)
06557 {
06558     int        match;
06559     DNS_entry* altName = NULL;
06560 
06561     WOLFSSL_MSG("Checking AltNames");
06562 
06563     if (dCert)
06564         altName = dCert->altNames;
06565 
06566     *checkCN = altName == NULL;
06567     match = 0;
06568     while (altName) {
06569         WOLFSSL_MSG("\tindividual AltName check");
06570 
06571         if (MatchDomainName(altName->name, (int)XSTRLEN(altName->name),
06572                             domain)) {
06573             match = 1;
06574             *checkCN = 0;
06575             break;
06576         }
06577         /* No matches and wild pattern match failed. */
06578         else if (altName->name[0] == '*' && match == 0)
06579             match = -1;
06580 
06581         altName = altName->next;
06582     }
06583 
06584     return match != -1;
06585 }
06586 
06587 /* Check the domain name matches the subject alternative name or the subject
06588  * name.
06589  *
06590  * dcert          Decoded certificate.
06591  * domainName     The domain name.
06592  * domainNameLen  The length of the domain name.
06593  * returns DOMAIN_NAME_MISMATCH when no match found and 0 on success.
06594  */
06595 int CheckHostName(DecodedCert* dCert, char *domainName, size_t domainNameLen)
06596 {
06597     int checkCN;
06598 
06599     /* Assume name is NUL terminated. */
06600     (void)domainNameLen;
06601 
06602     if (CheckForAltNames(dCert, domainName, &checkCN) == 0) {
06603         WOLFSSL_MSG("DomainName match on alt names failed too");
06604         return DOMAIN_NAME_MISMATCH;
06605     }
06606     if (checkCN == 1) {
06607         if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
06608                             domainName) == 0) {
06609             WOLFSSL_MSG("DomainName match on common name failed");
06610             return DOMAIN_NAME_MISMATCH;
06611         }
06612     }
06613 
06614     return 0;
06615 }
06616 #endif
06617 
06618 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
06619 
06620 /* Copy parts X509 needs from Decoded cert, 0 on success */
06621 int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
06622 {
06623     int ret = 0;
06624 
06625     if (x509 == NULL || dCert == NULL ||
06626         dCert->subjectCNLen < 0)
06627         return BAD_FUNC_ARG;
06628 
06629     x509->version = dCert->version + 1;
06630 
06631     XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
06632     x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
06633     x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
06634 #ifdef OPENSSL_EXTRA
06635     if (dCert->issuerName.fullName != NULL) {
06636         XMEMCPY(&x509->issuer.fullName,
06637                                        &dCert->issuerName, sizeof(DecodedName));
06638         x509->issuer.fullName.fullName = (char*)XMALLOC(
06639                         dCert->issuerName.fullNameLen, x509->heap,
06640                         DYNAMIC_TYPE_X509);
06641         if (x509->issuer.fullName.fullName != NULL)
06642             XMEMCPY(x509->issuer.fullName.fullName,
06643                      dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
06644     }
06645     x509->issuer.x509 = x509;
06646 #endif /* OPENSSL_EXTRA */
06647 
06648     XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
06649     x509->subject.name[ASN_NAME_MAX - 1] = '\0';
06650     x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
06651 #ifdef OPENSSL_EXTRA
06652     if (dCert->subjectName.fullName != NULL) {
06653         XMEMCPY(&x509->subject.fullName,
06654                                       &dCert->subjectName, sizeof(DecodedName));
06655         x509->subject.fullName.fullName = (char*)XMALLOC(
06656                  dCert->subjectName.fullNameLen, x509->heap, DYNAMIC_TYPE_X509);
06657         if (x509->subject.fullName.fullName != NULL)
06658             XMEMCPY(x509->subject.fullName.fullName,
06659                    dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
06660     }
06661     x509->subject.x509 = x509;
06662 #endif /* OPENSSL_EXTRA */
06663 
06664     XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
06665     x509->serialSz = dCert->serialSz;
06666     if (dCert->subjectCNLen < ASN_NAME_MAX) {
06667         XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
06668         x509->subjectCN[dCert->subjectCNLen] = '\0';
06669     }
06670     else
06671         x509->subjectCN[0] = '\0';
06672 
06673 #ifdef WOLFSSL_SEP
06674     {
06675         int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
06676         if (minSz > 0) {
06677             x509->deviceTypeSz = minSz;
06678             XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
06679         }
06680         else
06681             x509->deviceTypeSz = 0;
06682         minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
06683         if (minSz > 0) {
06684             x509->hwTypeSz = minSz;
06685             XMEMCPY(x509->hwType, dCert->hwType, minSz);
06686         }
06687         else
06688             x509->hwTypeSz = 0;
06689         minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
06690         if (minSz > 0) {
06691             x509->hwSerialNumSz = minSz;
06692             XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
06693         }
06694         else
06695             x509->hwSerialNumSz = 0;
06696     }
06697 #endif /* WOLFSSL_SEP */
06698     {
06699         int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
06700         if (minSz > 0) {
06701             x509->notBeforeSz = minSz;
06702             XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
06703         }
06704         else
06705             x509->notBeforeSz = 0;
06706         minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
06707         if (minSz > 0) {
06708             x509->notAfterSz = minSz;
06709             XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
06710         }
06711         else
06712             x509->notAfterSz = 0;
06713     }
06714 
06715     if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
06716         x509->pubKey.buffer = (byte*)XMALLOC(
06717                         dCert->pubKeySize, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
06718         if (x509->pubKey.buffer != NULL) {
06719             x509->pubKeyOID = dCert->keyOID;
06720             x509->pubKey.length = dCert->pubKeySize;
06721             XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
06722         }
06723         else
06724             ret = MEMORY_E;
06725     }
06726 
06727     if (dCert->signature != NULL && dCert->sigLength != 0 &&
06728             dCert->sigLength <= MAX_ENCODED_SIG_SZ) {
06729         x509->sig.buffer = (byte*)XMALLOC(
06730                           dCert->sigLength, x509->heap, DYNAMIC_TYPE_SIGNATURE);
06731         if (x509->sig.buffer == NULL) {
06732             ret = MEMORY_E;
06733         }
06734         else {
06735             XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
06736             x509->sig.length = dCert->sigLength;
06737             x509->sigOID = dCert->signatureOID;
06738         }
06739     }
06740 
06741     /* store cert for potential retrieval */
06742     if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, x509->heap) == 0) {
06743         XMEMCPY(x509->derCert->buffer, dCert->source, dCert->maxIdx);
06744     }
06745     else {
06746         ret = MEMORY_E;
06747     }
06748 
06749     x509->altNames       = dCert->altNames;
06750     dCert->weOwnAltNames = 0;
06751     x509->altNamesNext   = x509->altNames;  /* index hint */
06752 
06753     x509->isCa = dCert->isCA;
06754 #ifdef OPENSSL_EXTRA
06755     x509->pathLength = dCert->pathLength;
06756     x509->keyUsage = dCert->extKeyUsage;
06757 
06758     x509->CRLdistSet = dCert->extCRLdistSet;
06759     x509->CRLdistCrit = dCert->extCRLdistCrit;
06760     x509->CRLInfo = dCert->extCrlInfo;
06761     x509->CRLInfoSz = dCert->extCrlInfoSz;
06762     x509->authInfoSet = dCert->extAuthInfoSet;
06763     x509->authInfoCrit = dCert->extAuthInfoCrit;
06764     if (dCert->extAuthInfo != NULL && dCert->extAuthInfoSz > 0) {
06765         x509->authInfo = (byte*)XMALLOC(dCert->extAuthInfoSz, x509->heap,
06766                 DYNAMIC_TYPE_X509_EXT);
06767         if (x509->authInfo != NULL) {
06768             XMEMCPY(x509->authInfo, dCert->extAuthInfo, dCert->extAuthInfoSz);
06769             x509->authInfoSz = dCert->extAuthInfoSz;
06770         }
06771         else {
06772             ret = MEMORY_E;
06773         }
06774     }
06775     x509->basicConstSet = dCert->extBasicConstSet;
06776     x509->basicConstCrit = dCert->extBasicConstCrit;
06777     x509->basicConstPlSet = dCert->pathLengthSet;
06778     x509->subjAltNameSet = dCert->extSubjAltNameSet;
06779     x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
06780     x509->authKeyIdSet = dCert->extAuthKeyIdSet;
06781     x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
06782     if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
06783         x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, x509->heap,
06784                                          DYNAMIC_TYPE_X509_EXT);
06785         if (x509->authKeyId != NULL) {
06786             XMEMCPY(x509->authKeyId,
06787                                  dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
06788             x509->authKeyIdSz = dCert->extAuthKeyIdSz;
06789         }
06790         else
06791             ret = MEMORY_E;
06792     }
06793     x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
06794     x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
06795     if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
06796         x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, x509->heap,
06797                                          DYNAMIC_TYPE_X509_EXT);
06798         if (x509->subjKeyId != NULL) {
06799             XMEMCPY(x509->subjKeyId,
06800                                  dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
06801             x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
06802         }
06803         else
06804             ret = MEMORY_E;
06805     }
06806     x509->keyUsageSet = dCert->extKeyUsageSet;
06807     x509->keyUsageCrit = dCert->extKeyUsageCrit;
06808     if (dCert->extExtKeyUsageSrc != NULL && dCert->extExtKeyUsageSz > 0) {
06809         x509->extKeyUsageSrc = (byte*)XMALLOC(dCert->extExtKeyUsageSz,
06810                 x509->heap, DYNAMIC_TYPE_X509_EXT);
06811         if (x509->extKeyUsageSrc != NULL) {
06812             XMEMCPY(x509->extKeyUsageSrc, dCert->extExtKeyUsageSrc,
06813                                                        dCert->extExtKeyUsageSz);
06814             x509->extKeyUsageSz    = dCert->extExtKeyUsageSz;
06815             x509->extKeyUsageCrit  = dCert->extExtKeyUsageCrit;
06816             x509->extKeyUsageCount = dCert->extExtKeyUsageCount;
06817         }
06818         else {
06819             ret = MEMORY_E;
06820         }
06821     }
06822     #ifdef WOLFSSL_SEP
06823         x509->certPolicySet = dCert->extCertPolicySet;
06824         x509->certPolicyCrit = dCert->extCertPolicyCrit;
06825     #endif /* WOLFSSL_SEP */
06826     #ifdef WOLFSSL_CERT_EXT
06827         {
06828             int i;
06829             for (i = 0; i < dCert->extCertPoliciesNb && i < MAX_CERTPOL_NB; i++)
06830                 XMEMCPY(x509->certPolicies[i], dCert->extCertPolicies[i],
06831                                                                 MAX_CERTPOL_SZ);
06832             x509->certPoliciesNb = dCert->extCertPoliciesNb;
06833         }
06834     #endif /* WOLFSSL_CERT_EXT */
06835 #endif /* OPENSSL_EXTRA */
06836 #ifdef HAVE_ECC
06837     x509->pkCurveOID = dCert->pkCurveOID;
06838 #endif /* HAVE_ECC */
06839 
06840     return ret;
06841 }
06842 
06843 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
06844 
06845 typedef struct ProcPeerCertArgs {
06846     buffer*      certs;
06847 #ifdef WOLFSSL_TLS13
06848     buffer*      exts; /* extentions */
06849 #endif
06850     DecodedCert* dCert;
06851     char*  domain;
06852     word32 idx;
06853     word32 begin;
06854     int    totalCerts; /* number of certs in certs buffer */
06855     int    count;
06856     int    dCertInit;
06857     int    certIdx;
06858 #ifdef WOLFSSL_TLS13
06859     byte   ctxSz;
06860 #endif
06861 #ifdef WOLFSSL_TRUST_PEER_CERT
06862     byte haveTrustPeer; /* was cert verified by loaded trusted peer cert */
06863 #endif
06864 } ProcPeerCertArgs;
06865 
06866 static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs)
06867 {
06868     ProcPeerCertArgs* args = (ProcPeerCertArgs*)pArgs;
06869 
06870     (void)ssl;
06871 
06872     if (args->domain) {
06873         XFREE(args->domain, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06874         args->domain = NULL;
06875     }
06876     if (args->certs) {
06877         XFREE(args->certs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06878         args->certs = NULL;
06879     }
06880 #ifdef WOLFSSL_TLS13
06881     if (args->exts) {
06882         XFREE(args->exts, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06883         args->exts = NULL;
06884     }
06885 #endif
06886     if (args->dCert) {
06887         if (args->dCertInit) {
06888             FreeDecodedCert(args->dCert);
06889             args->dCertInit = 0;
06890         }
06891         XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06892         args->dCert = NULL;
06893     }
06894 }
06895 
06896 int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz)
06897 {
06898     int ret = 0, lastErr = 0;
06899 #ifdef WOLFSSL_ASYNC_CRYPT
06900     ProcPeerCertArgs* args = (ProcPeerCertArgs*)ssl->async.args;
06901     typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
06902     (void)sizeof(args_test);
06903 #else
06904     ProcPeerCertArgs  args[1];
06905 #endif
06906 
06907 #ifdef WOLFSSL_TRUST_PEER_CERT
06908     byte haveTrustPeer = 0; /* was cert verified by loaded trusted peer cert */
06909 #endif
06910 
06911     WOLFSSL_ENTER("ProcessPeerCerts");
06912 
06913 #ifdef WOLFSSL_ASYNC_CRYPT
06914     ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
06915     if (ret != WC_NOT_PENDING_E) {
06916         /* Check for error */
06917         if (ret < 0)
06918             goto exit_ppc;
06919     }
06920     else
06921 #endif
06922     {
06923         /* Reset state */
06924         ret = 0;
06925         ssl->options.asyncState = TLS_ASYNC_BEGIN;
06926         XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
06927         args->idx = *inOutIdx;
06928         args->begin = *inOutIdx;
06929     #ifdef WOLFSSL_ASYNC_CRYPT
06930         ssl->async.freeArgs = FreeProcPeerCertArgs;
06931     #endif
06932     }
06933 
06934     switch (ssl->options.asyncState)
06935     {
06936         case TLS_ASYNC_BEGIN:
06937         {
06938             word32 listSz;
06939 
06940         #ifdef WOLFSSL_CALLBACKS
06941             if (ssl->hsInfoOn)
06942                 AddPacketName("Certificate", &ssl->handShakeInfo);
06943             if (ssl->toInfoOn)
06944                 AddLateName("Certificate", &ssl->timeoutInfo);
06945         #endif
06946 
06947         #ifdef WOLFSSL_TLS13
06948             if (ssl->options.tls1_3) {
06949                 byte ctxSz;
06950 
06951                 /* Certificate Request Context */
06952                 if ((args->idx - args->begin) + OPAQUE8_LEN > totalSz)
06953                     return BUFFER_ERROR;
06954                 ctxSz = *(input + args->idx);
06955                 args->idx++;
06956                 if ((args->idx - args->begin) + ctxSz > totalSz)
06957                     return BUFFER_ERROR;
06958             #ifndef NO_WOLFSSL_CLIENT
06959                 /* Must be empty when received from server. */
06960                 if (ssl->options.side == WOLFSSL_CLIENT_END) {
06961                     if (ctxSz != 0) {
06962                         return INVALID_CERT_CTX_E;
06963                     }
06964                 }
06965             #endif
06966             #ifndef NO_WOLFSSL_SERVER
06967                 /* Must contain value sent in request when received from client. */
06968                 if (ssl->options.side == WOLFSSL_SERVER_END) {
06969                     if (ssl->clientCertCtx.length != ctxSz ||
06970                         XMEMCMP(ssl->clientCertCtx.buffer,
06971                             input + args->idx, ctxSz) != 0) {
06972                         return INVALID_CERT_CTX_E;
06973                     }
06974                 }
06975             #endif
06976                 args->idx += ctxSz;
06977 
06978                 /* allocate buffer for cert extensions */
06979                 args->exts = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH,
06980                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06981                 if (args->exts == NULL) {
06982                     ERROR_OUT(MEMORY_E, exit_ppc);
06983                 }
06984             }
06985         #endif
06986 
06987             /* allocate buffer for certs */
06988             args->certs = (buffer*)XMALLOC(sizeof(buffer) * MAX_CHAIN_DEPTH,
06989                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
06990             if (args->certs == NULL) {
06991                 ERROR_OUT(MEMORY_E, exit_ppc);
06992             }
06993             XMEMSET(args->certs, 0, sizeof(buffer) * MAX_CHAIN_DEPTH);
06994 
06995             /* Certificate List */
06996             if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) {
06997                 ERROR_OUT(BUFFER_ERROR, exit_ppc);
06998             }
06999             c24to32(input + args->idx, &listSz);
07000             args->idx += OPAQUE24_LEN;
07001             if (listSz > MAX_RECORD_SIZE) {
07002                 ERROR_OUT(BUFFER_ERROR, exit_ppc);
07003             }
07004             if ((args->idx - args->begin) + listSz != totalSz) {
07005                 ERROR_OUT(BUFFER_ERROR, exit_ppc);
07006             }
07007 
07008             WOLFSSL_MSG("Loading peer's cert chain");
07009             /* first put cert chain into buffer so can verify top down
07010                we're sent bottom up */
07011             while (listSz) {
07012                 word32 certSz;
07013 
07014                 if (args->totalCerts >= MAX_CHAIN_DEPTH) {
07015                 #ifdef OPENSSL_EXTRA
07016                     ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG;
07017                 #endif
07018                     ERROR_OUT(MAX_CHAIN_ERROR, exit_ppc);
07019                 }
07020 
07021                 if ((args->idx - args->begin) + OPAQUE24_LEN > totalSz) {
07022                     ERROR_OUT(BUFFER_ERROR, exit_ppc);
07023                 }
07024 
07025                 c24to32(input + args->idx, &certSz);
07026                 args->idx += OPAQUE24_LEN;
07027 
07028                 if ((args->idx - args->begin) + certSz > totalSz) {
07029                     ERROR_OUT(BUFFER_ERROR, exit_ppc);
07030                 }
07031 
07032                 args->certs[args->totalCerts].length = certSz;
07033                 args->certs[args->totalCerts].buffer = input + args->idx;
07034 
07035             #ifdef SESSION_CERTS
07036                 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
07037                                                certSz < MAX_X509_SIZE) {
07038                     ssl->session.chain.certs[
07039                         ssl->session.chain.count].length = certSz;
07040                     XMEMCPY(ssl->session.chain.certs[
07041                         ssl->session.chain.count].buffer,
07042                             input + args->idx, certSz);
07043                     ssl->session.chain.count++;
07044                 }
07045                 else {
07046                     WOLFSSL_MSG("Couldn't store chain cert for session");
07047                 }
07048             #endif /* SESSION_CERTS */
07049 
07050                 args->idx += certSz;
07051                 listSz -= certSz + CERT_HEADER_SZ;
07052 
07053             #ifdef WOLFSSL_TLS13
07054                 /* Extensions */
07055                 if (ssl->options.tls1_3) {
07056                     word16 extSz;
07057 
07058                     if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz)
07059                         return BUFFER_ERROR;
07060                     ato16(input + args->idx, &extSz);
07061                     args->idx += OPAQUE16_LEN;
07062                     if ((args->idx - args->begin) + extSz > totalSz)
07063                         return BUFFER_ERROR;
07064                     /* Store extension data info for later processing. */
07065                     args->exts[args->totalCerts].length = extSz;
07066                     args->exts[args->totalCerts].buffer = input + args->idx;
07067                     args->idx += extSz;
07068                     listSz -= extSz + OPAQUE16_LEN;
07069                 }
07070             #endif
07071 
07072                 args->totalCerts++;
07073                 WOLFSSL_MSG("\tPut another cert into chain");
07074             } /* while (listSz) */
07075 
07076             args->count = args->totalCerts;
07077             args->certIdx = 0;
07078 
07079             args->dCertInit = 0;
07080             args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
07081                                                        DYNAMIC_TYPE_TMP_BUFFER);
07082             if (args->dCert == NULL) {
07083                 ERROR_OUT(MEMORY_E, exit_ppc);
07084             }
07085 
07086             /* Advance state and proceed */
07087             ssl->options.asyncState = TLS_ASYNC_BUILD;
07088         } /* case TLS_ASYNC_BEGIN */
07089 
07090         case TLS_ASYNC_BUILD:
07091         {
07092             if (args->count > 0) {
07093             #ifdef WOLFSSL_TRUST_PEER_CERT
07094                 if (args->certIdx == 0) {
07095                     /* if using trusted peer certs check before verify chain
07096                        and CA test */
07097                     TrustedPeerCert* tp;
07098 
07099                     if (!args->dCertInit) {
07100                         InitDecodedCert(args->dCert,
07101                             args->certs[args->certIdx].buffer,
07102                             args->certs[args->certIdx].length, ssl->heap);
07103                         args->dCert->sigCtx.devId = ssl->devId; /* setup async dev */
07104                         args->dCertInit = 1;
07105                     }
07106 
07107                     ret = ParseCertRelative(args->dCert, CERT_TYPE, 0,
07108                                                                 ssl->ctx->cm);
07109                     if (ret != 0) {
07110                     #ifdef WOLFSSL_ASYNC_CRYPT
07111                         if (ret == WC_PENDING_E) {
07112                             ret = wolfSSL_AsyncPush(ssl,
07113                                 args->dCert->sigCtx.asyncDev,
07114                                 WC_ASYNC_FLAG_CALL_AGAIN);
07115                         }
07116                     #endif
07117                         goto exit_ppc;
07118                     }
07119 
07120                 #ifndef NO_SKID
07121                     if (args->dCert->extAuthKeyIdSet) {
07122                         tp = GetTrustedPeer(ssl->ctx->cm,
07123                                     args->dCert->extSubjKeyId, WC_MATCH_SKID);
07124                     }
07125                     else { /* if the cert has no SKID try to match by name */
07126                         tp = GetTrustedPeer(ssl->ctx->cm,
07127                                     args->dCert->subjectHash, WC_MATCH_NAME);
07128                     }
07129                 #else /* NO_SKID */
07130                     tp = GetTrustedPeer(ssl->ctx->cm, args->dCert->subjectHash,
07131                                                                  WC_MATCH_NAME);
07132                 #endif /* NO SKID */
07133                     WOLFSSL_MSG("Checking for trusted peer cert");
07134 
07135                     if (tp == NULL) {
07136                         /* no trusted peer cert */
07137                         WOLFSSL_MSG("No matching trusted peer cert. "
07138                             "Checking CAs");
07139                         FreeDecodedCert(args->dCert);
07140                         args->dCertInit = 0;
07141                     } else if (MatchTrustedPeer(tp, args->dCert)){
07142                         WOLFSSL_MSG("Found matching trusted peer cert");
07143                         haveTrustPeer = 1;
07144                     } else {
07145                         WOLFSSL_MSG("Trusted peer cert did not match!");
07146                         FreeDecodedCert(args->dCert);
07147                         args->dCertInit = 0;
07148                     }
07149                 }
07150             #endif /* WOLFSSL_TRUST_PEER_CERT */
07151 
07152                 /* verify up to peer's first */
07153                 /* do not verify chain if trusted peer cert found */
07154                 while (args->count > 1
07155                 #ifdef WOLFSSL_TRUST_PEER_CERT
07156                     && !haveTrustPeer
07157                 #endif /* WOLFSSL_TRUST_PEER_CERT */
07158                 ) {
07159                     byte* subjectHash;
07160 
07161                     args->certIdx = args->count - 1;
07162 
07163                     if (!args->dCertInit) {
07164                         InitDecodedCert(args->dCert,
07165                             args->certs[args->certIdx].buffer,
07166                             args->certs[args->certIdx].length, ssl->heap);
07167                         args->dCert->sigCtx.devId = ssl->devId; /* setup async dev */
07168                         args->dCertInit = 1;
07169                     }
07170 
07171                     ret = ParseCertRelative(args->dCert, CERT_TYPE,
07172                                     !ssl->options.verifyNone, ssl->ctx->cm);
07173                 #ifdef WOLFSSL_ASYNC_CRYPT
07174                     if (ret == WC_PENDING_E) {
07175                         ret = wolfSSL_AsyncPush(ssl,
07176                             args->dCert->sigCtx.asyncDev,
07177                             WC_ASYNC_FLAG_CALL_AGAIN);
07178                         goto exit_dc;
07179                     }
07180                 #endif
07181 
07182                 #ifndef NO_SKID
07183                     subjectHash = args->dCert->extSubjKeyId;
07184                 #else
07185                     subjectHash = args->dCert->subjectHash;
07186                 #endif
07187 
07188                     /* Check key sizes for certs. Is redundent check since
07189                        ProcessBuffer also performs this check. */
07190                     if (!ssl->options.verifyNone) {
07191                         switch (args->dCert->keyOID) {
07192                         #ifndef NO_RSA
07193                             case RSAk:
07194                                 if (ssl->options.minRsaKeySz < 0 ||
07195                                         args->dCert->pubKeySize <
07196                                          (word16)ssl->options.minRsaKeySz) {
07197                                     WOLFSSL_MSG(
07198                                         "RSA key size in cert chain error");
07199                                     ret = RSA_KEY_SIZE_E;
07200                                 }
07201                                 break;
07202                         #endif /* !NO_RSA */
07203                         #ifdef HAVE_ECC
07204                             case ECDSAk:
07205                                 if (ssl->options.minEccKeySz < 0 ||
07206                                         args->dCert->pubKeySize <
07207                                          (word16)ssl->options.minEccKeySz) {
07208                                     WOLFSSL_MSG(
07209                                         "ECC key size in cert chain error");
07210                                     ret = ECC_KEY_SIZE_E;
07211                                 }
07212                                 break;
07213                         #endif /* HAVE_ECC */
07214                             default:
07215                                 WOLFSSL_MSG("Key size not checked");
07216                                 /* key not being checked for size if not in
07217                                    switch */
07218                                 break;
07219                         } /* switch (dCert->keyOID) */
07220                     } /* if (!ssl->options.verifyNone) */
07221 
07222                     if (ret == 0 && args->dCert->isCA == 0) {
07223                         WOLFSSL_MSG("Chain cert is not a CA, not adding as one");
07224                     }
07225                     else if (ret == 0 && ssl->options.verifyNone) {
07226                         WOLFSSL_MSG("Chain cert not verified by option, not adding as CA");
07227                     }
07228                     else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
07229                         DerBuffer* add = NULL;
07230                         ret = AllocDer(&add, args->certs[args->certIdx].length,
07231                                                             CA_TYPE, ssl->heap);
07232                         if (ret < 0)
07233                             goto exit_ppc;
07234 
07235                         WOLFSSL_MSG("Adding CA from chain");
07236 
07237                         XMEMCPY(add->buffer, args->certs[args->certIdx].buffer,
07238                                              args->certs[args->certIdx].length);
07239 
07240                         /* already verified above */
07241                         ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0);
07242                         if (ret == 1) {
07243                             ret = 0;   /* SSL_SUCCESS for external */
07244                         }
07245                     }
07246                     else if (ret != 0) {
07247                         WOLFSSL_MSG("Failed to verify CA from chain");
07248                     #ifdef OPENSSL_EXTRA
07249                         ssl->peerVerifyRet = X509_V_ERR_INVALID_CA;
07250                     #endif
07251                     }
07252                     else {
07253                         WOLFSSL_MSG("Verified CA from chain and already had it");
07254                     }
07255 
07256             #if defined(HAVE_OCSP) || defined(HAVE_CRL)
07257                     if (ret == 0) {
07258                         int doCrlLookup = 1;
07259                 #ifdef HAVE_OCSP
07260                     #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
07261                         if (ssl->status_request_v2) {
07262                             ret = TLSX_CSR2_InitRequests(ssl->extensions,
07263                                                     args->dCert, 0, ssl->heap);
07264                         }
07265                         else /* skips OCSP and force CRL check */
07266                     #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
07267                         if (ssl->ctx->cm->ocspEnabled &&
07268                                             ssl->ctx->cm->ocspCheckAll) {
07269                             WOLFSSL_MSG("Doing Non Leaf OCSP check");
07270                             ret = CheckCertOCSP(ssl->ctx->cm->ocsp, args->dCert,
07271                                                                           NULL);
07272                             doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
07273                             if (ret != 0) {
07274                                 doCrlLookup = 0;
07275                                 WOLFSSL_MSG("\tOCSP Lookup not ok");
07276                             }
07277                         }
07278                 #endif /* HAVE_OCSP */
07279 
07280                 #ifdef HAVE_CRL
07281                         if (ret == 0 && doCrlLookup &&
07282                                     ssl->ctx->cm->crlEnabled &&
07283                                                 ssl->ctx->cm->crlCheckAll) {
07284                             WOLFSSL_MSG("Doing Non Leaf CRL check");
07285                             ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
07286                             if (ret != 0) {
07287                                 WOLFSSL_MSG("\tCRL check not ok");
07288                             }
07289                         }
07290                 #endif /* HAVE_CRL */
07291                         (void)doCrlLookup;
07292                     }
07293             #endif /* HAVE_OCSP || HAVE_CRL */
07294 
07295                     if (ret != 0 && lastErr == 0) {
07296                         lastErr = ret;   /* save error from last time */
07297                     }
07298 
07299                     FreeDecodedCert(args->dCert);
07300                     args->dCertInit = 0;
07301                     args->count--;
07302                 } /* while (count > 0 && !haveTrustPeer) */
07303             } /* if (count > 0) */
07304 
07305             /* Check for error */
07306             if (ret != 0) {
07307                 goto exit_ppc;
07308             }
07309 
07310             /* Advance state and proceed */
07311             ssl->options.asyncState = TLS_ASYNC_DO;
07312         } /* case TLS_ASYNC_BUILD */
07313 
07314         case TLS_ASYNC_DO:
07315         {
07316             /* peer's, may not have one if blank client cert sent by TLSv1.2 */
07317             if (args->count > 0) {
07318                 int fatal  = 0;
07319 
07320                 WOLFSSL_MSG("Verifying Peer's cert");
07321 
07322                 args->certIdx = 0;
07323 
07324                 if (!args->dCertInit) {
07325                     InitDecodedCert(args->dCert,
07326                         args->certs[args->certIdx].buffer,
07327                         args->certs[args->certIdx].length, ssl->heap);
07328                     args->dCertInit = 1;
07329                 }
07330 
07331             #ifdef WOLFSSL_TRUST_PEER_CERT
07332                 if (!haveTrustPeer)
07333             #endif
07334                 { /* only parse if not already present in dCert from above */
07335                     ret = ParseCertRelative(args->dCert, CERT_TYPE,
07336                                     !ssl->options.verifyNone, ssl->ctx->cm);
07337                 #ifdef WOLFSSL_ASYNC_CRYPT
07338                     if (ret == WC_PENDING_E) {
07339                         ret = wolfSSL_AsyncPush(ssl,
07340                             args->dCert->sigCtx.asyncDev,
07341                             WC_ASYNC_FLAG_CALL_AGAIN);
07342                         goto exit_dc;
07343                     }
07344                 #endif
07345                 }
07346 
07347                 if (ret == 0) {
07348                     WOLFSSL_MSG("Verified Peer's cert");
07349                 #ifdef OPENSSL_EXTRA
07350                     ssl->peerVerifyRet = X509_V_OK;
07351                 #endif
07352                     fatal = 0;
07353         #ifdef OPENSSL_EXTRA
07354                     ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
07355         #endif
07356                 }
07357                 else if (ret == ASN_PARSE_E || ret == BUFFER_E) {
07358                     WOLFSSL_MSG("Got Peer cert ASN PARSE or BUFFER ERROR");
07359                     fatal = 1;
07360                 }
07361                 else {
07362                     WOLFSSL_MSG("Failed to verify Peer's cert");
07363                 #ifdef OPENSSL_EXTRA
07364                     ssl->peerVerifyRet = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
07365                 #endif
07366                     if (ssl->verifyCallback) {
07367                         WOLFSSL_MSG(
07368                             "\tCallback override available, will continue");
07369                         fatal = 0;
07370                     }
07371                     else {
07372                         WOLFSSL_MSG("\tNo callback override available, fatal");
07373                         fatal = 1;
07374                     }
07375                 }
07376 
07377             #ifdef HAVE_SECURE_RENEGOTIATION
07378                 if (fatal == 0 && ssl->secure_renegotiation
07379                                && ssl->secure_renegotiation->enabled) {
07380 
07381                     if (IsEncryptionOn(ssl, 0)) {
07382                         /* compare against previous time */
07383                         if (XMEMCMP(args->dCert->subjectHash,
07384                                     ssl->secure_renegotiation->subject_hash,
07385                                     SHA_DIGEST_SIZE) != 0) {
07386                             WOLFSSL_MSG(
07387                                 "Peer sent different cert during scr, fatal");
07388                             fatal = 1;
07389                             ret   = SCR_DIFFERENT_CERT_E;
07390                         }
07391                     }
07392 
07393                     /* cache peer's hash */
07394                     if (fatal == 0) {
07395                         XMEMCPY(ssl->secure_renegotiation->subject_hash,
07396                                 args->dCert->subjectHash, SHA_DIGEST_SIZE);
07397                     }
07398                 }
07399             #endif /* HAVE_SECURE_RENEGOTIATION */
07400 
07401             #if defined(HAVE_OCSP) || defined(HAVE_CRL)
07402                 if (fatal == 0) {
07403                     int doLookup = 1;
07404 
07405                     if (ssl->options.side == WOLFSSL_CLIENT_END) {
07406                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
07407                         if (ssl->status_request) {
07408                             fatal = TLSX_CSR_InitRequest(ssl->extensions,
07409                                                     args->dCert, ssl->heap);
07410                             doLookup = 0;
07411                         }
07412                 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
07413                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
07414                         if (ssl->status_request_v2) {
07415                             fatal = TLSX_CSR2_InitRequests(ssl->extensions,
07416                                                     args->dCert, 1, ssl->heap);
07417                             doLookup = 0;
07418                         }
07419                 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
07420                     }
07421 
07422                 #ifdef HAVE_OCSP
07423                     if (doLookup && ssl->ctx->cm->ocspEnabled) {
07424                         WOLFSSL_MSG("Doing Leaf OCSP check");
07425                         ret = CheckCertOCSP(ssl->ctx->cm->ocsp,
07426                                                             args->dCert, NULL);
07427                         doLookup = (ret == OCSP_CERT_UNKNOWN);
07428                         if (ret != 0) {
07429                             WOLFSSL_MSG("\tOCSP Lookup not ok");
07430                             fatal = 0;
07431                         #ifdef OPENSSL_EXTRA
07432                             ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
07433                         #endif
07434                         }
07435                     }
07436                 #endif /* HAVE_OCSP */
07437 
07438                 #ifdef HAVE_CRL
07439                     if (doLookup && ssl->ctx->cm->crlEnabled) {
07440                         WOLFSSL_MSG("Doing Leaf CRL check");
07441                         ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
07442                         if (ret != 0) {
07443                             WOLFSSL_MSG("\tCRL check not ok");
07444                             fatal = 0;
07445                         #ifdef OPENSSL_EXTRA
07446                             ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
07447                         #endif
07448                         }
07449                     }
07450                 #endif /* HAVE_CRL */
07451                     (void)doLookup;
07452                 }
07453             #endif /* HAVE_OCSP || HAVE_CRL */
07454 
07455             #ifdef KEEP_PEER_CERT
07456                 if (fatal == 0) {
07457                     /* set X509 format for peer cert */
07458                     int copyRet = CopyDecodedToX509(&ssl->peerCert,
07459                                                                 args->dCert);
07460                     if (copyRet == MEMORY_E)
07461                         fatal = 1;
07462                 }
07463             #endif /* KEEP_PEER_CERT */
07464 
07465             #ifndef IGNORE_KEY_EXTENSIONS
07466                 if (args->dCert->extKeyUsageSet) {
07467                     if ((ssl->specs.kea == rsa_kea) &&
07468                         (ssl->options.side == WOLFSSL_CLIENT_END) &&
07469                         (args->dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
07470                         ret = KEYUSE_ENCIPHER_E;
07471                     }
07472                     if ((ssl->specs.sig_algo == rsa_sa_algo ||
07473                             (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
07474                                  !ssl->specs.static_ecdh)) &&
07475                         (args->dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
07476                         WOLFSSL_MSG("KeyUse Digital Sig not set");
07477                         ret = KEYUSE_SIGNATURE_E;
07478                     }
07479                 }
07480 
07481                 if (args->dCert->extExtKeyUsageSet) {
07482                     if (ssl->options.side == WOLFSSL_CLIENT_END) {
07483                         if ((args->dCert->extExtKeyUsage &
07484                                 (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
07485                             WOLFSSL_MSG("ExtKeyUse Server Auth not set");
07486                             ret = EXTKEYUSE_AUTH_E;
07487                         }
07488                     }
07489                     else {
07490                         if ((args->dCert->extExtKeyUsage &
07491                                 (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
07492                             WOLFSSL_MSG("ExtKeyUse Client Auth not set");
07493                             ret = EXTKEYUSE_AUTH_E;
07494                         }
07495                     }
07496                 }
07497             #endif /* IGNORE_KEY_EXTENSIONS */
07498 
07499                 if (fatal) {
07500                     ssl->error = ret;
07501                 #ifdef OPENSSL_EXTRA
07502                     ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED;
07503                 #endif
07504                     goto exit_ppc;
07505                 }
07506 
07507                 ssl->options.havePeerCert = 1;
07508             } /* if (count > 0) */
07509 
07510             /* Check for error */
07511             if (ret != 0) {
07512                 goto exit_ppc;
07513             }
07514 
07515             /* Advance state and proceed */
07516             ssl->options.asyncState = TLS_ASYNC_VERIFY;
07517         } /* case TLS_ASYNC_DO */
07518 
07519         case TLS_ASYNC_VERIFY:
07520         {
07521             if (args->count > 0) {
07522                 args->domain = (char*)XMALLOC(ASN_NAME_MAX, ssl->heap,
07523                                                     DYNAMIC_TYPE_TMP_BUFFER);
07524                 if (args->domain == NULL) {
07525                     ERROR_OUT(MEMORY_E, exit_ppc);
07526                 }
07527 
07528                 /* store for callback use */
07529                 if (args->dCert->subjectCNLen < ASN_NAME_MAX) {
07530                     XMEMCPY(args->domain, args->dCert->subjectCN, args->dCert->subjectCNLen);
07531                     args->domain[args->dCert->subjectCNLen] = '\0';
07532                 }
07533                 else {
07534                     args->domain[0] = '\0';
07535                 }
07536 
07537                 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
07538                     if (MatchDomainName(args->dCert->subjectCN,
07539                                 args->dCert->subjectCNLen,
07540                                 (char*)ssl->buffers.domainName.buffer) == 0) {
07541                         WOLFSSL_MSG("DomainName match on common name failed");
07542                         if (CheckAltNames(args->dCert,
07543                                  (char*)ssl->buffers.domainName.buffer) == 0 ) {
07544                             WOLFSSL_MSG(
07545                                 "DomainName match on alt names failed too");
07546                             /* try to get peer key still */
07547                             ret = DOMAIN_NAME_MISMATCH;
07548                         }
07549                     }
07550                 }
07551 
07552                 /* decode peer key */
07553                 switch (args->dCert->keyOID) {
07554                 #ifndef NO_RSA
07555                     case RSAk:
07556                     {
07557                         word32 keyIdx = 0;
07558                         int keyRet = 0;
07559 
07560                         if (ssl->peerRsaKey == NULL) {
07561                             keyRet = AllocKey(ssl, DYNAMIC_TYPE_RSA,
07562                                                 (void**)&ssl->peerRsaKey);
07563                         } else if (ssl->peerRsaKeyPresent) {
07564                             /* don't leak on reuse */
07565                             wc_FreeRsaKey(ssl->peerRsaKey);
07566                             ssl->peerRsaKeyPresent = 0;
07567                             keyRet = wc_InitRsaKey_ex(ssl->peerRsaKey,
07568                                                     ssl->heap, ssl->devId);
07569                         }
07570 
07571                         if (keyRet != 0 || wc_RsaPublicKeyDecode(
07572                                 args->dCert->publicKey, &keyIdx, ssl->peerRsaKey,
07573                                                 args->dCert->pubKeySize) != 0) {
07574                             ret = PEER_KEY_ERROR;
07575                         }
07576                         else {
07577                             ssl->peerRsaKeyPresent = 1;
07578                     #ifdef HAVE_PK_CALLBACKS
07579                         #ifndef NO_RSA
07580                             ssl->buffers.peerRsaKey.buffer =
07581                                    (byte*)XMALLOC(args->dCert->pubKeySize,
07582                                                 ssl->heap, DYNAMIC_TYPE_RSA);
07583                             if (ssl->buffers.peerRsaKey.buffer == NULL) {
07584                                 ret = MEMORY_ERROR;
07585                             }
07586                             else {
07587                                 XMEMCPY(ssl->buffers.peerRsaKey.buffer,
07588                                         args->dCert->publicKey,
07589                                         args->dCert->pubKeySize);
07590                                 ssl->buffers.peerRsaKey.length =
07591                                     args->dCert->pubKeySize;
07592                             }
07593                         #endif /* NO_RSA */
07594                     #endif /* HAVE_PK_CALLBACKS */
07595                         }
07596 
07597                         /* check size of peer RSA key */
07598                         if (ret == 0 && ssl->peerRsaKeyPresent &&
07599                                           !ssl->options.verifyNone &&
07600                                           wc_RsaEncryptSize(ssl->peerRsaKey)
07601                                               < ssl->options.minRsaKeySz) {
07602                             ret = RSA_KEY_SIZE_E;
07603                             WOLFSSL_MSG("Peer RSA key is too small");
07604                         }
07605                         break;
07606                     }
07607                 #endif /* NO_RSA */
07608                 #ifdef HAVE_NTRU
07609                     case NTRUk:
07610                     {
07611                         if (args->dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
07612                             ret = PEER_KEY_ERROR;
07613                         }
07614                         else {
07615                             XMEMCPY(ssl->peerNtruKey, args->dCert->publicKey,
07616                                                       args->dCert->pubKeySize);
07617                             ssl->peerNtruKeyLen =
07618                                 (word16)args->dCert->pubKeySize;
07619                             ssl->peerNtruKeyPresent = 1;
07620                         }
07621                         break;
07622                     }
07623                 #endif /* HAVE_NTRU */
07624                 #ifdef HAVE_ECC
07625                     case ECDSAk:
07626                     {
07627                         int curveId;
07628                         if (ssl->peerEccDsaKey == NULL) {
07629                             /* alloc/init on demand */
07630                             ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
07631                                     (void**)&ssl->peerEccDsaKey);
07632                         } else if (ssl->peerEccDsaKeyPresent) {
07633                             /* don't leak on reuse */
07634                             wc_ecc_free(ssl->peerEccDsaKey);
07635                             ssl->peerEccDsaKeyPresent = 0;
07636                             ret = wc_ecc_init_ex(ssl->peerEccDsaKey,
07637                                                     ssl->heap, ssl->devId);
07638                         }
07639                         if (ret != 0) {
07640                             break;
07641                         }
07642 
07643                         curveId = wc_ecc_get_oid(args->dCert->keyOID, NULL, NULL);
07644                         if (wc_ecc_import_x963_ex(args->dCert->publicKey,
07645                                     args->dCert->pubKeySize, ssl->peerEccDsaKey,
07646                                                             curveId) != 0) {
07647                             ret = PEER_KEY_ERROR;
07648                         }
07649                         else {
07650                             ssl->peerEccDsaKeyPresent = 1;
07651                     #ifdef HAVE_PK_CALLBACKS
07652                         #ifdef HAVE_ECC
07653                             ssl->buffers.peerEccDsaKey.buffer =
07654                                    (byte*)XMALLOC(args->dCert->pubKeySize,
07655                                            ssl->heap, DYNAMIC_TYPE_ECC);
07656                             if (ssl->buffers.peerEccDsaKey.buffer == NULL)
07657                                 ret = MEMORY_ERROR;
07658                             else {
07659                                 XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
07660                                         args->dCert->publicKey,
07661                                         args->dCert->pubKeySize);
07662                                 ssl->buffers.peerEccDsaKey.length =
07663                                         args->dCert->pubKeySize;
07664                             }
07665                         #endif /* HAVE_ECC */
07666                     #endif /*HAVE_PK_CALLBACKS */
07667                         }
07668 
07669                         /* check size of peer ECC key */
07670                         if (ret == 0 && ssl->peerEccDsaKeyPresent &&
07671                                               !ssl->options.verifyNone &&
07672                                               wc_ecc_size(ssl->peerEccDsaKey)
07673                                               < ssl->options.minEccKeySz) {
07674                             ret = ECC_KEY_SIZE_E;
07675                             WOLFSSL_MSG("Peer ECC key is too small");
07676                         }
07677                         break;
07678                     }
07679                 #endif /* HAVE_ECC */
07680                     default:
07681                         break;
07682                 }
07683 
07684                 FreeDecodedCert(args->dCert);
07685                 args->dCertInit = 0;
07686 
07687                 /* release since we don't need it anymore */
07688                 if (args->dCert) {
07689                     XFREE(args->dCert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07690                     args->dCert = NULL;
07691                 }
07692             } /* if (count > 0) */
07693 
07694             /* Check for error */
07695             if (ret != 0) {
07696                 goto exit_ppc;
07697             }
07698 
07699             /* Advance state and proceed */
07700             ssl->options.asyncState = TLS_ASYNC_FINALIZE;
07701         } /* case TLS_ASYNC_VERIFY */
07702 
07703         case TLS_ASYNC_FINALIZE:
07704         {
07705         #ifdef WOLFSSL_SMALL_STACK
07706             WOLFSSL_X509_STORE_CTX* store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(
07707                                     sizeof(WOLFSSL_X509_STORE_CTX), ssl->heap,
07708                                                     DYNAMIC_TYPE_TMP_BUFFER);
07709             if (store == NULL) {
07710                 ERROR_OUT(MEMORY_E, exit_ppc);
07711             }
07712         #else
07713             WOLFSSL_X509_STORE_CTX  store[1];
07714         #endif
07715 
07716             XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE_CTX));
07717 
07718             /* load last error */
07719             if (lastErr != 0 && ret == 0) {
07720                 ret = lastErr;
07721             }
07722 
07723             if (ret != 0) {
07724                 if (!ssl->options.verifyNone) {
07725                     int why = bad_certificate;
07726 
07727                     if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E) {
07728                         why = certificate_expired;
07729                     }
07730                     if (ssl->verifyCallback) {
07731                         int ok;
07732 
07733                         store->error = ret;
07734                         store->error_depth = args->totalCerts;
07735                         store->discardSessionCerts = 0;
07736                         store->domain = args->domain;
07737                         store->userCtx = ssl->verifyCbCtx;
07738                         store->certs = args->certs;
07739                         store->totalCerts = args->totalCerts;
07740                     #ifdef KEEP_PEER_CERT
07741                         if (ssl->peerCert.subject.sz > 0)
07742                             store->current_cert = &ssl->peerCert;
07743                         else
07744                             store->current_cert = NULL;
07745                     #else
07746                         store->current_cert = NULL;
07747                     #endif /* KEEP_PEER_CERT */
07748                     #if defined(HAVE_EX_DATA) || defined(HAVE_FORTRESS)
07749                         store->ex_data = ssl;
07750                     #endif
07751                         ok = ssl->verifyCallback(0, store);
07752                         if (ok) {
07753                             WOLFSSL_MSG("Verify callback overriding error!");
07754                             ret = 0;
07755                         }
07756                     #ifdef SESSION_CERTS
07757                         if (store->discardSessionCerts) {
07758                             WOLFSSL_MSG("Verify callback requested discard sess certs");
07759                             ssl->session.chain.count = 0;
07760                         }
07761                     #endif /* SESSION_CERTS */
07762                     }
07763                     if (ret != 0) {
07764                         SendAlert(ssl, alert_fatal, why);   /* try to send */
07765                         ssl->options.isClosed = 1;
07766                     }
07767                 }
07768                 ssl->error = ret;
07769             }
07770         #ifdef WOLFSSL_ALWAYS_VERIFY_CB
07771             else {
07772                 if (ssl->verifyCallback) {
07773                     int ok;
07774 
07775                     store->error = ret;
07776                 #ifdef WOLFSSL_WPAS
07777                     store->error_depth = 0;
07778                 #else
07779                     store->error_depth = args->totalCerts;
07780                 #endif
07781                     store->discardSessionCerts = 0;
07782                     store->domain = args->domain;
07783                     store->userCtx = ssl->verifyCbCtx;
07784                     store->certs = args->certs;
07785                     store->totalCerts = args->totalCerts;
07786                 #ifdef KEEP_PEER_CERT
07787                     if (ssl->peerCert.subject.sz > 0)
07788                         store->current_cert = &ssl->peerCert;
07789                     else
07790                         store->current_cert = NULL;
07791                 #endif
07792                     store->ex_data = ssl;
07793 
07794                     ok = ssl->verifyCallback(1, store);
07795                     if (!ok) {
07796                         WOLFSSL_MSG("Verify callback overriding valid certificate!");
07797                         ret = -1;
07798                         SendAlert(ssl, alert_fatal, bad_certificate);
07799                         ssl->options.isClosed = 1;
07800                     }
07801                 #ifdef SESSION_CERTS
07802                     if (store->discardSessionCerts) {
07803                         WOLFSSL_MSG("Verify callback requested discard sess certs");
07804                         ssl->session.chain.count = 0;
07805                     }
07806                 #endif /* SESSION_CERTS */
07807                 }
07808             }
07809         #endif /* WOLFSSL_ALWAYS_VERIFY_CB */
07810 
07811             if (ssl->options.verifyNone &&
07812                                       (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
07813                 WOLFSSL_MSG("Ignoring CRL problem based on verify setting");
07814                 ret = ssl->error = 0;
07815             }
07816 
07817             if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END) {
07818                 ssl->options.serverState = SERVER_CERT_COMPLETE;
07819             }
07820 
07821             if (IsEncryptionOn(ssl, 0)) {
07822                 args->idx += ssl->keys.padSz;
07823             }
07824 
07825         #ifdef WOLFSSL_SMALL_STACK
07826             XFREE(store, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07827         #endif
07828             /* Advance state and proceed */
07829             ssl->options.asyncState = TLS_ASYNC_END;
07830         } /* case TLS_ASYNC_FINALIZE */
07831 
07832         case TLS_ASYNC_END:
07833         {
07834             /* Set final index */
07835             *inOutIdx = args->idx;
07836 
07837             break;
07838         }
07839         default:
07840             ret = INPUT_CASE_ERROR;
07841             break;
07842     } /* switch(ssl->options.asyncState) */
07843 
07844 exit_ppc:
07845 
07846     WOLFSSL_LEAVE("ProcessPeerCerts", ret);
07847 
07848 #ifdef WOLFSSL_ASYNC_CRYPT
07849     /* Handle WC_PENDING_E */
07850     if (ret == WC_PENDING_E) {
07851         /* Mark message as not recevied so it can process again */
07852         ssl->msgsReceived.got_certificate = 0;
07853 
07854         return ret;
07855     }
07856 #endif /* WOLFSSL_ASYNC_CRYPT */
07857 
07858     FreeProcPeerCertArgs(ssl, args);
07859     FreeKeyExchange(ssl);
07860 
07861     return ret;
07862 }
07863 
07864 static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
07865                                                                 word32 size)
07866 {
07867     return ProcessPeerCerts(ssl, input, inOutIdx, size);
07868 }
07869 
07870 static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
07871                                                                     word32 size)
07872 {
07873     int    ret = 0;
07874     byte   status_type;
07875     word32 status_length;
07876 
07877     if (size < ENUM_LEN + OPAQUE24_LEN)
07878         return BUFFER_ERROR;
07879 
07880     status_type = input[(*inOutIdx)++];
07881 
07882     c24to32(input + *inOutIdx, &status_length);
07883     *inOutIdx += OPAQUE24_LEN;
07884 
07885     if (size != ENUM_LEN + OPAQUE24_LEN + status_length)
07886         return BUFFER_ERROR;
07887 
07888     switch (status_type) {
07889 
07890     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
07891      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
07892 
07893         /* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
07894         case WOLFSSL_CSR2_OCSP: {
07895             OcspRequest* request;
07896 
07897             #ifdef WOLFSSL_SMALL_STACK
07898                 CertStatus* status;
07899                 OcspResponse* response;
07900             #else
07901                 CertStatus status[1];
07902                 OcspResponse response[1];
07903             #endif
07904 
07905             do {
07906                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
07907                     if (ssl->status_request) {
07908                         request = (OcspRequest*)TLSX_CSR_GetRequest(
07909                                                                ssl->extensions);
07910                         ssl->status_request = 0;
07911                         break;
07912                     }
07913                 #endif
07914 
07915                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
07916                     if (ssl->status_request_v2) {
07917                         request = (OcspRequest*)TLSX_CSR2_GetRequest(
07918                                                ssl->extensions, status_type, 0);
07919                         ssl->status_request_v2 = 0;
07920                         break;
07921                     }
07922                 #endif
07923 
07924                 return BUFFER_ERROR;
07925             } while(0);
07926 
07927             if (request == NULL)
07928                 return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */
07929 
07930             #ifdef WOLFSSL_SMALL_STACK
07931                 status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
07932                                                        DYNAMIC_TYPE_TMP_BUFFER);
07933                 response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), ssl->heap,
07934                                                        DYNAMIC_TYPE_TMP_BUFFER);
07935 
07936                 if (status == NULL || response == NULL) {
07937                     if (status)
07938                         XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07939                     if (response)
07940                         XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07941 
07942                     return MEMORY_ERROR;
07943                 }
07944             #endif
07945 
07946             InitOcspResponse(response, status, input +*inOutIdx, status_length);
07947 
07948             if (OcspResponseDecode(response, ssl->ctx->cm, ssl->heap, 0) != 0)
07949                 ret = BAD_CERTIFICATE_STATUS_ERROR;
07950             else if (CompareOcspReqResp(request, response) != 0)
07951                 ret = BAD_CERTIFICATE_STATUS_ERROR;
07952             else if (response->responseStatus != OCSP_SUCCESSFUL)
07953                 ret = BAD_CERTIFICATE_STATUS_ERROR;
07954             else if (response->status->status == CERT_REVOKED)
07955                 ret = OCSP_CERT_REVOKED;
07956             else if (response->status->status != CERT_GOOD)
07957                 ret = BAD_CERTIFICATE_STATUS_ERROR;
07958 
07959             *inOutIdx += status_length;
07960 
07961             #ifdef WOLFSSL_SMALL_STACK
07962                 XFREE(status,   ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07963                 XFREE(response, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
07964             #endif
07965 
07966         }
07967         break;
07968 
07969     #endif
07970 
07971     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
07972 
07973         case WOLFSSL_CSR2_OCSP_MULTI: {
07974             OcspRequest* request;
07975             word32 list_length = status_length;
07976             byte   idx = 0;
07977 
07978             #ifdef WOLFSSL_SMALL_STACK
07979                 CertStatus* status;
07980                 OcspResponse* response;
07981             #else
07982                 CertStatus status[1];
07983                 OcspResponse response[1];
07984             #endif
07985 
07986             do {
07987                 if (ssl->status_request_v2) {
07988                     ssl->status_request_v2 = 0;
07989                     break;
07990                 }
07991 
07992                 return BUFFER_ERROR;
07993             } while(0);
07994 
07995             #ifdef WOLFSSL_SMALL_STACK
07996                 status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
07997                                                        DYNAMIC_TYPE_TMP_BUFFER);
07998                 response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), ssl->heap,
07999                                                        DYNAMIC_TYPE_TMP_BUFFER);
08000 
08001                 if (status == NULL || response == NULL) {
08002                     if (status)
08003                         XFREE(status, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
08004                     if (response)
08005                         XFREE(response, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
08006 
08007                     return MEMORY_ERROR;
08008                 }
08009             #endif
08010 
08011             while (list_length && ret == 0) {
08012                 if (OPAQUE24_LEN > list_length) {
08013                     ret = BUFFER_ERROR;
08014                     break;
08015                 }
08016 
08017                 c24to32(input + *inOutIdx, &status_length);
08018                 *inOutIdx   += OPAQUE24_LEN;
08019                 list_length -= OPAQUE24_LEN;
08020 
08021                 if (status_length > list_length) {
08022                     ret = BUFFER_ERROR;
08023                     break;
08024                 }
08025 
08026                 if (status_length) {
08027                     InitOcspResponse(response, status, input +*inOutIdx,
08028                                                                  status_length);
08029 
08030                     if ((OcspResponseDecode(response, ssl->ctx->cm, ssl->heap,
08031                                                                         0) != 0)
08032                     ||  (response->responseStatus != OCSP_SUCCESSFUL)
08033                     ||  (response->status->status != CERT_GOOD))
08034                         ret = BAD_CERTIFICATE_STATUS_ERROR;
08035 
08036                     while (ret == 0) {
08037                         request = (OcspRequest*)TLSX_CSR2_GetRequest(
08038                                 ssl->extensions, status_type, idx++);
08039 
08040                         if (request == NULL)
08041                             ret = BAD_CERTIFICATE_STATUS_ERROR;
08042                         else if (CompareOcspReqResp(request, response) == 0)
08043                             break;
08044                         else if (idx == 1) /* server cert must be OK */
08045                             ret = BAD_CERTIFICATE_STATUS_ERROR;
08046                     }
08047 
08048                     *inOutIdx   += status_length;
08049                     list_length -= status_length;
08050                 }
08051             }
08052 
08053             #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
08054                 ssl->status_request_v2 = 0;
08055             #endif
08056 
08057             #ifdef WOLFSSL_SMALL_STACK
08058                 XFREE(status,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
08059                 XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08060             #endif
08061 
08062         }
08063         break;
08064 
08065     #endif
08066 
08067         default:
08068             ret = BUFFER_ERROR;
08069     }
08070 
08071     if (ret != 0)
08072         SendAlert(ssl, alert_fatal, bad_certificate_status_response);
08073 
08074     return ret;
08075 }
08076 
08077 #endif /* !NO_CERTS */
08078 
08079 
08080 static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
08081                                                     word32 size, word32 totalSz)
08082 {
08083     (void)input;
08084 
08085     if (size) /* must be 0 */
08086         return BUFFER_ERROR;
08087 
08088     if (IsEncryptionOn(ssl, 0)) {
08089         /* access beyond input + size should be checked against totalSz */
08090         if (*inOutIdx + ssl->keys.padSz > totalSz)
08091             return BUFFER_E;
08092 
08093         *inOutIdx += ssl->keys.padSz;
08094     }
08095 
08096     if (ssl->options.side == WOLFSSL_SERVER_END) {
08097         SendAlert(ssl, alert_fatal, unexpected_message); /* try */
08098         return FATAL_ERROR;
08099     }
08100 #ifdef HAVE_SECURE_RENEGOTIATION
08101     else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
08102         ssl->secure_renegotiation->startScr = 1;
08103         return 0;
08104     }
08105 #endif
08106     else {
08107         return SendAlert(ssl, alert_warning, no_renegotiation);
08108     }
08109 }
08110 
08111 
08112 int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
08113                                                       word32 totalSz, int sniff)
08114 {
08115     word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
08116 
08117     if (finishedSz != size)
08118         return BUFFER_ERROR;
08119 
08120     /* check against totalSz */
08121     if (*inOutIdx + size + ssl->keys.padSz > totalSz)
08122         return BUFFER_E;
08123 
08124     #ifdef WOLFSSL_CALLBACKS
08125         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
08126         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
08127     #endif
08128 
08129     if (sniff == NO_SNIFF) {
08130         if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
08131             WOLFSSL_MSG("Verify finished error on hashes");
08132             return VERIFY_FINISHED_ERROR;
08133         }
08134     }
08135 
08136 #ifdef HAVE_SECURE_RENEGOTIATION
08137     if (ssl->secure_renegotiation) {
08138         /* save peer's state */
08139         if (ssl->options.side == WOLFSSL_CLIENT_END)
08140             XMEMCPY(ssl->secure_renegotiation->server_verify_data,
08141                     input + *inOutIdx, TLS_FINISHED_SZ);
08142         else
08143             XMEMCPY(ssl->secure_renegotiation->client_verify_data,
08144                     input + *inOutIdx, TLS_FINISHED_SZ);
08145     }
08146 #endif
08147 
08148     /* force input exhaustion at ProcessReply consuming padSz */
08149     *inOutIdx += size + ssl->keys.padSz;
08150 
08151     if (ssl->options.side == WOLFSSL_CLIENT_END) {
08152         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
08153         if (!ssl->options.resuming) {
08154             ssl->options.handShakeState = HANDSHAKE_DONE;
08155             ssl->options.handShakeDone  = 1;
08156         }
08157     }
08158     else {
08159         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
08160         if (ssl->options.resuming) {
08161             ssl->options.handShakeState = HANDSHAKE_DONE;
08162             ssl->options.handShakeDone  = 1;
08163         }
08164     }
08165 
08166     return 0;
08167 }
08168 
08169 
08170 /* Make sure no duplicates, no fast forward, or other problems; 0 on success */
08171 static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
08172 {
08173     /* verify not a duplicate, mark received, check state */
08174     switch (type) {
08175 
08176 #ifndef NO_WOLFSSL_CLIENT
08177         case hello_request:
08178             if (ssl->msgsReceived.got_hello_request) {
08179                 WOLFSSL_MSG("Duplicate HelloRequest received");
08180                 return DUPLICATE_MSG_E;
08181             }
08182             ssl->msgsReceived.got_hello_request = 1;
08183 
08184             break;
08185 #endif
08186 
08187 #ifndef NO_WOLFSSL_SERVER
08188         case client_hello:
08189             if (ssl->msgsReceived.got_client_hello) {
08190                 WOLFSSL_MSG("Duplicate ClientHello received");
08191                 return DUPLICATE_MSG_E;
08192             }
08193             ssl->msgsReceived.got_client_hello = 1;
08194 
08195             break;
08196 #endif
08197 
08198 #ifndef NO_WOLFSSL_CLIENT
08199         case server_hello:
08200             if (ssl->msgsReceived.got_server_hello) {
08201                 WOLFSSL_MSG("Duplicate ServerHello received");
08202                 return DUPLICATE_MSG_E;
08203             }
08204             ssl->msgsReceived.got_server_hello = 1;
08205 
08206             break;
08207 #endif
08208 
08209 #ifndef NO_WOLFSSL_CLIENT
08210         case hello_verify_request:
08211             if (ssl->msgsReceived.got_hello_verify_request) {
08212                 WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
08213                 return DUPLICATE_MSG_E;
08214             }
08215             ssl->msgsReceived.got_hello_verify_request = 1;
08216 
08217             break;
08218 #endif
08219 
08220 #ifndef NO_WOLFSSL_CLIENT
08221         case session_ticket:
08222             if (ssl->msgsReceived.got_session_ticket) {
08223                 WOLFSSL_MSG("Duplicate SessionTicket received");
08224                 return DUPLICATE_MSG_E;
08225             }
08226             ssl->msgsReceived.got_session_ticket = 1;
08227 
08228             break;
08229 #endif
08230 
08231         case certificate:
08232             if (ssl->msgsReceived.got_certificate) {
08233                 WOLFSSL_MSG("Duplicate Certificate received");
08234                 return DUPLICATE_MSG_E;
08235             }
08236             ssl->msgsReceived.got_certificate = 1;
08237 
08238 #ifndef NO_WOLFSSL_CLIENT
08239             if (ssl->options.side == WOLFSSL_CLIENT_END) {
08240                 if ( ssl->msgsReceived.got_server_hello == 0) {
08241                     WOLFSSL_MSG("No ServerHello before Cert");
08242                     return OUT_OF_ORDER_E;
08243                 }
08244             }
08245 #endif
08246 #ifndef NO_WOLFSSL_SERVER
08247             if (ssl->options.side == WOLFSSL_SERVER_END) {
08248                 if ( ssl->msgsReceived.got_client_hello == 0) {
08249                     WOLFSSL_MSG("No ClientHello before Cert");
08250                     return OUT_OF_ORDER_E;
08251                 }
08252             }
08253 #endif
08254             break;
08255 
08256 #ifndef NO_WOLFSSL_CLIENT
08257         case certificate_status:
08258             if (ssl->msgsReceived.got_certificate_status) {
08259                 WOLFSSL_MSG("Duplicate CertificateSatatus received");
08260                 return DUPLICATE_MSG_E;
08261             }
08262             ssl->msgsReceived.got_certificate_status = 1;
08263 
08264             if (ssl->msgsReceived.got_certificate == 0) {
08265                 WOLFSSL_MSG("No Certificate before CertificateStatus");
08266                 return OUT_OF_ORDER_E;
08267             }
08268             if (ssl->msgsReceived.got_server_key_exchange != 0) {
08269                 WOLFSSL_MSG("CertificateStatus after ServerKeyExchange");
08270                 return OUT_OF_ORDER_E;
08271             }
08272 
08273             break;
08274 #endif
08275 
08276 #ifndef NO_WOLFSSL_CLIENT
08277         case server_key_exchange:
08278             if (ssl->msgsReceived.got_server_key_exchange) {
08279                 WOLFSSL_MSG("Duplicate ServerKeyExchange received");
08280                 return DUPLICATE_MSG_E;
08281             }
08282             ssl->msgsReceived.got_server_key_exchange = 1;
08283 
08284             if (ssl->msgsReceived.got_server_hello == 0) {
08285                 WOLFSSL_MSG("No ServerHello before ServerKeyExchange");
08286                 return OUT_OF_ORDER_E;
08287             }
08288             if (ssl->msgsReceived.got_certificate_status == 0) {
08289 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
08290                 if (ssl->status_request) {
08291                     int ret;
08292 
08293                     WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
08294                     if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0)
08295                         return ret;
08296                 }
08297 #endif
08298 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
08299                 if (ssl->status_request_v2) {
08300                     int ret;
08301 
08302                     WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
08303                     if ((ret = TLSX_CSR2_ForceRequest(ssl)) != 0)
08304                         return ret;
08305                 }
08306 #endif
08307             }
08308 
08309             break;
08310 #endif
08311 
08312 #ifndef NO_WOLFSSL_CLIENT
08313         case certificate_request:
08314             if (ssl->msgsReceived.got_certificate_request) {
08315                 WOLFSSL_MSG("Duplicate CertificateRequest received");
08316                 return DUPLICATE_MSG_E;
08317             }
08318             ssl->msgsReceived.got_certificate_request = 1;
08319 
08320             break;
08321 #endif
08322 
08323 #ifndef NO_WOLFSSL_CLIENT
08324         case server_hello_done:
08325             if (ssl->msgsReceived.got_server_hello_done) {
08326                 WOLFSSL_MSG("Duplicate ServerHelloDone received");
08327                 return DUPLICATE_MSG_E;
08328             }
08329             ssl->msgsReceived.got_server_hello_done = 1;
08330 
08331             if (ssl->msgsReceived.got_certificate == 0) {
08332                 if (ssl->specs.kea == psk_kea ||
08333                     ssl->specs.kea == dhe_psk_kea ||
08334                     ssl->specs.kea == ecdhe_psk_kea ||
08335                     ssl->options.usingAnon_cipher) {
08336                     WOLFSSL_MSG("No Cert required");
08337                 } else {
08338                     WOLFSSL_MSG("No Certificate before ServerHelloDone");
08339                     return OUT_OF_ORDER_E;
08340                 }
08341             }
08342             if (ssl->msgsReceived.got_server_key_exchange == 0) {
08343                 int pskNoServerHint = 0;  /* not required in this case */
08344 
08345                 #ifndef NO_PSK
08346                     if (ssl->specs.kea == psk_kea &&
08347                                                ssl->arrays->server_hint[0] == 0)
08348                         pskNoServerHint = 1;
08349                 #endif
08350                 if (ssl->specs.static_ecdh == 1 ||
08351                     ssl->specs.kea == rsa_kea ||
08352                     ssl->specs.kea == ntru_kea ||
08353                     pskNoServerHint) {
08354                     WOLFSSL_MSG("No KeyExchange required");
08355                 } else {
08356                     WOLFSSL_MSG("No ServerKeyExchange before ServerDone");
08357                     return OUT_OF_ORDER_E;
08358                 }
08359             }
08360             break;
08361 #endif
08362 
08363 #ifndef NO_WOLFSSL_SERVER
08364         case certificate_verify:
08365             if (ssl->msgsReceived.got_certificate_verify) {
08366                 WOLFSSL_MSG("Duplicate CertificateVerify received");
08367                 return DUPLICATE_MSG_E;
08368             }
08369             ssl->msgsReceived.got_certificate_verify = 1;
08370 
08371             if ( ssl->msgsReceived.got_certificate == 0) {
08372                 WOLFSSL_MSG("No Cert before CertVerify");
08373                 return OUT_OF_ORDER_E;
08374             }
08375             break;
08376 #endif
08377 
08378 #ifndef NO_WOLFSSL_SERVER
08379         case client_key_exchange:
08380             if (ssl->msgsReceived.got_client_key_exchange) {
08381                 WOLFSSL_MSG("Duplicate ClientKeyExchange received");
08382                 return DUPLICATE_MSG_E;
08383             }
08384             ssl->msgsReceived.got_client_key_exchange = 1;
08385 
08386             if (ssl->msgsReceived.got_client_hello == 0) {
08387                 WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
08388                 return OUT_OF_ORDER_E;
08389             }
08390             break;
08391 #endif
08392 
08393         case finished:
08394             if (ssl->msgsReceived.got_finished) {
08395                 WOLFSSL_MSG("Duplicate Finished received");
08396                 return DUPLICATE_MSG_E;
08397             }
08398             ssl->msgsReceived.got_finished = 1;
08399 
08400             if (ssl->msgsReceived.got_change_cipher == 0) {
08401                 WOLFSSL_MSG("Finished received before ChangeCipher");
08402                 return NO_CHANGE_CIPHER_E;
08403             }
08404             break;
08405 
08406         case change_cipher_hs:
08407             if (ssl->msgsReceived.got_change_cipher) {
08408                 WOLFSSL_MSG("Duplicate ChangeCipher received");
08409                 return DUPLICATE_MSG_E;
08410             }
08411             /* DTLS is going to ignore the CCS message if the client key
08412              * exchange message wasn't received yet. */
08413             if (!ssl->options.dtls)
08414                 ssl->msgsReceived.got_change_cipher = 1;
08415 
08416 #ifndef NO_WOLFSSL_CLIENT
08417             if (ssl->options.side == WOLFSSL_CLIENT_END) {
08418                 if (!ssl->options.resuming &&
08419                                  ssl->msgsReceived.got_server_hello_done == 0) {
08420                     WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
08421                     return OUT_OF_ORDER_E;
08422                 }
08423                 #ifdef HAVE_SESSION_TICKET
08424                     if (ssl->expect_session_ticket) {
08425                         WOLFSSL_MSG("Expected session ticket missing");
08426                         #ifdef WOLFSSL_DTLS
08427                             if (ssl->options.dtls)
08428                                 return OUT_OF_ORDER_E;
08429                         #endif
08430                         return SESSION_TICKET_EXPECT_E;
08431                     }
08432                 #endif
08433             }
08434 #endif
08435 #ifndef NO_WOLFSSL_SERVER
08436             if (ssl->options.side == WOLFSSL_SERVER_END) {
08437                 if (!ssl->options.resuming &&
08438                                ssl->msgsReceived.got_client_key_exchange == 0) {
08439                     WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
08440                     return OUT_OF_ORDER_E;
08441                 }
08442                 #ifndef NO_CERTS
08443                     if (ssl->options.verifyPeer &&
08444                         ssl->options.havePeerCert) {
08445 
08446                         if (!ssl->options.havePeerVerify) {
08447                             WOLFSSL_MSG("client didn't send cert verify");
08448                             #ifdef WOLFSSL_DTLS
08449                                 if (ssl->options.dtls)
08450                                     return OUT_OF_ORDER_E;
08451                             #endif
08452                             return NO_PEER_VERIFY;
08453                         }
08454                     }
08455                 #endif
08456             }
08457 #endif
08458             if (ssl->options.dtls)
08459                 ssl->msgsReceived.got_change_cipher = 1;
08460             break;
08461 
08462         default:
08463             WOLFSSL_MSG("Unknown message type");
08464             return SANITY_MSG_E;
08465     }
08466 
08467     return 0;
08468 }
08469 
08470 
08471 static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
08472                           byte type, word32 size, word32 totalSz)
08473 {
08474     int ret = 0;
08475     word32 expectedIdx;
08476 
08477     WOLFSSL_ENTER("DoHandShakeMsgType");
08478 
08479 #ifdef WOLFSSL_TLS13
08480     if (type == hello_retry_request) {
08481         return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
08482                                        totalSz);
08483     }
08484 #endif
08485 
08486     /* make sure can read the message */
08487     if (*inOutIdx + size > totalSz)
08488         return INCOMPLETE_DATA;
08489 
08490     expectedIdx = *inOutIdx + size +
08491                   (ssl->keys.encryptionOn ? ssl->keys.padSz : 0);
08492 
08493     /* sanity check msg received */
08494     if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
08495         WOLFSSL_MSG("Sanity Check on handshake message type received failed");
08496         return ret;
08497     }
08498 
08499 #ifdef WOLFSSL_CALLBACKS
08500     /* add name later, add on record and handshake header part back on */
08501     if (ssl->toInfoOn) {
08502         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08503         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
08504                       size + add, ssl->heap);
08505         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
08506     }
08507 #endif
08508 
08509     if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
08510         WOLFSSL_MSG("HandShake message after handshake complete");
08511         SendAlert(ssl, alert_fatal, unexpected_message);
08512         return OUT_OF_ORDER_E;
08513     }
08514 
08515     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
08516                ssl->options.serverState == NULL_STATE && type != server_hello) {
08517         WOLFSSL_MSG("First server message not server hello");
08518         SendAlert(ssl, alert_fatal, unexpected_message);
08519         return OUT_OF_ORDER_E;
08520     }
08521 
08522     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
08523             type == server_hello_done &&
08524             ssl->options.serverState < SERVER_HELLO_COMPLETE) {
08525         WOLFSSL_MSG("Server hello done received before server hello in DTLS");
08526         SendAlert(ssl, alert_fatal, unexpected_message);
08527         return OUT_OF_ORDER_E;
08528     }
08529 
08530     if (ssl->options.side == WOLFSSL_SERVER_END &&
08531                ssl->options.clientState == NULL_STATE && type != client_hello) {
08532         WOLFSSL_MSG("First client message not client hello");
08533         SendAlert(ssl, alert_fatal, unexpected_message);
08534         return OUT_OF_ORDER_E;
08535     }
08536 
08537     /* above checks handshake state */
08538     /* hello_request not hashed */
08539     /* Also, skip hashing the client_hello message here for DTLS. It will be
08540      * hashed later if the DTLS cookie is correct. */
08541     if (type != hello_request &&
08542             !(IsDtlsNotSctpMode(ssl) && type == client_hello) &&
08543             ssl->error != WC_PENDING_E) {
08544         ret = HashInput(ssl, input + *inOutIdx, size);
08545         if (ret != 0) return ret;
08546     }
08547 
08548     switch (type) {
08549 
08550     case hello_request:
08551         WOLFSSL_MSG("processing hello request");
08552         ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
08553         break;
08554 
08555 #ifndef NO_WOLFSSL_CLIENT
08556     case hello_verify_request:
08557         WOLFSSL_MSG("processing hello verify request");
08558         ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
08559         break;
08560 
08561     case server_hello:
08562         WOLFSSL_MSG("processing server hello");
08563         ret = DoServerHello(ssl, input, inOutIdx, size);
08564         break;
08565 
08566 #ifndef NO_CERTS
08567     case certificate_request:
08568         WOLFSSL_MSG("processing certificate request");
08569         ret = DoCertificateRequest(ssl, input, inOutIdx, size);
08570         break;
08571 #endif
08572 
08573     case server_key_exchange:
08574         WOLFSSL_MSG("processing server key exchange");
08575         ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
08576         break;
08577 
08578 #ifdef HAVE_SESSION_TICKET
08579     case session_ticket:
08580         WOLFSSL_MSG("processing session ticket");
08581         ret = DoSessionTicket(ssl, input, inOutIdx, size);
08582         break;
08583 #endif /* HAVE_SESSION_TICKET */
08584 #endif
08585 
08586 #ifndef NO_CERTS
08587     case certificate:
08588         WOLFSSL_MSG("processing certificate");
08589         ret = DoCertificate(ssl, input, inOutIdx, size);
08590         break;
08591 
08592     case certificate_status:
08593         WOLFSSL_MSG("processing certificate status");
08594         ret = DoCertificateStatus(ssl, input, inOutIdx, size);
08595         break;
08596 #endif
08597 
08598     case server_hello_done:
08599         WOLFSSL_MSG("processing server hello done");
08600     #ifdef WOLFSSL_CALLBACKS
08601         if (ssl->hsInfoOn)
08602             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
08603         if (ssl->toInfoOn)
08604             AddLateName("ServerHelloDone", &ssl->timeoutInfo);
08605     #endif
08606         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
08607         if (IsEncryptionOn(ssl, 0)) {
08608             *inOutIdx += ssl->keys.padSz;
08609         }
08610         if (ssl->options.resuming) {
08611             WOLFSSL_MSG("Not resuming as thought");
08612             ssl->options.resuming = 0;
08613         }
08614         break;
08615 
08616     case finished:
08617         WOLFSSL_MSG("processing finished");
08618         ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
08619         break;
08620 
08621 #ifndef NO_WOLFSSL_SERVER
08622     case client_hello:
08623         WOLFSSL_MSG("processing client hello");
08624         ret = DoClientHello(ssl, input, inOutIdx, size);
08625         break;
08626 
08627     case client_key_exchange:
08628         WOLFSSL_MSG("processing client key exchange");
08629         ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
08630         break;
08631 
08632 #if !defined(NO_RSA) || defined(HAVE_ECC)
08633     case certificate_verify:
08634         WOLFSSL_MSG("processing certificate verify");
08635         ret = DoCertificateVerify(ssl, input, inOutIdx, size);
08636         break;
08637 #endif /* !NO_RSA || HAVE_ECC */
08638 
08639 #endif /* !NO_WOLFSSL_SERVER */
08640 
08641     default:
08642         WOLFSSL_MSG("Unknown handshake message type");
08643         ret = UNKNOWN_HANDSHAKE_TYPE;
08644         break;
08645     }
08646 
08647     if (ret == 0 && expectedIdx != *inOutIdx) {
08648         WOLFSSL_MSG("Extra data in handshake message");
08649         if (!ssl->options.dtls)
08650             SendAlert(ssl, alert_fatal, decode_error);
08651         ret = DECODE_E;
08652     }
08653 
08654 #ifdef WOLFSSL_ASYNC_CRYPT
08655     /* if async, offset index so this msg will be processed again */
08656     if (ret == WC_PENDING_E) {
08657         *inOutIdx -= HANDSHAKE_HEADER_SZ;
08658     #ifdef WOLFSSL_DTLS
08659         if (ssl->options.dtls) {
08660             *inOutIdx -= DTLS_HANDSHAKE_EXTRA;
08661         }
08662     #endif
08663     }
08664 #endif
08665 
08666     WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
08667     return ret;
08668 }
08669 
08670 
08671 static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
08672                           word32 totalSz)
08673 {
08674     int    ret = 0;
08675     word32 inputLength;
08676 
08677     WOLFSSL_ENTER("DoHandShakeMsg()");
08678 
08679     if (ssl->arrays == NULL) {
08680         byte   type;
08681         word32 size;
08682 
08683         if (GetHandShakeHeader(ssl,input,inOutIdx,&type, &size, totalSz) != 0)
08684             return PARSE_ERROR;
08685 
08686         return DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
08687     }
08688 
08689     inputLength = ssl->buffers.inputBuffer.length - *inOutIdx;
08690 
08691     /* If there is a pending fragmented handshake message,
08692      * pending message size will be non-zero. */
08693     if (ssl->arrays->pendingMsgSz == 0) {
08694         byte   type;
08695         word32 size;
08696 
08697         if (GetHandShakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
08698             return PARSE_ERROR;
08699 
08700         /* Cap the maximum size of a handshake message to something reasonable.
08701          * By default is the maximum size of a certificate message assuming
08702          * nine 2048-bit RSA certificates in the chain. */
08703         if (size > MAX_HANDSHAKE_SZ) {
08704             WOLFSSL_MSG("Handshake message too large");
08705             return HANDSHAKE_SIZE_ERROR;
08706         }
08707 
08708         /* size is the size of the certificate message payload */
08709         if (inputLength - HANDSHAKE_HEADER_SZ < size) {
08710             ssl->arrays->pendingMsgType = type;
08711             ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
08712             ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
08713                                                      ssl->heap,
08714                                                      DYNAMIC_TYPE_ARRAYS);
08715             if (ssl->arrays->pendingMsg == NULL)
08716                 return MEMORY_E;
08717             XMEMCPY(ssl->arrays->pendingMsg,
08718                     input + *inOutIdx - HANDSHAKE_HEADER_SZ,
08719                     inputLength);
08720             ssl->arrays->pendingMsgOffset = inputLength;
08721             *inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
08722             return 0;
08723         }
08724 
08725         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
08726     }
08727     else {
08728         if (inputLength + ssl->arrays->pendingMsgOffset
08729                                                   > ssl->arrays->pendingMsgSz) {
08730 
08731             return BUFFER_ERROR;
08732         }
08733         else {
08734             XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
08735                     input + *inOutIdx, inputLength);
08736             ssl->arrays->pendingMsgOffset += inputLength;
08737             *inOutIdx += inputLength;
08738         }
08739 
08740         if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
08741         {
08742             word32 idx = 0;
08743             ret = DoHandShakeMsgType(ssl,
08744                                      ssl->arrays->pendingMsg
08745                                                           + HANDSHAKE_HEADER_SZ,
08746                                      &idx, ssl->arrays->pendingMsgType,
08747                                      ssl->arrays->pendingMsgSz
08748                                                           - HANDSHAKE_HEADER_SZ,
08749                                      ssl->arrays->pendingMsgSz);
08750             XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
08751             ssl->arrays->pendingMsg = NULL;
08752             ssl->arrays->pendingMsgSz = 0;
08753         }
08754     }
08755 
08756     WOLFSSL_LEAVE("DoHandShakeMsg()", ret);
08757     return ret;
08758 }
08759 
08760 #ifdef WOLFSSL_DTLS
08761 
08762 static INLINE int DtlsCheckWindow(WOLFSSL* ssl)
08763 {
08764     word32* window;
08765     word16 cur_hi, next_hi;
08766     word32 cur_lo, next_lo, diff;
08767     int curLT;
08768 
08769     if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
08770         next_hi = ssl->keys.nextSeq_hi;
08771         next_lo = ssl->keys.nextSeq_lo;
08772         window = ssl->keys.window;
08773     }
08774     else if (ssl->keys.curEpoch == ssl->keys.nextEpoch - 1) {
08775         next_hi = ssl->keys.prevSeq_hi;
08776         next_lo = ssl->keys.prevSeq_lo;
08777         window = ssl->keys.prevWindow;
08778     }
08779     else {
08780         return 0;
08781     }
08782 
08783     cur_hi = ssl->keys.curSeq_hi;
08784     cur_lo = ssl->keys.curSeq_lo;
08785 
08786     /* If the difference between next and cur is > 2^32, way outside window. */
08787     if ((cur_hi > next_hi + 1) || (next_hi > cur_hi + 1)) {
08788         WOLFSSL_MSG("Current record from way too far in the future.");
08789         return 0;
08790     }
08791 
08792     if (cur_hi == next_hi) {
08793         curLT = cur_lo < next_lo;
08794         diff = curLT ? next_lo - cur_lo : cur_lo - next_lo;
08795     }
08796     else {
08797         curLT = cur_hi < next_hi;
08798         diff = curLT ? cur_lo - next_lo : next_lo - cur_lo;
08799     }
08800 
08801     /* Check to see that the next value is greater than the number of messages
08802      * trackable in the window, and that the difference between the next
08803      * expected sequence number and the received sequence number is inside the
08804      * window. */
08805     if ((next_hi || next_lo > DTLS_SEQ_BITS) &&
08806         curLT && (diff > DTLS_SEQ_BITS)) {
08807 
08808         WOLFSSL_MSG("Current record sequence number from the past.");
08809         return 0;
08810     }
08811     else if (!curLT && (diff > DTLS_SEQ_BITS)) {
08812         WOLFSSL_MSG("Rejecting message too far into the future.");
08813         return 0;
08814     }
08815     else if (curLT) {
08816         word32 idx = diff / DTLS_WORD_BITS;
08817         word32 newDiff = diff % DTLS_WORD_BITS;
08818 
08819         /* verify idx is valid for window array */
08820         if (idx >= WOLFSSL_DTLS_WINDOW_WORDS) {
08821             WOLFSSL_MSG("Invalid DTLS windows index");
08822             return 0;
08823         }
08824 
08825         if (window[idx] & (1 << (newDiff - 1))) {
08826             WOLFSSL_MSG("Current record sequence number already received.");
08827             return 0;
08828         }
08829     }
08830 
08831     return 1;
08832 }
08833 
08834 
08835 static INLINE int DtlsUpdateWindow(WOLFSSL* ssl)
08836 {
08837     word32* window;
08838     word32* next_lo;
08839     word16* next_hi;
08840     int curLT;
08841     word32 cur_lo, diff;
08842     word16 cur_hi;
08843 
08844     if (ssl->keys.curEpoch == ssl->keys.nextEpoch) {
08845         next_hi = &ssl->keys.nextSeq_hi;
08846         next_lo = &ssl->keys.nextSeq_lo;
08847         window = ssl->keys.window;
08848     }
08849     else {
08850         next_hi = &ssl->keys.prevSeq_hi;
08851         next_lo = &ssl->keys.prevSeq_lo;
08852         window = ssl->keys.prevWindow;
08853     }
08854 
08855     cur_hi = ssl->keys.curSeq_hi;
08856     cur_lo = ssl->keys.curSeq_lo;
08857 
08858     if (cur_hi == *next_hi) {
08859         curLT = cur_lo < *next_lo;
08860         diff = curLT ? *next_lo - cur_lo : cur_lo - *next_lo;
08861     }
08862     else {
08863         curLT = cur_hi < *next_hi;
08864         diff = curLT ? cur_lo - *next_lo : *next_lo - cur_lo;
08865     }
08866 
08867     if (curLT) {
08868         word32 idx = diff / DTLS_WORD_BITS;
08869         word32 newDiff = diff % DTLS_WORD_BITS;
08870 
08871         if (idx < WOLFSSL_DTLS_WINDOW_WORDS)
08872             window[idx] |= (1 << (newDiff - 1));
08873     }
08874     else {
08875         if (diff >= DTLS_SEQ_BITS)
08876             XMEMSET(window, 0, DTLS_SEQ_SZ);
08877         else {
08878             word32 idx, newDiff, temp, i;
08879             word32 oldWindow[WOLFSSL_DTLS_WINDOW_WORDS];
08880 
08881             temp = 0;
08882             diff++;
08883             idx = diff / DTLS_WORD_BITS;
08884             newDiff = diff % DTLS_WORD_BITS;
08885 
08886             XMEMCPY(oldWindow, window, sizeof(oldWindow));
08887 
08888             for (i = 0; i < WOLFSSL_DTLS_WINDOW_WORDS; i++) {
08889                 if (i < idx)
08890                     window[i] = 0;
08891                 else {
08892                     temp |= (oldWindow[i-idx] << newDiff);
08893                     window[i] = temp;
08894                     temp = oldWindow[i-idx] >> (DTLS_WORD_BITS - newDiff);
08895                 }
08896             }
08897         }
08898         window[0] |= 1;
08899         *next_lo = cur_lo + 1;
08900         if (*next_lo < cur_lo)
08901             (*next_hi)++;
08902     }
08903 
08904     return 1;
08905 }
08906 
08907 
08908 static int DtlsMsgDrain(WOLFSSL* ssl)
08909 {
08910     DtlsMsg* item = ssl->dtls_rx_msg_list;
08911     int ret = 0;
08912 
08913     /* While there is an item in the store list, and it is the expected
08914      * message, and it is complete, and there hasn't been an error in the
08915      * last messge... */
08916     while (item != NULL &&
08917             ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
08918             item->fragSz == item->sz &&
08919             ret == 0) {
08920         word32 idx = 0;
08921         ssl->keys.dtls_expected_peer_handshake_number++;
08922         ret = DoHandShakeMsgType(ssl, item->msg,
08923                                  &idx, item->type, item->sz, item->sz);
08924         ssl->dtls_rx_msg_list = item->next;
08925         DtlsMsgDelete(item, ssl->heap);
08926         item = ssl->dtls_rx_msg_list;
08927         ssl->dtls_rx_msg_list_sz--;
08928     }
08929 
08930     return ret;
08931 }
08932 
08933 
08934 static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
08935                           word32 totalSz)
08936 {
08937     byte type;
08938     word32 size;
08939     word32 fragOffset, fragSz;
08940     int ret = 0;
08941 
08942     WOLFSSL_ENTER("DoDtlsHandShakeMsg()");
08943     if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
08944                                &size, &fragOffset, &fragSz, totalSz) != 0)
08945         return PARSE_ERROR;
08946 
08947     if (*inOutIdx + fragSz > totalSz)
08948         return INCOMPLETE_DATA;
08949 
08950     /* Check the handshake sequence number first. If out of order,
08951      * add the current message to the list. If the message is in order,
08952      * but it is a fragment, add the current message to the list, then
08953      * check the head of the list to see if it is complete, if so, pop
08954      * it out as the current message. If the message is complete and in
08955      * order, process it. Check the head of the list to see if it is in
08956      * order, if so, process it. (Repeat until list exhausted.) If the
08957      * head is out of order, return for more processing.
08958      */
08959     if (ssl->keys.dtls_peer_handshake_number >
08960                                 ssl->keys.dtls_expected_peer_handshake_number) {
08961         /* Current message is out of order. It will get stored in the list.
08962          * Storing also takes care of defragmentation. If the messages is a
08963          * client hello, we need to process this out of order; the server
08964          * is not supposed to keep state, but the second client hello will
08965          * have a different handshake sequence number than is expected, and
08966          * the server shouldn't be expecting any particular handshake sequence
08967          * number. (If the cookie changes multiple times in quick succession,
08968          * the client could be sending multiple new client hello messages
08969          * with newer and newer cookies.) */
08970         if (type != client_hello) {
08971             if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
08972                 DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
08973                              input + *inOutIdx, size, type,
08974                              fragOffset, fragSz, ssl->heap);
08975             }
08976             *inOutIdx += fragSz;
08977             ret = 0;
08978         }
08979         else {
08980             ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
08981             if (ret == 0) {
08982                 ssl->keys.dtls_expected_peer_handshake_number =
08983                     ssl->keys.dtls_peer_handshake_number + 1;
08984             }
08985         }
08986     }
08987     else if (ssl->keys.dtls_peer_handshake_number <
08988                                 ssl->keys.dtls_expected_peer_handshake_number) {
08989         /* Already saw this message and processed it. It can be ignored. */
08990         *inOutIdx += fragSz;
08991         if(type == finished ) {
08992             if (*inOutIdx + ssl->keys.padSz > totalSz) {
08993                 return BUFFER_E;
08994             }
08995             *inOutIdx += ssl->keys.padSz;
08996         }
08997         if (IsDtlsNotSctpMode(ssl) &&
08998             VerifyForDtlsMsgPoolSend(ssl, type, fragOffset)) {
08999 
09000             ret = DtlsMsgPoolSend(ssl, 0);
09001         }
09002     }
09003     else if (fragSz < size) {
09004         /* Since this branch is in order, but fragmented, dtls_rx_msg_list will
09005          * be pointing to the message with this fragment in it. Check it to see
09006          * if it is completed. */
09007         if (ssl->dtls_rx_msg_list_sz < DTLS_POOL_SZ) {
09008             DtlsMsgStore(ssl, ssl->keys.dtls_peer_handshake_number,
09009                          input + *inOutIdx, size, type,
09010                          fragOffset, fragSz, ssl->heap);
09011         }
09012         *inOutIdx += fragSz;
09013         ret = 0;
09014         if (ssl->dtls_rx_msg_list != NULL &&
09015             ssl->dtls_rx_msg_list->fragSz >= ssl->dtls_rx_msg_list->sz)
09016             ret = DtlsMsgDrain(ssl);
09017     }
09018     else {
09019         /* This branch is in order next, and a complete message. */
09020         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
09021         if (ret == 0) {
09022             if (type != client_hello || !IsDtlsNotSctpMode(ssl))
09023                 ssl->keys.dtls_expected_peer_handshake_number++;
09024             if (ssl->dtls_rx_msg_list != NULL) {
09025                 ret = DtlsMsgDrain(ssl);
09026             }
09027         }
09028     }
09029 
09030     WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret);
09031     return ret;
09032 }
09033 #endif
09034 
09035 
09036 #ifdef HAVE_AEAD
09037 static INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
09038 {
09039     int i;
09040     for (i = AEAD_MAX_EXP_SZ-1; i >= 0; i--) {
09041         if (++ssl->keys.aead_exp_IV[i]) return;
09042     }
09043 }
09044 
09045 
09046 #if defined(HAVE_POLY1305) && defined(HAVE_CHACHA)
09047 /* Used for the older version of creating AEAD tags with Poly1305 */
09048 static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
09049                        byte* cipher, word16 sz, byte* tag)
09050 {
09051     int ret       = 0;
09052     int msglen    = (sz - ssl->specs.aead_mac_size);
09053     word32 keySz  = 32;
09054     byte padding[8]; /* used to temporarily store lengths */
09055 
09056 #ifdef CHACHA_AEAD_TEST
09057       printf("Using old version of poly1305 input.\n");
09058 #endif
09059 
09060     if (msglen < 0)
09061         return INPUT_CASE_ERROR;
09062 
09063     if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
09064         return ret;
09065 
09066     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
09067                    AEAD_AUTH_DATA_SZ)) != 0)
09068         return ret;
09069 
09070     /* length of additional input plus padding */
09071     XMEMSET(padding, 0, sizeof(padding));
09072     padding[0] = AEAD_AUTH_DATA_SZ;
09073     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding,
09074                     sizeof(padding))) != 0)
09075         return ret;
09076 
09077 
09078     /* add cipher info and then its length */
09079     XMEMSET(padding, 0, sizeof(padding));
09080     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
09081         return ret;
09082 
09083     /* 32 bit size of cipher to 64 bit endian */
09084     padding[0] =  msglen        & 0xff;
09085     padding[1] = (msglen >>  8) & 0xff;
09086     padding[2] = (msglen >> 16) & 0xff;
09087     padding[3] = (msglen >> 24) & 0xff;
09088     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
09089         != 0)
09090         return ret;
09091 
09092     /* generate tag */
09093     if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
09094         return ret;
09095 
09096     return ret;
09097 }
09098 
09099 
09100 /* When the flag oldPoly is not set this follows RFC7905. When oldPoly is set
09101  * the implmentation follows an older draft for creating the nonce and MAC.
09102  * The flag oldPoly gets set automaticlly depending on what cipher suite was
09103  * negotiated in the handshake. This is able to be done because the IDs for the
09104  * cipher suites was updated in RFC7905 giving unique values for the older
09105  * draft in comparision to the more recent RFC.
09106  *
09107  * ssl   WOLFSSL structure to get cipher and TLS state from
09108  * out   output buffer to hold encrypted data
09109  * input data to encrypt
09110  * sz    size of input
09111  *
09112  * Return 0 on success negative values in error case
09113  */
09114 static int  ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
09115                               word16 sz)
09116 {
09117     const byte* additionalSrc = input - RECORD_HEADER_SZ;
09118     int ret       = 0;
09119     word32 msgLen = (sz - ssl->specs.aead_mac_size);
09120     byte tag[POLY1305_AUTH_SZ];
09121     byte add[AEAD_AUTH_DATA_SZ];
09122     byte nonce[CHACHA20_NONCE_SZ];
09123     byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
09124     #ifdef CHACHA_AEAD_TEST
09125         int i;
09126     #endif
09127 
09128     XMEMSET(tag,   0, sizeof(tag));
09129     XMEMSET(nonce, 0, sizeof(nonce));
09130     XMEMSET(poly,  0, sizeof(poly));
09131     XMEMSET(add,   0, sizeof(add));
09132 
09133     /* opaque SEQ number stored for AD */
09134     WriteSEQ(ssl, CUR_ORDER, add);
09135 
09136     if (ssl->options.oldPoly != 0) {
09137         /* get nonce. SEQ should not be incremented again here */
09138         XMEMCPY(nonce + CHACHA20_OLD_OFFSET, add, OPAQUE32_LEN * 2);
09139     }
09140 
09141     /* Store the type, version. Unfortunately, they are in
09142      * the input buffer ahead of the plaintext. */
09143     #ifdef WOLFSSL_DTLS
09144         if (ssl->options.dtls) {
09145             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
09146             DtlsSEQIncrement(ssl, CUR_ORDER);
09147         }
09148     #endif
09149 
09150     /* add TLS message size to additional data */
09151     add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
09152     add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
09153 
09154     XMEMCPY(add + AEAD_TYPE_OFFSET, additionalSrc, 3);
09155 
09156     #ifdef CHACHA_AEAD_TEST
09157         printf("Encrypt Additional : ");
09158         for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
09159             printf("%02x", add[i]);
09160         }
09161         printf("\n\n");
09162         printf("input before encryption :\n");
09163         for (i = 0; i < sz; i++) {
09164             printf("%02x", input[i]);
09165             if ((i + 1) % 16 == 0)
09166                 printf("\n");
09167         }
09168         printf("\n");
09169     #endif
09170 
09171     if (ssl->options.oldPoly == 0) {
09172         /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
09173          * record sequence number XORed with client_write_IV/server_write_IV */
09174         XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, CHACHA20_IMP_IV_SZ);
09175         nonce[4]  ^= add[0];
09176         nonce[5]  ^= add[1];
09177         nonce[6]  ^= add[2];
09178         nonce[7]  ^= add[3];
09179         nonce[8]  ^= add[4];
09180         nonce[9]  ^= add[5];
09181         nonce[10] ^= add[6];
09182         nonce[11] ^= add[7];
09183     }
09184 
09185     /* set the nonce for chacha and get poly1305 key */
09186     if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) {
09187         ForceZero(nonce, CHACHA20_NONCE_SZ);
09188         return ret;
09189     }
09190 
09191     ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
09192     /* create Poly1305 key using chacha20 keystream */
09193     if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, poly,
09194                                                       poly, sizeof(poly))) != 0)
09195         return ret;
09196 
09197     /* encrypt the plain text */
09198     if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out,
09199                                                          input, msgLen)) != 0) {
09200         ForceZero(poly, sizeof(poly));
09201         return ret;
09202     }
09203 
09204     /* get the poly1305 tag using either old padding scheme or more recent */
09205     if (ssl->options.oldPoly != 0) {
09206         if ((ret = Poly1305TagOld(ssl, add, (const byte* )out,
09207                                                          poly, sz, tag)) != 0) {
09208             ForceZero(poly, sizeof(poly));
09209             return ret;
09210         }
09211     }
09212     else {
09213         if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
09214                                                           sizeof(poly))) != 0) {
09215             ForceZero(poly, sizeof(poly));
09216             return ret;
09217         }
09218         if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
09219                             sizeof(add), out, msgLen, tag, sizeof(tag))) != 0) {
09220             ForceZero(poly, sizeof(poly));
09221             return ret;
09222         }
09223     }
09224     ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
09225 
09226     /* append tag to ciphertext */
09227     XMEMCPY(out + msgLen, tag, sizeof(tag));
09228 
09229     AeadIncrementExpIV(ssl);
09230 
09231     #ifdef CHACHA_AEAD_TEST
09232        printf("mac tag :\n");
09233         for (i = 0; i < 16; i++) {
09234            printf("%02x", tag[i]);
09235            if ((i + 1) % 16 == 0)
09236                printf("\n");
09237         }
09238        printf("\n\noutput after encrypt :\n");
09239         for (i = 0; i < sz; i++) {
09240            printf("%02x", out[i]);
09241            if ((i + 1) % 16 == 0)
09242                printf("\n");
09243         }
09244         printf("\n");
09245     #endif
09246 
09247     return ret;
09248 }
09249 
09250 
09251 /* When the flag oldPoly is not set this follows RFC7905. When oldPoly is set
09252  * the implmentation follows an older draft for creating the nonce and MAC.
09253  * The flag oldPoly gets set automaticlly depending on what cipher suite was
09254  * negotiated in the handshake. This is able to be done because the IDs for the
09255  * cipher suites was updated in RFC7905 giving unique values for the older
09256  * draft in comparision to the more recent RFC.
09257  *
09258  * ssl   WOLFSSL structure to get cipher and TLS state from
09259  * plain output buffer to hold decrypted data
09260  * input data to decrypt
09261  * sz    size of input
09262  *
09263  * Return 0 on success negative values in error case
09264  */
09265 static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
09266                            word16 sz)
09267 {
09268     byte add[AEAD_AUTH_DATA_SZ];
09269     byte nonce[CHACHA20_NONCE_SZ];
09270     byte tag[POLY1305_AUTH_SZ];
09271     byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
09272     int ret    = 0;
09273     int msgLen = (sz - ssl->specs.aead_mac_size);
09274 
09275     #ifdef CHACHA_AEAD_TEST
09276        int i;
09277        printf("input before decrypt :\n");
09278         for (i = 0; i < sz; i++) {
09279            printf("%02x", input[i]);
09280            if ((i + 1) % 16 == 0)
09281                printf("\n");
09282         }
09283         printf("\n");
09284     #endif
09285 
09286     XMEMSET(tag,   0, sizeof(tag));
09287     XMEMSET(poly,  0, sizeof(poly));
09288     XMEMSET(nonce, 0, sizeof(nonce));
09289     XMEMSET(add,   0, sizeof(add));
09290 
09291     /* sequence number field is 64-bits */
09292     WriteSEQ(ssl, PEER_ORDER, add);
09293 
09294     if (ssl->options.oldPoly != 0) {
09295         /* get nonce, SEQ should not be incremented again here */
09296         XMEMCPY(nonce + CHACHA20_OLD_OFFSET, add, OPAQUE32_LEN * 2);
09297     }
09298 
09299     /* get AD info */
09300     /* Store the type, version. */
09301     add[AEAD_TYPE_OFFSET] = ssl->curRL.type;
09302     add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
09303     add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
09304 
09305     /* add TLS message size to additional data */
09306     add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
09307     add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
09308 
09309     #ifdef CHACHA_AEAD_TEST
09310         printf("Decrypt Additional : ");
09311         for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
09312             printf("%02x", add[i]);
09313         }
09314         printf("\n\n");
09315     #endif
09316 
09317     if (ssl->options.oldPoly == 0) {
09318         /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
09319          * record sequence number XORed with client_write_IV/server_write_IV */
09320         XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, CHACHA20_IMP_IV_SZ);
09321         nonce[4]  ^= add[0];
09322         nonce[5]  ^= add[1];
09323         nonce[6]  ^= add[2];
09324         nonce[7]  ^= add[3];
09325         nonce[8]  ^= add[4];
09326         nonce[9]  ^= add[5];
09327         nonce[10] ^= add[6];
09328         nonce[11] ^= add[7];
09329     }
09330 
09331     /* set nonce and get poly1305 key */
09332     if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) {
09333         ForceZero(nonce, CHACHA20_NONCE_SZ);
09334         return ret;
09335     }
09336 
09337     ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
09338     /* use chacha20 keystream to get poly1305 key for tag */
09339     if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, poly,
09340                                                       poly, sizeof(poly))) != 0)
09341         return ret;
09342 
09343     /* get the tag using Poly1305 */
09344     if (ssl->options.oldPoly != 0) {
09345         if ((ret = Poly1305TagOld(ssl, add, input, poly, sz, tag)) != 0) {
09346             ForceZero(poly, sizeof(poly));
09347             return ret;
09348         }
09349     }
09350     else {
09351         if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
09352                                                           sizeof(poly))) != 0) {
09353             ForceZero(poly, sizeof(poly));
09354             return ret;
09355         }
09356         if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
09357                    sizeof(add), (byte*)input, msgLen, tag, sizeof(tag))) != 0) {
09358             ForceZero(poly, sizeof(poly));
09359             return ret;
09360         }
09361     }
09362     ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
09363 
09364     /* check tag sent along with packet */
09365     if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) {
09366         WOLFSSL_MSG("MAC did not match");
09367         if (!ssl->options.dtls)
09368             SendAlert(ssl, alert_fatal, bad_record_mac);
09369         return VERIFY_MAC_ERROR;
09370     }
09371 
09372     /* if the tag was good decrypt message */
09373     if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain,
09374                                                            input, msgLen)) != 0)
09375         return ret;
09376 
09377     #ifdef CHACHA_AEAD_TEST
09378        printf("plain after decrypt :\n");
09379         for (i = 0; i < sz; i++) {
09380            printf("%02x", plain[i]);
09381            if ((i + 1) % 16 == 0)
09382                printf("\n");
09383         }
09384         printf("\n");
09385     #endif
09386 
09387     return ret;
09388 }
09389 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
09390 #endif /* HAVE_AEAD */
09391 
09392 
09393 static INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input,
09394     word16 sz, int asyncOkay)
09395 {
09396     int ret = 0;
09397 #ifdef WOLFSSL_ASYNC_CRYPT
09398     WC_ASYNC_DEV* asyncDev = NULL;
09399     word32 event_flags = WC_ASYNC_FLAG_CALL_AGAIN;
09400 #else
09401     (void)asyncOkay;
09402 #endif
09403 
09404     (void)out;
09405     (void)input;
09406     (void)sz;
09407 
09408     switch (ssl->specs.bulk_cipher_algorithm) {
09409     #ifdef BUILD_ARC4
09410         case wolfssl_rc4:
09411             wc_Arc4Process(ssl->encrypt.arc4, out, input, sz);
09412             break;
09413     #endif
09414 
09415     #ifdef BUILD_DES3
09416         case wolfssl_triple_des:
09417             ret = wc_Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
09418         #ifdef WOLFSSL_ASYNC_CRYPT
09419             if (ret == WC_PENDING_E) {
09420                 asyncDev = &ssl->encrypt.des3->asyncDev;
09421                 if (asyncOkay)
09422                     ret = wolfSSL_AsyncPush(ssl, asyncDev, event_flags);
09423             }
09424         #endif
09425             break;
09426     #endif
09427 
09428     #ifdef BUILD_AES
09429         case wolfssl_aes:
09430             ret = wc_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
09431         #ifdef WOLFSSL_ASYNC_CRYPT
09432             if (ret == WC_PENDING_E) {
09433                 asyncDev = &ssl->encrypt.aes->asyncDev;
09434                 if (asyncOkay)
09435                     ret = wolfSSL_AsyncPush(ssl, asyncDev, event_flags);
09436                 break;
09437             }
09438         #endif
09439             break;
09440     #endif
09441 
09442     #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09443         case wolfssl_aes_gcm:
09444         case wolfssl_aes_ccm:/* GCM AEAD macros use same size as CCM */
09445         {
09446             wc_AesAuthEncryptFunc aes_auth_fn;
09447             const byte* additionalSrc;
09448         #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM)
09449             aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
09450                             ? wc_AesGcmEncrypt : wc_AesCcmEncrypt;
09451         #elif defined(BUILD_AESGCM)
09452             aes_auth_fn = wc_AesGcmEncrypt;
09453         #else
09454             aes_auth_fn = wc_AesCcmEncrypt;
09455         #endif
09456             additionalSrc = input - 5;
09457 
09458             XMEMSET(ssl->encrypt.additional, 0, AEAD_AUTH_DATA_SZ);
09459 
09460             /* sequence number field is 64-bits */
09461             WriteSEQ(ssl, CUR_ORDER, ssl->encrypt.additional);
09462 
09463             /* Store the type, version. Unfortunately, they are in
09464              * the input buffer ahead of the plaintext. */
09465         #ifdef WOLFSSL_DTLS
09466             if (ssl->options.dtls) {
09467                 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
09468             }
09469         #endif
09470             XMEMCPY(ssl->encrypt.additional + AEAD_TYPE_OFFSET,
09471                                                         additionalSrc, 3);
09472 
09473             /* Store the length of the plain text minus the explicit
09474              * IV length minus the authentication tag size. */
09475             c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
09476                                 ssl->encrypt.additional + AEAD_LEN_OFFSET);
09477             XMEMCPY(ssl->encrypt.nonce,
09478                                 ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ);
09479             XMEMCPY(ssl->encrypt.nonce + AESGCM_IMP_IV_SZ,
09480                                 ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
09481             ret = aes_auth_fn(ssl->encrypt.aes,
09482                     out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
09483                     sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
09484                     ssl->encrypt.nonce, AESGCM_NONCE_SZ,
09485                     out + sz - ssl->specs.aead_mac_size,
09486                     ssl->specs.aead_mac_size,
09487                     ssl->encrypt.additional, AEAD_AUTH_DATA_SZ);
09488         #ifdef WOLFSSL_ASYNC_CRYPT
09489             if (ret == WC_PENDING_E) {
09490                 asyncDev = &ssl->encrypt.aes->asyncDev;
09491                 if (asyncOkay)
09492                     ret = wolfSSL_AsyncPush(ssl, asyncDev, event_flags);
09493             }
09494         #endif
09495         }
09496         break;
09497     #endif /* BUILD_AESGCM || HAVE_AESCCM */
09498 
09499     #ifdef HAVE_CAMELLIA
09500         case wolfssl_camellia:
09501             wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
09502             break;
09503     #endif
09504 
09505     #ifdef HAVE_HC128
09506         case wolfssl_hc128:
09507             ret = wc_Hc128_Process(ssl->encrypt.hc128, out, input, sz);
09508             break;
09509     #endif
09510 
09511     #ifdef BUILD_RABBIT
09512         case wolfssl_rabbit:
09513             ret = wc_RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
09514             break;
09515     #endif
09516 
09517     #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
09518         case wolfssl_chacha:
09519             ret = ChachaAEADEncrypt(ssl, out, input, sz);
09520             break;
09521     #endif
09522 
09523     #ifdef HAVE_NULL_CIPHER
09524         case wolfssl_cipher_null:
09525             if (input != out) {
09526                 XMEMMOVE(out, input, sz);
09527             }
09528             break;
09529     #endif
09530 
09531     #ifdef HAVE_IDEA
09532         case wolfssl_idea:
09533             ret = wc_IdeaCbcEncrypt(ssl->encrypt.idea, out, input, sz);
09534             break;
09535     #endif
09536 
09537         default:
09538             WOLFSSL_MSG("wolfSSL Encrypt programming error");
09539             ret = ENCRYPT_ERROR;
09540     }
09541 
09542 #ifdef WOLFSSL_ASYNC_CRYPT
09543     /* if async is not okay, then block */
09544     if (ret == WC_PENDING_E && !asyncOkay) {
09545         ret = wc_AsyncWait(ret, asyncDev, event_flags);
09546     }
09547 #endif
09548 
09549     return ret;
09550 }
09551 
09552 static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz,
09553     int asyncOkay)
09554 {
09555     int ret = 0;
09556 
09557 #ifdef WOLFSSL_ASYNC_CRYPT
09558     if (asyncOkay && ssl->error == WC_PENDING_E) {
09559         ssl->error = 0; /* clear async */
09560     }
09561 #endif
09562 
09563     switch (ssl->encrypt.state) {
09564         case CIPHER_STATE_BEGIN:
09565         {
09566             if (ssl->encrypt.setup == 0) {
09567                 WOLFSSL_MSG("Encrypt ciphers not setup");
09568                 return ENCRYPT_ERROR;
09569             }
09570 
09571         #ifdef HAVE_FUZZER
09572             if (ssl->fuzzerCb)
09573                 ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
09574         #endif
09575 
09576         #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09577             /* make sure AES GCM/CCM memory is allocated */
09578             /* free for these happens in FreeCiphers */
09579             if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
09580                 ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
09581                 /* make sure auth iv and auth are allocated */
09582                 if (ssl->encrypt.additional == NULL)
09583                     ssl->encrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ,
09584                                                    ssl->heap, DYNAMIC_TYPE_AES);
09585                 if (ssl->encrypt.nonce == NULL)
09586                     ssl->encrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ,
09587                                                    ssl->heap, DYNAMIC_TYPE_AES);
09588                 if (ssl->encrypt.additional == NULL ||
09589                          ssl->encrypt.nonce == NULL) {
09590                     return MEMORY_E;
09591                 }
09592             }
09593         #endif /* BUILD_AESGCM || HAVE_AESCCM */
09594 
09595             /* Advance state and proceed */
09596             ssl->encrypt.state = CIPHER_STATE_DO;
09597         }
09598         case CIPHER_STATE_DO:
09599         {
09600             ret = EncryptDo(ssl, out, input, sz, asyncOkay);
09601 
09602             /* Advance state */
09603             ssl->encrypt.state = CIPHER_STATE_END;
09604 
09605         #ifdef WOLFSSL_ASYNC_CRYPT
09606             /* If pending, then leave and return will resume below */
09607             if (ret == WC_PENDING_E) {
09608                 return ret;
09609             }
09610         #endif
09611         }
09612 
09613         case CIPHER_STATE_END:
09614         {
09615         #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09616             if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
09617                 ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
09618             {
09619                 /* finalize authentication cipher */
09620                 AeadIncrementExpIV(ssl);
09621 
09622                 if (ssl->encrypt.nonce)
09623                     ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ);
09624 
09625             #ifdef WOLFSSL_DTLS
09626                 if (ssl->options.dtls)
09627                     DtlsSEQIncrement(ssl, CUR_ORDER);
09628             #endif
09629             }
09630         #endif /* BUILD_AESGCM || HAVE_AESCCM */
09631             break;
09632         }
09633     }
09634 
09635     /* Reset state */
09636     ssl->encrypt.state = CIPHER_STATE_BEGIN;
09637 
09638     return ret;
09639 }
09640 
09641 static INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input,
09642                            word16 sz)
09643 {
09644     int ret = 0;
09645 
09646     (void)plain;
09647     (void)input;
09648     (void)sz;
09649 
09650     switch (ssl->specs.bulk_cipher_algorithm)
09651     {
09652     #ifdef BUILD_ARC4
09653         case wolfssl_rc4:
09654             wc_Arc4Process(ssl->decrypt.arc4, plain, input, sz);
09655             break;
09656     #endif
09657 
09658     #ifdef BUILD_DES3
09659         case wolfssl_triple_des:
09660             ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
09661         #ifdef WOLFSSL_ASYNC_CRYPT
09662             if (ret == WC_PENDING_E) {
09663                 ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.des3->asyncDev,
09664                                                     WC_ASYNC_FLAG_CALL_AGAIN);
09665             }
09666         #endif
09667             break;
09668     #endif
09669 
09670     #ifdef BUILD_AES
09671         case wolfssl_aes:
09672             ret = wc_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
09673         #ifdef WOLFSSL_ASYNC_CRYPT
09674             if (ret == WC_PENDING_E) {
09675                 ret = wolfSSL_AsyncPush(ssl, &ssl->decrypt.aes->asyncDev,
09676                                                     WC_ASYNC_FLAG_CALL_AGAIN);
09677             }
09678         #endif
09679             break;
09680     #endif
09681 
09682     #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09683         case wolfssl_aes_gcm:
09684         case wolfssl_aes_ccm: /* GCM AEAD macros use same size as CCM */
09685         {
09686             wc_AesAuthDecryptFunc aes_auth_fn;
09687         #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM)
09688             aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm)
09689                             ? wc_AesGcmDecrypt : wc_AesCcmDecrypt;
09690         #elif defined(BUILD_AESGCM)
09691             aes_auth_fn = wc_AesGcmDecrypt;
09692         #else
09693             aes_auth_fn = wc_AesCcmDecrypt;
09694         #endif
09695 
09696             XMEMSET(ssl->decrypt.additional, 0, AEAD_AUTH_DATA_SZ);
09697 
09698             /* sequence number field is 64-bits */
09699             WriteSEQ(ssl, PEER_ORDER, ssl->decrypt.additional);
09700 
09701             ssl->decrypt.additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
09702             ssl->decrypt.additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
09703             ssl->decrypt.additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
09704 
09705             c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
09706                                     ssl->decrypt.additional + AEAD_LEN_OFFSET);
09707             XMEMCPY(ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV,
09708                                                             AESGCM_IMP_IV_SZ);
09709             XMEMCPY(ssl->decrypt.nonce + AESGCM_IMP_IV_SZ, input,
09710                                                             AESGCM_EXP_IV_SZ);
09711             if ((ret = aes_auth_fn(ssl->decrypt.aes,
09712                         plain + AESGCM_EXP_IV_SZ,
09713                         input + AESGCM_EXP_IV_SZ,
09714                            sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
09715                         ssl->decrypt.nonce, AESGCM_NONCE_SZ,
09716                         input + sz - ssl->specs.aead_mac_size,
09717                         ssl->specs.aead_mac_size,
09718                         ssl->decrypt.additional, AEAD_AUTH_DATA_SZ)) < 0) {
09719             #ifdef WOLFSSL_ASYNC_CRYPT
09720                 if (ret == WC_PENDING_E) {
09721                     ret = wolfSSL_AsyncPush(ssl,
09722                         &ssl->decrypt.aes->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
09723                     break;
09724                 }
09725             #endif
09726             }
09727         }
09728         break;
09729     #endif /* BUILD_AESGCM || HAVE_AESCCM */
09730 
09731     #ifdef HAVE_CAMELLIA
09732         case wolfssl_camellia:
09733             wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
09734             break;
09735     #endif
09736 
09737     #ifdef HAVE_HC128
09738         case wolfssl_hc128:
09739             ret = wc_Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
09740             break;
09741     #endif
09742 
09743     #ifdef BUILD_RABBIT
09744         case wolfssl_rabbit:
09745             ret = wc_RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
09746             break;
09747     #endif
09748 
09749     #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
09750         case wolfssl_chacha:
09751             ret = ChachaAEADDecrypt(ssl, plain, input, sz);
09752             break;
09753     #endif
09754 
09755     #ifdef HAVE_NULL_CIPHER
09756         case wolfssl_cipher_null:
09757             if (input != plain) {
09758                 XMEMMOVE(plain, input, sz);
09759             }
09760             break;
09761     #endif
09762 
09763     #ifdef HAVE_IDEA
09764         case wolfssl_idea:
09765             ret = wc_IdeaCbcDecrypt(ssl->decrypt.idea, plain, input, sz);
09766             break;
09767     #endif
09768 
09769         default:
09770             WOLFSSL_MSG("wolfSSL Decrypt programming error");
09771             ret = DECRYPT_ERROR;
09772     }
09773 
09774     return ret;
09775 }
09776 
09777 static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
09778                            word16 sz)
09779 {
09780     int ret = 0;
09781 
09782 #ifdef WOLFSSL_ASYNC_CRYPT
09783     ret = wolfSSL_AsyncPop(ssl, &ssl->decrypt.state);
09784     if (ret != WC_NOT_PENDING_E) {
09785         /* check for still pending */
09786         if (ret == WC_PENDING_E)
09787             return ret;
09788 
09789         ssl->error = 0; /* clear async */
09790 
09791         /* let failures through so CIPHER_STATE_END logic is run */
09792     }
09793     else
09794 #endif
09795     {
09796         /* Reset state */
09797         ret = 0;
09798         ssl->decrypt.state = CIPHER_STATE_BEGIN;
09799     }
09800 
09801     switch (ssl->decrypt.state) {
09802         case CIPHER_STATE_BEGIN:
09803         {
09804             if (ssl->decrypt.setup == 0) {
09805                 WOLFSSL_MSG("Decrypt ciphers not setup");
09806                 return DECRYPT_ERROR;
09807             }
09808 
09809         #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09810             /* make sure AES GCM/CCM memory is allocated */
09811             /* free for these happens in FreeCiphers */
09812             if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
09813                 ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
09814                 /* make sure auth iv and auth are allocated */
09815                 if (ssl->decrypt.additional == NULL)
09816                     ssl->decrypt.additional = (byte*)XMALLOC(AEAD_AUTH_DATA_SZ,
09817                                                    ssl->heap, DYNAMIC_TYPE_AES);
09818                 if (ssl->decrypt.nonce == NULL)
09819                     ssl->decrypt.nonce = (byte*)XMALLOC(AESGCM_NONCE_SZ,
09820                                                    ssl->heap, DYNAMIC_TYPE_AES);
09821                 if (ssl->decrypt.additional == NULL ||
09822                          ssl->decrypt.nonce == NULL) {
09823                     return MEMORY_E;
09824                 }
09825             }
09826         #endif /* BUILD_AESGCM || HAVE_AESCCM */
09827 
09828             /* Advance state and proceed */
09829             ssl->decrypt.state = CIPHER_STATE_DO;
09830         }
09831         case CIPHER_STATE_DO:
09832         {
09833             ret = DecryptDo(ssl, plain, input, sz);
09834 
09835             /* Advance state */
09836             ssl->decrypt.state = CIPHER_STATE_END;
09837 
09838         #ifdef WOLFSSL_ASYNC_CRYPT
09839             /* If pending, leave and return below */
09840             if (ret == WC_PENDING_E) {
09841                 return ret;
09842             }
09843         #endif
09844         }
09845 
09846         case CIPHER_STATE_END:
09847         {
09848         #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
09849             /* make sure AES GCM/CCM nonce is cleared */
09850             if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_ccm ||
09851                 ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
09852                 if (ssl->decrypt.nonce)
09853                     ForceZero(ssl->decrypt.nonce, AESGCM_NONCE_SZ);
09854 
09855                 if (ret < 0)
09856                     ret = VERIFY_MAC_ERROR;
09857             }
09858         #endif /* BUILD_AESGCM || HAVE_AESCCM */
09859             break;
09860         }
09861     }
09862 
09863     /* Reset state */
09864     ssl->decrypt.state = CIPHER_STATE_BEGIN;
09865 
09866     /* handle mac error case */
09867     if (ret == VERIFY_MAC_ERROR) {
09868         if (!ssl->options.dtls)
09869             SendAlert(ssl, alert_fatal, bad_record_mac);
09870     }
09871 
09872     return ret;
09873 }
09874 
09875 /* Check conditions for a cipher to have an explicit IV.
09876  *
09877  * ssl  The SSL/TLS object.
09878  * returns 1 if the cipher in use has an explicit IV and 0 otherwise.
09879  */
09880 static INLINE int CipherHasExpIV(WOLFSSL *ssl)
09881 {
09882 #ifdef WOLFSSL_TLS13
09883     if (ssl->options.tls1_3)
09884         return 0;
09885 #endif
09886     return (ssl->specs.cipher_type == aead) &&
09887             (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha);
09888 }
09889 
09890 /* check cipher text size for sanity */
09891 static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
09892 {
09893 #ifdef HAVE_TRUNCATED_HMAC
09894     word32 minLength = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
09895                                            : ssl->specs.hash_size;
09896 #else
09897     word32 minLength = ssl->specs.hash_size; /* covers stream */
09898 #endif
09899 
09900     if (ssl->specs.cipher_type == block) {
09901         if (encryptSz % ssl->specs.block_size) {
09902             WOLFSSL_MSG("Block ciphertext not block size");
09903             return SANITY_CIPHER_E;
09904         }
09905 
09906         minLength++;  /* pad byte */
09907 
09908         if (ssl->specs.block_size > minLength)
09909             minLength = ssl->specs.block_size;
09910 
09911         if (ssl->options.tls1_1)
09912             minLength += ssl->specs.block_size;  /* explicit IV */
09913     }
09914     else if (ssl->specs.cipher_type == aead) {
09915         minLength = ssl->specs.aead_mac_size;    /* authTag size */
09916         if (CipherHasExpIV(ssl))
09917             minLength += AESGCM_EXP_IV_SZ;       /* explicit IV  */
09918     }
09919 
09920     if (encryptSz < minLength) {
09921         WOLFSSL_MSG("Ciphertext not minimum size");
09922         return SANITY_CIPHER_E;
09923     }
09924 
09925     return 0;
09926 }
09927 
09928 
09929 #ifndef NO_OLD_TLS
09930 
09931 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
09932 {
09933     Md5 md5;
09934     int i;
09935 
09936     wc_InitMd5(&md5);   /* no error check on purpose, dummy round */
09937 
09938     for (i = 0; i < rounds; i++)
09939         wc_Md5Update(&md5, data, sz);
09940     wc_Md5Free(&md5); /* in case needed to release resources */
09941 }
09942 
09943 
09944 
09945 /* do a dummy sha round */
09946 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
09947 {
09948     Sha sha;
09949     int i;
09950 
09951     wc_InitSha(&sha);  /* no error check on purpose, dummy round */
09952 
09953     for (i = 0; i < rounds; i++)
09954         wc_ShaUpdate(&sha, data, sz);
09955     wc_ShaFree(&sha); /* in case needed to release resources */
09956 }
09957 #endif
09958 
09959 
09960 #ifndef NO_SHA256
09961 
09962 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
09963 {
09964     Sha256 sha256;
09965     int i;
09966 
09967     wc_InitSha256(&sha256);  /* no error check on purpose, dummy round */
09968 
09969     for (i = 0; i < rounds; i++) {
09970         wc_Sha256Update(&sha256, data, sz);
09971         /* no error check on purpose, dummy round */
09972     }
09973     wc_Sha256Free(&sha256); /* in case needed to release resources */
09974 }
09975 
09976 #endif
09977 
09978 
09979 #ifdef WOLFSSL_SHA384
09980 
09981 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
09982 {
09983     Sha384 sha384;
09984     int i;
09985 
09986     wc_InitSha384(&sha384);  /* no error check on purpose, dummy round */
09987 
09988     for (i = 0; i < rounds; i++) {
09989         wc_Sha384Update(&sha384, data, sz);
09990         /* no error check on purpose, dummy round */
09991     }
09992     wc_Sha384Free(&sha384); /* in case needed to release resources */
09993 }
09994 
09995 #endif
09996 
09997 
09998 #ifdef WOLFSSL_SHA512
09999 
10000 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
10001 {
10002     Sha512 sha512;
10003     int i;
10004 
10005     wc_InitSha512(&sha512);  /* no error check on purpose, dummy round */
10006 
10007     for (i = 0; i < rounds; i++) {
10008         wc_Sha512Update(&sha512, data, sz);
10009         /* no error check on purpose, dummy round */
10010     }
10011     wc_Sha512Free(&sha512); /* in case needed to release resources */
10012 }
10013 
10014 #endif
10015 
10016 
10017 #ifdef WOLFSSL_RIPEMD
10018 
10019 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
10020 {
10021     RipeMd ripemd;
10022     int i;
10023 
10024     wc_InitRipeMd(&ripemd);
10025 
10026     for (i = 0; i < rounds; i++)
10027         wc_RipeMdUpdate(&ripemd, data, sz);
10028 }
10029 
10030 #endif
10031 
10032 
10033 /* Do dummy rounds */
10034 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
10035 {
10036     (void)rounds;
10037     (void)data;
10038     (void)sz;
10039 
10040     switch (type) {
10041         case no_mac :
10042             break;
10043 
10044 #ifndef NO_OLD_TLS
10045 #ifndef NO_MD5
10046         case md5_mac :
10047             Md5Rounds(rounds, data, sz);
10048             break;
10049 #endif
10050 
10051 #ifndef NO_SHA
10052         case sha_mac :
10053             ShaRounds(rounds, data, sz);
10054             break;
10055 #endif
10056 #endif
10057 
10058 #ifndef NO_SHA256
10059         case sha256_mac :
10060             Sha256Rounds(rounds, data, sz);
10061             break;
10062 #endif
10063 
10064 #ifdef WOLFSSL_SHA384
10065         case sha384_mac :
10066             Sha384Rounds(rounds, data, sz);
10067             break;
10068 #endif
10069 
10070 #ifdef WOLFSSL_SHA512
10071         case sha512_mac :
10072             Sha512Rounds(rounds, data, sz);
10073             break;
10074 #endif
10075 
10076 #ifdef WOLFSSL_RIPEMD
10077         case rmd_mac :
10078             RmdRounds(rounds, data, sz);
10079             break;
10080 #endif
10081 
10082         default:
10083             WOLFSSL_MSG("Bad round type");
10084             break;
10085     }
10086 }
10087 
10088 
10089 /* do number of compression rounds on dummy data */
10090 static INLINE void CompressRounds(WOLFSSL* ssl, int rounds, const byte* dummy)
10091 {
10092     if (rounds)
10093         DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
10094 }
10095 
10096 
10097 /* check all length bytes for the pad value, return 0 on success */
10098 static int PadCheck(const byte* a, byte pad, int length)
10099 {
10100     int i;
10101     int compareSum = 0;
10102 
10103     for (i = 0; i < length; i++) {
10104         compareSum |= a[i] ^ pad;
10105     }
10106 
10107     return compareSum;
10108 }
10109 
10110 
10111 /* get compression extra rounds */
10112 static INLINE int GetRounds(int pLen, int padLen, int t)
10113 {
10114     int  roundL1 = 1;  /* round up flags */
10115     int  roundL2 = 1;
10116 
10117     int L1 = COMPRESS_CONSTANT + pLen - t;
10118     int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
10119 
10120     L1 -= COMPRESS_UPPER;
10121     L2 -= COMPRESS_UPPER;
10122 
10123     if ( (L1 % COMPRESS_LOWER) == 0)
10124         roundL1 = 0;
10125     if ( (L2 % COMPRESS_LOWER) == 0)
10126         roundL2 = 0;
10127 
10128     L1 /= COMPRESS_LOWER;
10129     L2 /= COMPRESS_LOWER;
10130 
10131     L1 += roundL1;
10132     L2 += roundL2;
10133 
10134     return L1 - L2;
10135 }
10136 
10137 
10138 /* timing resistant pad/verify check, return 0 on success */
10139 static int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
10140                            int pLen, int content)
10141 {
10142     byte verify[MAX_DIGEST_SIZE];
10143     byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
10144     byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
10145     int  ret = 0;
10146 
10147     (void)dmy;
10148 
10149     if ( (t + padLen + 1) > pLen) {
10150         WOLFSSL_MSG("Plain Len not long enough for pad/mac");
10151         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
10152         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
10153         ConstantCompare(verify, input + pLen - t, t);
10154 
10155         return VERIFY_MAC_ERROR;
10156     }
10157 
10158     if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
10159         WOLFSSL_MSG("PadCheck failed");
10160         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
10161         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
10162         ConstantCompare(verify, input + pLen - t, t);
10163 
10164         return VERIFY_MAC_ERROR;
10165     }
10166 
10167     PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
10168     ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
10169 
10170     CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
10171 
10172     if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
10173         WOLFSSL_MSG("Verify MAC compare failed");
10174         return VERIFY_MAC_ERROR;
10175     }
10176 
10177     /* treat any faulure as verify MAC error */
10178     if (ret != 0)
10179         ret = VERIFY_MAC_ERROR;
10180 
10181     return ret;
10182 }
10183 
10184 
10185 int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
10186 {
10187     word32 msgSz   = ssl->keys.encryptSz;
10188     word32 idx     = *inOutIdx;
10189     int    dataSz;
10190     int    ivExtra = 0;
10191     byte*  rawData = input + idx;  /* keep current  for hmac */
10192 #ifdef HAVE_LIBZ
10193     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
10194 #endif
10195 
10196     if (ssl->options.handShakeDone == 0) {
10197         WOLFSSL_MSG("Received App data before a handshake completed");
10198         SendAlert(ssl, alert_fatal, unexpected_message);
10199         return OUT_OF_ORDER_E;
10200     }
10201 
10202     if (ssl->specs.cipher_type == block) {
10203         if (ssl->options.tls1_1)
10204             ivExtra = ssl->specs.block_size;
10205     }
10206     else if (ssl->specs.cipher_type == aead) {
10207         if (CipherHasExpIV(ssl))
10208             ivExtra = AESGCM_EXP_IV_SZ;
10209     }
10210 
10211     dataSz = msgSz - ivExtra - ssl->keys.padSz;
10212     if (dataSz < 0) {
10213         WOLFSSL_MSG("App data buffer error, malicious input?");
10214         return BUFFER_ERROR;
10215     }
10216 
10217     /* read data */
10218     if (dataSz) {
10219         int rawSz = dataSz;       /* keep raw size for idx adjustment */
10220 
10221 #ifdef HAVE_LIBZ
10222         if (ssl->options.usingCompression) {
10223             dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
10224             if (dataSz < 0) return dataSz;
10225         }
10226 #endif
10227         idx += rawSz;
10228 
10229         ssl->buffers.clearOutputBuffer.buffer = rawData;
10230         ssl->buffers.clearOutputBuffer.length = dataSz;
10231     }
10232 
10233     idx += ssl->keys.padSz;
10234 
10235 #ifdef HAVE_LIBZ
10236     /* decompress could be bigger, overwrite after verify */
10237     if (ssl->options.usingCompression)
10238         XMEMMOVE(rawData, decomp, dataSz);
10239 #endif
10240 
10241     *inOutIdx = idx;
10242     return 0;
10243 }
10244 
10245 
10246 /* process alert, return level */
10247 static int DoAlert(WOLFSSL* ssl, byte* input, word32* inOutIdx, int* type,
10248                    word32 totalSz)
10249 {
10250     byte level;
10251     byte code;
10252 
10253     #ifdef WOLFSSL_CALLBACKS
10254         if (ssl->hsInfoOn)
10255             AddPacketName("Alert", &ssl->handShakeInfo);
10256         if (ssl->toInfoOn)
10257             /* add record header back on to info + alert bytes level/code */
10258             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
10259                           RECORD_HEADER_SZ, RECORD_HEADER_SZ + ALERT_SIZE,
10260                           ssl->heap);
10261     #endif
10262 
10263     /* make sure can read the message */
10264     if (*inOutIdx + ALERT_SIZE > totalSz)
10265         return BUFFER_E;
10266 
10267     level = input[(*inOutIdx)++];
10268     code  = input[(*inOutIdx)++];
10269     ssl->alert_history.last_rx.code = code;
10270     ssl->alert_history.last_rx.level = level;
10271     *type = code;
10272     if (level == alert_fatal) {
10273         ssl->options.isClosed = 1;  /* Don't send close_notify */
10274     }
10275 
10276     WOLFSSL_MSG("Got alert");
10277     if (*type == close_notify) {
10278         WOLFSSL_MSG("\tclose notify");
10279         ssl->options.closeNotify = 1;
10280     }
10281 #ifdef WOLFSSL_TLS13
10282     if (*type == decode_error) {
10283         WOLFSSL_MSG("    decode error");
10284     }
10285     if (*type == illegal_parameter) {
10286         WOLFSSL_MSG("    illegal parameter");
10287     }
10288 #endif
10289     WOLFSSL_ERROR(*type);
10290     if (IsEncryptionOn(ssl, 0)) {
10291         if (*inOutIdx + ssl->keys.padSz > totalSz)
10292             return BUFFER_E;
10293         *inOutIdx += ssl->keys.padSz;
10294     }
10295 
10296     return level;
10297 }
10298 
10299 static int GetInputData(WOLFSSL *ssl, word32 size)
10300 {
10301     int in;
10302     int inSz;
10303     int maxLength;
10304     int usedLength;
10305     int dtlsExtra = 0;
10306 
10307 
10308     /* check max input length */
10309     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
10310     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
10311     inSz       = (int)(size - usedLength);      /* from last partial read */
10312 
10313 #ifdef WOLFSSL_DTLS
10314     if (ssl->options.dtls) {
10315         if (size < ssl->dtls_expected_rx)
10316             dtlsExtra = (int)(ssl->dtls_expected_rx - size);
10317         inSz = ssl->dtls_expected_rx;
10318     }
10319 #endif
10320 
10321     /* check that no lengths or size values are negative */
10322     if (usedLength < 0 || maxLength < 0 || inSz <= 0) {
10323         return BUFFER_ERROR;
10324     }
10325 
10326     if (inSz > maxLength) {
10327         if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
10328             return MEMORY_E;
10329     }
10330 
10331     /* Put buffer data at start if not there */
10332     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
10333         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
10334                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
10335                 usedLength);
10336 
10337     /* remove processed data */
10338     ssl->buffers.inputBuffer.idx    = 0;
10339     ssl->buffers.inputBuffer.length = usedLength;
10340 
10341     /* read data from network */
10342     do {
10343         in = Receive(ssl,
10344                      ssl->buffers.inputBuffer.buffer +
10345                      ssl->buffers.inputBuffer.length,
10346                      inSz);
10347         if (in == -1)
10348             return SOCKET_ERROR_E;
10349 
10350         if (in == WANT_READ)
10351             return WANT_READ;
10352 
10353         if (in > inSz)
10354             return RECV_OVERFLOW_E;
10355 
10356         ssl->buffers.inputBuffer.length += in;
10357         inSz -= in;
10358 
10359     } while (ssl->buffers.inputBuffer.length < size);
10360 
10361 #ifdef WOLFSSL_DEBUG_TLS
10362     if (ssl->buffers.inputBuffer.idx == 0) {
10363         WOLFSSL_MSG("Data received");
10364         WOLFSSL_BUFFER(ssl->buffers.inputBuffer.buffer,
10365                        ssl->buffers.inputBuffer.length);
10366     }
10367 #endif
10368 
10369     return 0;
10370 }
10371 
10372 
10373 static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
10374                             int content, word32* padSz)
10375 {
10376     int    ivExtra = 0;
10377     int    ret;
10378     word32 pad     = 0;
10379     word32 padByte = 0;
10380 #ifdef HAVE_TRUNCATED_HMAC
10381     word32 digestSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
10382                                           : ssl->specs.hash_size;
10383 #else
10384     word32 digestSz = ssl->specs.hash_size;
10385 #endif
10386     byte   verify[MAX_DIGEST_SIZE];
10387 
10388     if (ssl->specs.cipher_type == block) {
10389         if (ssl->options.tls1_1)
10390             ivExtra = ssl->specs.block_size;
10391         pad = *(input + msgSz - ivExtra - 1);
10392         padByte = 1;
10393 
10394         if (ssl->options.tls) {
10395             ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
10396                                   content);
10397             if (ret != 0)
10398                 return ret;
10399         }
10400         else {  /* sslv3, some implementations have bad padding, but don't
10401                  * allow bad read */
10402             int  badPadLen = 0;
10403             byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
10404             byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
10405 
10406             (void)dmy;
10407 
10408             if (pad > (msgSz - digestSz - 1)) {
10409                 WOLFSSL_MSG("Plain Len not long enough for pad/mac");
10410                 pad       = 0;  /* no bad read */
10411                 badPadLen = 1;
10412             }
10413             PadCheck(dummy, (byte)pad, MAX_PAD_SIZE);  /* timing only */
10414             ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
10415                             content, 1);
10416             if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
10417                                 digestSz) != 0)
10418                 return VERIFY_MAC_ERROR;
10419             if (ret != 0 || badPadLen)
10420                 return VERIFY_MAC_ERROR;
10421         }
10422     }
10423     else if (ssl->specs.cipher_type == stream) {
10424         ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
10425         if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
10426             return VERIFY_MAC_ERROR;
10427         }
10428         if (ret != 0)
10429             return VERIFY_MAC_ERROR;
10430     }
10431 
10432     if (ssl->specs.cipher_type == aead) {
10433         *padSz = ssl->specs.aead_mac_size;
10434     }
10435     else {
10436         *padSz = digestSz + pad + padByte;
10437     }
10438 
10439     return 0;
10440 }
10441 
10442 
10443 /* process input requests, return 0 is done, 1 is call again to complete, and
10444    negative number is error */
10445 int ProcessReply(WOLFSSL* ssl)
10446 {
10447     int    ret = 0, type, readSz;
10448     int    atomicUser = 0;
10449     word32 startIdx = 0;
10450 #if defined(WOLFSSL_DTLS)
10451     int    used;
10452 #endif
10453 
10454 #ifdef ATOMIC_USER
10455     if (ssl->ctx->DecryptVerifyCb)
10456         atomicUser = 1;
10457 #endif
10458 
10459     if (ssl->error != 0 && ssl->error != WANT_READ &&
10460         ssl->error != WANT_WRITE && ssl->error != WC_PENDING_E) {
10461         WOLFSSL_MSG("ProcessReply retry in error state, not allowed");
10462         return ssl->error;
10463     }
10464 
10465     for (;;) {
10466         switch (ssl->options.processReply) {
10467 
10468         /* in the WOLFSSL_SERVER case, get the first byte for detecting
10469          * old client hello */
10470         case doProcessInit:
10471 
10472             readSz = RECORD_HEADER_SZ;
10473 
10474         #ifdef WOLFSSL_DTLS
10475             if (ssl->options.dtls)
10476                 readSz = DTLS_RECORD_HEADER_SZ;
10477         #endif
10478 
10479             /* get header or return error */
10480             if (!ssl->options.dtls) {
10481                 if ((ret = GetInputData(ssl, readSz)) < 0)
10482                     return ret;
10483             } else {
10484             #ifdef WOLFSSL_DTLS
10485                 /* read ahead may already have header */
10486                 used = ssl->buffers.inputBuffer.length -
10487                        ssl->buffers.inputBuffer.idx;
10488                 if (used < readSz) {
10489                     if ((ret = GetInputData(ssl, readSz)) < 0)
10490                         return ret;
10491                 }
10492             #endif
10493             }
10494 
10495 #ifdef OLD_HELLO_ALLOWED
10496 
10497             /* see if sending SSLv2 client hello */
10498             if ( ssl->options.side == WOLFSSL_SERVER_END &&
10499                  ssl->options.clientState == NULL_STATE &&
10500                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
10501                          != handshake) {
10502                 byte b0, b1;
10503 
10504                 ssl->options.processReply = runProcessOldClientHello;
10505 
10506                 /* sanity checks before getting size at front */
10507                 if (ssl->buffers.inputBuffer.buffer[
10508                           ssl->buffers.inputBuffer.idx + OPAQUE16_LEN] != OLD_HELLO_ID) {
10509                     WOLFSSL_MSG("Not a valid old client hello");
10510                     return PARSE_ERROR;
10511                 }
10512 
10513                 if (ssl->buffers.inputBuffer.buffer[
10514                           ssl->buffers.inputBuffer.idx + OPAQUE24_LEN] != SSLv3_MAJOR &&
10515                     ssl->buffers.inputBuffer.buffer[
10516                           ssl->buffers.inputBuffer.idx + OPAQUE24_LEN] != DTLS_MAJOR) {
10517                     WOLFSSL_MSG("Not a valid version in old client hello");
10518                     return PARSE_ERROR;
10519                 }
10520 
10521                 /* how many bytes need ProcessOldClientHello */
10522                 b0 =
10523                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
10524                 b1 =
10525                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
10526                 ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
10527             }
10528             else {
10529                 ssl->options.processReply = getRecordLayerHeader;
10530                 continue;
10531             }
10532 
10533         /* in the WOLFSSL_SERVER case, run the old client hello */
10534         case runProcessOldClientHello:
10535 
10536             /* get sz bytes or return error */
10537             if (!ssl->options.dtls) {
10538                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
10539                     return ret;
10540             } else {
10541             #ifdef WOLFSSL_DTLS
10542                 /* read ahead may already have */
10543                 used = ssl->buffers.inputBuffer.length -
10544                        ssl->buffers.inputBuffer.idx;
10545                 if (used < ssl->curSize)
10546                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
10547                         return ret;
10548             #endif  /* WOLFSSL_DTLS */
10549             }
10550 
10551             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
10552                                         &ssl->buffers.inputBuffer.idx,
10553                                         ssl->buffers.inputBuffer.length -
10554                                         ssl->buffers.inputBuffer.idx,
10555                                         ssl->curSize);
10556             if (ret < 0)
10557                 return ret;
10558 
10559             else if (ssl->buffers.inputBuffer.idx ==
10560                      ssl->buffers.inputBuffer.length) {
10561                 ssl->options.processReply = doProcessInit;
10562                 return 0;
10563             }
10564 
10565 #endif  /* OLD_HELLO_ALLOWED */
10566 
10567         /* get the record layer header */
10568         case getRecordLayerHeader:
10569 
10570             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
10571                                        &ssl->buffers.inputBuffer.idx,
10572                                        &ssl->curRL, &ssl->curSize);
10573 #ifdef WOLFSSL_DTLS
10574             if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
10575                 WOLFSSL_MSG("Silently dropping out of order DTLS message");
10576                 ssl->options.processReply = doProcessInit;
10577                 ssl->buffers.inputBuffer.length = 0;
10578                 ssl->buffers.inputBuffer.idx = 0;
10579 
10580                 if (IsDtlsNotSctpMode(ssl) && ssl->options.dtlsHsRetain) {
10581                     ret = DtlsMsgPoolSend(ssl, 0);
10582                     if (ret != 0)
10583                         return ret;
10584                 }
10585 
10586                 continue;
10587             }
10588 #endif
10589             if (ret != 0)
10590                 return ret;
10591 
10592             ssl->options.processReply = getData;
10593 
10594         /* retrieve record layer data */
10595         case getData:
10596 
10597             /* get sz bytes or return error */
10598             if (!ssl->options.dtls) {
10599                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
10600                     return ret;
10601             } else {
10602 #ifdef WOLFSSL_DTLS
10603                 /* read ahead may already have */
10604                 used = ssl->buffers.inputBuffer.length -
10605                        ssl->buffers.inputBuffer.idx;
10606                 if (used < ssl->curSize)
10607                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
10608                         return ret;
10609 #endif
10610             }
10611 
10612             ssl->options.processReply = decryptMessage;
10613             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
10614 
10615         /* decrypt message */
10616         case decryptMessage:
10617 
10618             if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0) {
10619                 bufferStatic* in = &ssl->buffers.inputBuffer;
10620 
10621                 ret = SanityCheckCipherText(ssl, ssl->curSize);
10622                 if (ret < 0)
10623                     return ret;
10624 
10625                 if (atomicUser) {
10626                 #ifdef ATOMIC_USER
10627                     ret = ssl->ctx->DecryptVerifyCb(ssl,
10628                                   in->buffer + in->idx,
10629                                   in->buffer + in->idx,
10630                                   ssl->curSize, ssl->curRL.type, 1,
10631                                   &ssl->keys.padSz, ssl->DecryptVerifyCtx);
10632                 #endif /* ATOMIC_USER */
10633                 }
10634                 else {
10635                     if (!ssl->options.tls1_3) {
10636                         ret = Decrypt(ssl,
10637                                       in->buffer + in->idx,
10638                                       in->buffer + in->idx,
10639                                       ssl->curSize);
10640                     }
10641                     else {
10642                     #ifdef WOLFSSL_TLS13
10643                         ret = DecryptTls13(ssl,
10644                                            in->buffer + in->idx,
10645                                            in->buffer + in->idx,
10646                                            ssl->curSize);
10647                     #else
10648                         ret = DECRYPT_ERROR;
10649                     #endif /* WOLFSSL_TLS13 */
10650                     }
10651                 }
10652 
10653             #ifdef WOLFSSL_ASYNC_CRYPT
10654                 if (ret == WC_PENDING_E)
10655                     return ret;
10656             #endif
10657 
10658                 if (ret >= 0) {
10659                     /* handle success */
10660                     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
10661                         ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
10662                         /* go past TLSv1.1 IV */
10663                     if (CipherHasExpIV(ssl))
10664                         ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ;
10665                 }
10666                 else {
10667                     WOLFSSL_MSG("Decrypt failed");
10668                     WOLFSSL_ERROR(ret);
10669                 #ifdef WOLFSSL_DTLS
10670                     /* If in DTLS mode, if the decrypt fails for any
10671                      * reason, pretend the datagram never happened. */
10672                     if (ssl->options.dtls) {
10673                         ssl->options.processReply = doProcessInit;
10674                         ssl->buffers.inputBuffer.idx =
10675                                         ssl->buffers.inputBuffer.length;
10676                     }
10677                 #endif /* WOLFSSL_DTLS */
10678 
10679                     return DECRYPT_ERROR;
10680                 }
10681             }
10682 
10683             ssl->options.processReply = verifyMessage;
10684 
10685         /* verify digest of message */
10686         case verifyMessage:
10687 
10688             if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0) {
10689                 if (!atomicUser) {
10690                     ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
10691                                     ssl->buffers.inputBuffer.idx,
10692                                     ssl->curSize, ssl->curRL.type,
10693                                     &ssl->keys.padSz);
10694                 #ifdef WOLFSSL_ASYNC_CRYPT
10695                     if (ret == WC_PENDING_E)
10696                         return ret;
10697                 #endif
10698                     if (ret < 0) {
10699                         WOLFSSL_MSG("VerifyMac failed");
10700                         WOLFSSL_ERROR(ret);
10701                         return DECRYPT_ERROR;
10702                     }
10703                 }
10704 
10705                 ssl->keys.encryptSz    = ssl->curSize;
10706                 ssl->keys.decryptedCur = 1;
10707 #ifdef WOLFSSL_TLS13
10708                 if (ssl->options.tls1_3) {
10709                     /* Get the real content type from the end of the data. */
10710                     ssl->keys.padSz++;
10711                     ssl->curRL.type = ssl->buffers.inputBuffer.buffer[
10712                         ssl->buffers.inputBuffer.length - ssl->keys.padSz];
10713                 }
10714 #endif
10715             }
10716 
10717             ssl->options.processReply = runProcessingOneMessage;
10718 
10719         /* the record layer is here */
10720         case runProcessingOneMessage:
10721 
10722         #ifdef WOLFSSL_DTLS
10723             if (IsDtlsNotSctpMode(ssl)) {
10724                 DtlsUpdateWindow(ssl);
10725             }
10726         #endif /* WOLFSSL_DTLS */
10727 
10728             WOLFSSL_MSG("received record layer msg");
10729 
10730             switch (ssl->curRL.type) {
10731                 case handshake :
10732                     /* debugging in DoHandShakeMsg */
10733                     if (ssl->options.dtls) {
10734 #ifdef WOLFSSL_DTLS
10735                         ret = DoDtlsHandShakeMsg(ssl,
10736                                             ssl->buffers.inputBuffer.buffer,
10737                                             &ssl->buffers.inputBuffer.idx,
10738                                             ssl->buffers.inputBuffer.length);
10739 #endif
10740                     }
10741                     else if (!IsAtLeastTLSv1_3(ssl->version)) {
10742                         ret = DoHandShakeMsg(ssl,
10743                                             ssl->buffers.inputBuffer.buffer,
10744                                             &ssl->buffers.inputBuffer.idx,
10745                                             ssl->buffers.inputBuffer.length);
10746                     }
10747                     else {
10748 #ifdef WOLFSSL_TLS13
10749                         ret = DoTls13HandShakeMsg(ssl,
10750                                             ssl->buffers.inputBuffer.buffer,
10751                                             &ssl->buffers.inputBuffer.idx,
10752                                             ssl->buffers.inputBuffer.length);
10753 #else
10754                         ret = BUFFER_ERROR;
10755 #endif
10756                     }
10757                     if (ret != 0)
10758                         return ret;
10759                     break;
10760 
10761                 case change_cipher_spec:
10762                     WOLFSSL_MSG("got CHANGE CIPHER SPEC");
10763                     #ifdef WOLFSSL_CALLBACKS
10764                         if (ssl->hsInfoOn)
10765                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
10766                         /* add record header back on info */
10767                         if (ssl->toInfoOn) {
10768                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
10769                                 ssl->buffers.inputBuffer.buffer +
10770                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
10771                                 1 + RECORD_HEADER_SZ, ssl->heap);
10772                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
10773                         }
10774                     #endif
10775 
10776                     ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
10777                     if (ret != 0) {
10778                         if (!ssl->options.dtls) {
10779                             return ret;
10780                         }
10781                         else {
10782                         #ifdef WOLFSSL_DTLS
10783                         /* Check for duplicate CCS message in DTLS mode.
10784                          * DTLS allows for duplicate messages, and it should be
10785                          * skipped. Also skip if out of order. */
10786                             if (ret != DUPLICATE_MSG_E && ret != OUT_OF_ORDER_E)
10787                                 return ret;
10788 
10789                             if (IsDtlsNotSctpMode(ssl)) {
10790                                 ret = DtlsMsgPoolSend(ssl, 1);
10791                                 if (ret != 0)
10792                                     return ret;
10793                             }
10794 
10795                             if (ssl->curSize != 1) {
10796                                 WOLFSSL_MSG("Malicious or corrupted"
10797                                             " duplicate ChangeCipher msg");
10798                                 return LENGTH_ERROR;
10799                             }
10800                             ssl->buffers.inputBuffer.idx++;
10801                             break;
10802                         #endif /* WOLFSSL_DTLS */
10803                         }
10804                     }
10805 
10806                     if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) {
10807                         ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
10808                         ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx;
10809                     }
10810 
10811                     if (ssl->curSize != 1) {
10812                         WOLFSSL_MSG("Malicious or corrupted ChangeCipher msg");
10813                         return LENGTH_ERROR;
10814                     }
10815 
10816                     ssl->buffers.inputBuffer.idx++;
10817                     ssl->keys.encryptionOn = 1;
10818 
10819                     /* setup decrypt keys for following messages */
10820                     if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
10821                         return ret;
10822 
10823                     #ifdef WOLFSSL_DTLS
10824                         if (ssl->options.dtls) {
10825                             DtlsMsgPoolReset(ssl);
10826                             ssl->keys.prevSeq_lo = ssl->keys.nextSeq_lo;
10827                             ssl->keys.prevSeq_hi = ssl->keys.nextSeq_hi;
10828                             XMEMCPY(ssl->keys.prevWindow, ssl->keys.window,
10829                                     DTLS_SEQ_SZ);
10830                             ssl->keys.nextEpoch++;
10831                             ssl->keys.nextSeq_lo = 0;
10832                             ssl->keys.nextSeq_hi = 0;
10833                             XMEMSET(ssl->keys.window, 0, DTLS_SEQ_SZ);
10834                         }
10835                     #endif
10836 
10837                     #ifdef HAVE_LIBZ
10838                         if (ssl->options.usingCompression)
10839                             if ( (ret = InitStreams(ssl)) != 0)
10840                                 return ret;
10841                     #endif
10842                     ret = BuildFinished(ssl, &ssl->hsHashes->verifyHashes,
10843                                        ssl->options.side == WOLFSSL_CLIENT_END ?
10844                                        server : client);
10845                     if (ret != 0)
10846                         return ret;
10847                     break;
10848 
10849                 case application_data:
10850                     WOLFSSL_MSG("got app DATA");
10851                     #ifdef WOLFSSL_DTLS
10852                         if (ssl->options.dtls && ssl->options.dtlsHsRetain) {
10853                             FreeHandshakeResources(ssl);
10854                             ssl->options.dtlsHsRetain = 0;
10855                         }
10856                     #endif
10857                     #ifdef WOLFSSL_TLS13
10858                         if (ssl->keys.keyUpdateRespond) {
10859                             WOLFSSL_MSG("No KeyUpdate from peer seen");
10860                             return SANITY_MSG_E;
10861                         }
10862                     #endif
10863                     if ((ret = DoApplicationData(ssl,
10864                                                 ssl->buffers.inputBuffer.buffer,
10865                                                &ssl->buffers.inputBuffer.idx))
10866                                                                          != 0) {
10867                         WOLFSSL_ERROR(ret);
10868                         return ret;
10869                     }
10870                     break;
10871 
10872                 case alert:
10873                     WOLFSSL_MSG("got ALERT!");
10874                     ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
10875                                   &ssl->buffers.inputBuffer.idx, &type,
10876                                    ssl->buffers.inputBuffer.length);
10877                     if (ret == alert_fatal)
10878                         return FATAL_ERROR;
10879                     else if (ret < 0)
10880                         return ret;
10881 
10882                     /* catch warnings that are handled as errors */
10883                     if (type == close_notify)
10884                         return ssl->error = ZERO_RETURN;
10885 
10886                     if (type == decrypt_error)
10887                         return FATAL_ERROR;
10888                     break;
10889 
10890                 default:
10891                     WOLFSSL_ERROR(UNKNOWN_RECORD_TYPE);
10892                     return UNKNOWN_RECORD_TYPE;
10893             }
10894 
10895             ssl->options.processReply = doProcessInit;
10896 
10897             /* input exhausted? */
10898             if (ssl->buffers.inputBuffer.idx >= ssl->buffers.inputBuffer.length)
10899                 return 0;
10900 
10901             /* more messages per record */
10902             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
10903                 WOLFSSL_MSG("More messages in record");
10904 
10905                 ssl->options.processReply = runProcessingOneMessage;
10906 
10907                 if (IsEncryptionOn(ssl, 0)) {
10908                     WOLFSSL_MSG("Bundled encrypted messages, remove middle pad");
10909                     if (ssl->buffers.inputBuffer.idx >= ssl->keys.padSz) {
10910                         ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
10911                     }
10912                     else {
10913                         WOLFSSL_MSG("\tmiddle padding error");
10914                         return FATAL_ERROR;
10915                     }
10916                 }
10917 
10918                 continue;
10919             }
10920             /* more records */
10921             else {
10922                 WOLFSSL_MSG("More records in input");
10923                 ssl->options.processReply = doProcessInit;
10924                 continue;
10925             }
10926 
10927         default:
10928             WOLFSSL_MSG("Bad process input state, programming error");
10929             return INPUT_CASE_ERROR;
10930         }
10931     }
10932 }
10933 
10934 
10935 int SendChangeCipher(WOLFSSL* ssl)
10936 {
10937     byte              *output;
10938     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
10939     int                idx    = RECORD_HEADER_SZ;
10940     int                ret;
10941 
10942     #ifdef WOLFSSL_DTLS
10943         if (ssl->options.dtls) {
10944             sendSz += DTLS_RECORD_EXTRA;
10945             idx    += DTLS_RECORD_EXTRA;
10946         }
10947     #endif
10948 
10949     /* are we in scr */
10950     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
10951         sendSz += MAX_MSG_EXTRA;
10952     }
10953 
10954     /* check for avalaible size */
10955     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
10956         return ret;
10957 
10958     /* get output buffer */
10959     output = ssl->buffers.outputBuffer.buffer +
10960              ssl->buffers.outputBuffer.length;
10961 
10962     AddRecordHeader(output, 1, change_cipher_spec, ssl);
10963 
10964     output[idx] = 1;             /* turn it on */
10965 
10966     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
10967         byte input[ENUM_LEN];
10968         int  inputSz = ENUM_LEN;
10969 
10970         input[0] = 1;  /* turn it on */
10971         sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
10972                               change_cipher_spec, 0, 0, 0);
10973         if (sendSz < 0) {
10974             return sendSz;
10975         }
10976     }
10977 
10978     #ifdef WOLFSSL_DTLS
10979         if (IsDtlsNotSctpMode(ssl)) {
10980             if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
10981                 return ret;
10982         }
10983     #endif
10984     #ifdef WOLFSSL_CALLBACKS
10985         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
10986         if (ssl->toInfoOn)
10987             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
10988                            ssl->heap);
10989     #endif
10990     ssl->buffers.outputBuffer.length += sendSz;
10991 
10992     if (ssl->options.groupMessages)
10993         return 0;
10994     #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DEBUG_DTLS)
10995     else if (ssl->options.dtls) {
10996         /* If using DTLS, force the ChangeCipherSpec message to be in the
10997          * same datagram as the finished message. */
10998         return 0;
10999     }
11000     #endif
11001     else
11002         return SendBuffered(ssl);
11003 }
11004 
11005 
11006 #ifndef NO_OLD_TLS
11007 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
11008                  int content, int verify)
11009 {
11010     byte   result[MAX_DIGEST_SIZE];
11011     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
11012     word32 padSz    = ssl->specs.pad_size;
11013     int    ret      = 0;
11014 
11015     Md5 md5;
11016     Sha sha;
11017 
11018     /* data */
11019     byte seq[SEQ_SZ];
11020     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
11021     const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
11022 
11023 #ifdef HAVE_FUZZER
11024     if (ssl->fuzzerCb)
11025         ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
11026 #endif
11027 
11028     XMEMSET(seq, 0, SEQ_SZ);
11029     conLen[0] = (byte)content;
11030     c16toa((word16)sz, &conLen[ENUM_LEN]);
11031     WriteSEQ(ssl, verify, seq);
11032 
11033     if (ssl->specs.mac_algorithm == md5_mac) {
11034         ret =  wc_InitMd5_ex(&md5, ssl->heap, ssl->devId);
11035         if (ret != 0)
11036             return ret;
11037 
11038         /* inner */
11039         ret =  wc_Md5Update(&md5, macSecret, digestSz);
11040         ret |= wc_Md5Update(&md5, PAD1, padSz);
11041         ret |= wc_Md5Update(&md5, seq, SEQ_SZ);
11042         ret |= wc_Md5Update(&md5, conLen, sizeof(conLen));
11043         /* in buffer */
11044         ret |= wc_Md5Update(&md5, in, sz);
11045         if (ret != 0)
11046             return VERIFY_MAC_ERROR;
11047         ret = wc_Md5Final(&md5, result);
11048     #ifdef WOLFSSL_ASYNC_CRYPT
11049         /* TODO: Make non-blocking */
11050         if (ret == WC_PENDING_E) {
11051             ret = wc_AsyncWait(ret, &md5.asyncDev, WC_ASYNC_FLAG_NONE);
11052         }
11053     #endif
11054         if (ret != 0)
11055             return VERIFY_MAC_ERROR;
11056 
11057         /* outer */
11058         ret =  wc_Md5Update(&md5, macSecret, digestSz);
11059         ret |= wc_Md5Update(&md5, PAD2, padSz);
11060         ret |= wc_Md5Update(&md5, result, digestSz);
11061         if (ret != 0)
11062             return VERIFY_MAC_ERROR;
11063         ret =  wc_Md5Final(&md5, digest);
11064     #ifdef WOLFSSL_ASYNC_CRYPT
11065         /* TODO: Make non-blocking */
11066         if (ret == WC_PENDING_E) {
11067             ret = wc_AsyncWait(ret, &md5.asyncDev, WC_ASYNC_FLAG_NONE);
11068         }
11069     #endif
11070         if (ret != 0)
11071             return VERIFY_MAC_ERROR;
11072 
11073         wc_Md5Free(&md5);
11074     }
11075     else {
11076         ret =  wc_InitSha_ex(&sha, ssl->heap, ssl->devId);
11077         if (ret != 0)
11078             return ret;
11079 
11080         /* inner */
11081         ret =  wc_ShaUpdate(&sha, macSecret, digestSz);
11082         ret |= wc_ShaUpdate(&sha, PAD1, padSz);
11083         ret |= wc_ShaUpdate(&sha, seq, SEQ_SZ);
11084         ret |= wc_ShaUpdate(&sha, conLen, sizeof(conLen));
11085         /* in buffer */
11086         ret |= wc_ShaUpdate(&sha, in, sz);
11087         if (ret != 0)
11088             return VERIFY_MAC_ERROR;
11089         ret = wc_ShaFinal(&sha, result);
11090     #ifdef WOLFSSL_ASYNC_CRYPT
11091         /* TODO: Make non-blocking */
11092         if (ret == WC_PENDING_E) {
11093             ret = wc_AsyncWait(ret, &sha.asyncDev, WC_ASYNC_FLAG_NONE);
11094         }
11095     #endif
11096         if (ret != 0)
11097             return VERIFY_MAC_ERROR;
11098 
11099         /* outer */
11100         ret =  wc_ShaUpdate(&sha, macSecret, digestSz);
11101         ret |= wc_ShaUpdate(&sha, PAD2, padSz);
11102         ret |= wc_ShaUpdate(&sha, result, digestSz);
11103         if (ret != 0)
11104             return VERIFY_MAC_ERROR;
11105         ret =  wc_ShaFinal(&sha, digest);
11106     #ifdef WOLFSSL_ASYNC_CRYPT
11107         /* TODO: Make non-blocking */
11108         if (ret == WC_PENDING_E) {
11109             ret = wc_AsyncWait(ret, &sha.asyncDev, WC_ASYNC_FLAG_NONE);
11110         }
11111     #endif
11112         if (ret != 0)
11113             return VERIFY_MAC_ERROR;
11114 
11115         wc_ShaFree(&sha);
11116     }
11117     return 0;
11118 }
11119 #endif /* NO_OLD_TLS */
11120 
11121 
11122 #ifndef NO_CERTS
11123 
11124 #if !defined(NO_MD5) && !defined(NO_OLD_TLS)
11125 static int BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
11126 {
11127     int ret;
11128     byte md5_result[MD5_DIGEST_SIZE];
11129 #ifdef WOLFSSL_SMALL_STACK
11130     Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11131 #else
11132     Md5  md5[1];
11133 #endif
11134 
11135     /* make md5 inner */
11136     ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5); /* Save current position */
11137     if (ret == 0)
11138         ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN);
11139     if (ret == 0)
11140         ret = wc_Md5Update(md5, PAD1, PAD_MD5);
11141     if (ret == 0)
11142         ret = wc_Md5Final(md5, md5_result);
11143 
11144     /* make md5 outer */
11145     if (ret == 0) {
11146         ret = wc_InitMd5_ex(md5, ssl->heap, ssl->devId);
11147         if (ret == 0) {
11148             ret = wc_Md5Update(md5, ssl->arrays->masterSecret, SECRET_LEN);
11149             if (ret == 0)
11150                 ret = wc_Md5Update(md5, PAD2, PAD_MD5);
11151             if (ret == 0)
11152                 ret = wc_Md5Update(md5, md5_result, MD5_DIGEST_SIZE);
11153             if (ret == 0)
11154                 ret = wc_Md5Final(md5, digest);
11155             wc_Md5Free(md5);
11156         }
11157     }
11158 
11159 #ifdef WOLFSSL_SMALL_STACK
11160     XFREE(md5, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11161 #endif
11162 
11163     return ret;
11164 }
11165 #endif /* !NO_MD5 && !NO_OLD_TLS */
11166 
11167 #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
11168                               defined(WOLFSSL_ALLOW_TLS_SHA1))
11169 static int BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
11170 {
11171     int ret;
11172     byte sha_result[SHA_DIGEST_SIZE];
11173 #ifdef WOLFSSL_SMALL_STACK
11174     Sha* sha = (Sha*)XMALLOC(sizeof(Sha), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11175 #else
11176     Sha  sha[1];
11177 #endif
11178 
11179     /* make sha inner */
11180     ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */
11181     if (ret == 0)
11182         ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
11183     if (ret == 0)
11184         ret = wc_ShaUpdate(sha, PAD1, PAD_SHA);
11185     if (ret == 0)
11186         ret = wc_ShaFinal(sha, sha_result);
11187 
11188     /* make sha outer */
11189     if (ret == 0) {
11190         ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId);
11191         if (ret == 0) {
11192             ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN);
11193             if (ret == 0)
11194                 ret = wc_ShaUpdate(sha, PAD2, PAD_SHA);
11195             if (ret == 0)
11196                 ret = wc_ShaUpdate(sha, sha_result, SHA_DIGEST_SIZE);
11197             if (ret == 0)
11198                 ret = wc_ShaFinal(sha, digest);
11199             wc_ShaFree(sha);
11200         }
11201     }
11202 
11203 #ifdef WOLFSSL_SMALL_STACK
11204     XFREE(sha, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11205 #endif
11206 
11207     return ret;
11208 }
11209 #endif /* !NO_SHA && (!NO_OLD_TLS || WOLFSSL_ALLOW_TLS_SHA1) */
11210 
11211 int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
11212 {
11213     int ret = 0;
11214 
11215     (void)hashes;
11216 
11217     if (ssl->options.tls) {
11218     #if !defined(NO_MD5) && !defined(NO_OLD_TLS)
11219         ret = wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
11220         if (ret != 0)
11221             return ret;
11222     #endif
11223     #if !defined(NO_SHA)
11224         ret = wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
11225         if (ret != 0)
11226             return ret;
11227     #endif
11228         if (IsAtLeastTLSv1_2(ssl)) {
11229             #ifndef NO_SHA256
11230                 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,
11231                                        hashes->sha256);
11232                 if (ret != 0)
11233                     return ret;
11234             #endif
11235             #ifdef WOLFSSL_SHA384
11236                 ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384,
11237                                        hashes->sha384);
11238                 if (ret != 0)
11239                     return ret;
11240             #endif
11241             #ifdef WOLFSSL_SHA512
11242                 ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512,
11243                                        hashes->sha512);
11244                 if (ret != 0)
11245                     return ret;
11246             #endif
11247         }
11248     }
11249     else {
11250     #if !defined(NO_MD5) && !defined(NO_OLD_TLS)
11251         ret = BuildMD5_CertVerify(ssl, hashes->md5);
11252         if (ret != 0)
11253             return ret;
11254     #endif
11255     #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
11256                               defined(WOLFSSL_ALLOW_TLS_SHA1))
11257         ret = BuildSHA_CertVerify(ssl, hashes->sha);
11258         if (ret != 0)
11259             return ret;
11260     #endif
11261     }
11262 
11263     return ret;
11264 }
11265 
11266 #endif /* WOLFSSL_LEANPSK */
11267 
11268 /* Persistable BuildMessage arguments */
11269 typedef struct BuildMsgArgs {
11270     word32 digestSz;
11271     word32 sz;
11272     word32 pad;
11273     word32 idx;
11274     word32 headerSz;
11275     word16 size;
11276     word32 ivSz;      /* TLSv1.1  IV */
11277     byte   iv[AES_BLOCK_SIZE]; /* max size */
11278 } BuildMsgArgs;
11279 
11280 static void FreeBuildMsgArgs(WOLFSSL* ssl, void* pArgs)
11281 {
11282     BuildMsgArgs* args = (BuildMsgArgs*)pArgs;
11283 
11284     (void)ssl;
11285     (void)args;
11286 
11287     /* no allocations in BuildMessage */
11288 }
11289 
11290 /* Build SSL Message, encrypted */
11291 int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
11292              int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay)
11293 {
11294     int ret = 0;
11295 #ifdef WOLFSSL_ASYNC_CRYPT
11296     BuildMsgArgs* args = (BuildMsgArgs*)ssl->async.args;
11297     typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
11298     (void)sizeof(args_test);
11299 #else
11300     BuildMsgArgs  args[1];
11301 #endif
11302 
11303     WOLFSSL_ENTER("BuildMessage");
11304 
11305     if (ssl == NULL) {
11306         return BAD_FUNC_ARG;
11307     }
11308 
11309 #ifdef WOLFSSL_TLS13
11310     if (ssl->options.tls1_3) {
11311         return BuildTls13Message(ssl, output, outSz, input, inSz, type,
11312                                  hashOutput, sizeOnly);
11313     }
11314 #endif
11315 
11316     /* catch mistaken sizeOnly parameter */
11317     if (sizeOnly && (output || input) ) {
11318         WOLFSSL_MSG("BuildMessage with sizeOnly doesn't need input or output");
11319         return BAD_FUNC_ARG;
11320     }
11321 
11322     ret = WC_NOT_PENDING_E;
11323 #ifdef WOLFSSL_ASYNC_CRYPT
11324     if (asyncOkay) {
11325         ret = wolfSSL_AsyncPop(ssl, &ssl->options.buildMsgState);
11326         if (ret != WC_NOT_PENDING_E) {
11327             /* Check for error */
11328             if (ret < 0)
11329                 goto exit_buildmsg;
11330         }
11331     }
11332 #endif
11333 
11334     /* Reset state */
11335     if (ret == WC_NOT_PENDING_E) {
11336         ret = 0;
11337         ssl->options.buildMsgState = BUILD_MSG_BEGIN;
11338         XMEMSET(args, 0, sizeof(BuildMsgArgs));
11339 
11340         args->sz = RECORD_HEADER_SZ + inSz;
11341         args->idx  = RECORD_HEADER_SZ;
11342         args->headerSz = RECORD_HEADER_SZ;
11343     #ifdef WOLFSSL_ASYNC_CRYPT
11344         ssl->async.freeArgs = FreeBuildMsgArgs;
11345     #endif
11346     }
11347 
11348     switch (ssl->options.buildMsgState) {
11349         case BUILD_MSG_BEGIN:
11350         {
11351             /* catch mistaken sizeOnly parameter */
11352             if (!sizeOnly && (output == NULL || input == NULL) ) {
11353                 return BAD_FUNC_ARG;
11354             }
11355             if (sizeOnly && (output || input) ) {
11356                 WOLFSSL_MSG("BuildMessage w/sizeOnly doesn't need input/output");
11357                 return BAD_FUNC_ARG;
11358             }
11359 
11360             ssl->options.buildMsgState = BUILD_MSG_SIZE;
11361         }
11362 
11363         case BUILD_MSG_SIZE:
11364         {
11365             args->digestSz = ssl->specs.hash_size;
11366         #ifdef HAVE_TRUNCATED_HMAC
11367             if (ssl->truncated_hmac)
11368                 args->digestSz = min(TRUNCATED_HMAC_SZ, args->digestSz);
11369         #endif
11370             args->sz += args->digestSz;
11371 
11372         #ifdef WOLFSSL_DTLS
11373             if (ssl->options.dtls) {
11374                 args->sz       += DTLS_RECORD_EXTRA;
11375                 args->idx      += DTLS_RECORD_EXTRA;
11376                 args->headerSz += DTLS_RECORD_EXTRA;
11377             }
11378         #endif
11379 
11380             if (ssl->specs.cipher_type == block) {
11381                 word32 blockSz = ssl->specs.block_size;
11382                 if (ssl->options.tls1_1) {
11383                     args->ivSz = blockSz;
11384                     args->sz  += args->ivSz;
11385 
11386                     if (args->ivSz > (word32)sizeof(args->iv))
11387                         ERROR_OUT(BUFFER_E, exit_buildmsg);
11388                 }
11389                 args->sz += 1;       /* pad byte */
11390                 args->pad = (args->sz - args->headerSz) % blockSz;
11391                 args->pad = blockSz - args->pad;
11392                 args->sz += args->pad;
11393             }
11394 
11395         #ifdef HAVE_AEAD
11396             if (ssl->specs.cipher_type == aead) {
11397                 if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
11398                     args->ivSz = AESGCM_EXP_IV_SZ;
11399 
11400                 args->sz += (args->ivSz + ssl->specs.aead_mac_size - args->digestSz);
11401             }
11402         #endif
11403 
11404             /* done with size calculations */
11405             if (sizeOnly)
11406                 goto exit_buildmsg;
11407 
11408             if (args->sz > (word32)outSz) {
11409                 WOLFSSL_MSG("Oops, want to write past output buffer size");
11410                 ERROR_OUT(BUFFER_E, exit_buildmsg);
11411             }
11412 
11413             if (args->ivSz > 0) {
11414                 ret = wc_RNG_GenerateBlock(ssl->rng, args->iv, args->ivSz);
11415                 if (ret != 0)
11416                     goto exit_buildmsg;
11417 
11418             }
11419 
11420         #ifdef HAVE_AEAD
11421             if (ssl->specs.cipher_type == aead) {
11422                 if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
11423                     XMEMCPY(args->iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
11424             }
11425         #endif
11426 
11427             args->size = (word16)(args->sz - args->headerSz);    /* include mac and digest */
11428             AddRecordHeader(output, args->size, (byte)type, ssl);
11429 
11430             /* write to output */
11431             if (args->ivSz) {
11432                 XMEMCPY(output + args->idx, args->iv,
11433                                         min(args->ivSz, sizeof(args->iv)));
11434                 args->idx += args->ivSz;
11435             }
11436             XMEMCPY(output + args->idx, input, inSz);
11437             args->idx += inSz;
11438 
11439             ssl->options.buildMsgState = BUILD_MSG_HASH;
11440         }
11441         case BUILD_MSG_HASH:
11442         {
11443             word32 i;
11444 
11445             if (type == handshake && hashOutput) {
11446                 ret = HashOutput(ssl, output, args->headerSz + inSz, args->ivSz);
11447                 if (ret != 0)
11448                     goto exit_buildmsg;
11449             }
11450             if (ssl->specs.cipher_type == block) {
11451                 word32 tmpIdx = args->idx + args->digestSz;
11452 
11453                 for (i = 0; i <= args->pad; i++)
11454                     output[tmpIdx++] = (byte)args->pad; /* pad byte gets pad value */
11455             }
11456 
11457             ssl->options.buildMsgState = BUILD_MSG_VERIFY_MAC;
11458         }
11459         case BUILD_MSG_VERIFY_MAC:
11460         {
11461             /* User Record Layer Callback handling */
11462         #ifdef ATOMIC_USER
11463             if (ssl->ctx->MacEncryptCb) {
11464                 ret = ssl->ctx->MacEncryptCb(ssl, output + args->idx,
11465                                 output + args->headerSz + args->ivSz, inSz, type, 0,
11466                                 output + args->headerSz, output + args->headerSz, args->size,
11467                                 ssl->MacEncryptCtx);
11468                 goto exit_buildmsg;
11469             }
11470         #endif
11471 
11472             if (ssl->specs.cipher_type != aead) {
11473         #ifdef HAVE_TRUNCATED_HMAC
11474             if (ssl->truncated_hmac && ssl->specs.hash_size > args->digestSz) {
11475             #ifdef WOLFSSL_SMALL_STACK
11476                 byte* hmac = NULL;
11477             #else
11478                 byte  hmac[MAX_DIGEST_SIZE];
11479             #endif
11480 
11481             #ifdef WOLFSSL_SMALL_STACK
11482                 hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, ssl->heap,
11483                                                        DYNAMIC_TYPE_TMP_BUFFER);
11484                 if (hmac == NULL)
11485                     ERROR_OUT(MEMORY_E, exit_buildmsg);
11486             #endif
11487 
11488                 ret = ssl->hmac(ssl, hmac, output + args->headerSz + args->ivSz, inSz,
11489                                                                        type, 0);
11490                 XMEMCPY(output + args->idx, hmac, args->digestSz);
11491 
11492             #ifdef WOLFSSL_SMALL_STACK
11493                 XFREE(hmac, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11494             #endif
11495             }
11496             else
11497         #endif
11498                 ret = ssl->hmac(ssl, output + args->idx, output + args->headerSz + args->ivSz,
11499                                                                 inSz, type, 0);
11500             #ifdef WOLFSSL_DTLS
11501                 if (ssl->options.dtls)
11502                     DtlsSEQIncrement(ssl, CUR_ORDER);
11503             #endif
11504             }
11505             if (ret != 0)
11506                 goto exit_buildmsg;
11507 
11508             ssl->options.buildMsgState = BUILD_MSG_ENCRYPT;
11509         }
11510         case BUILD_MSG_ENCRYPT:
11511         {
11512             ret = Encrypt(ssl, output + args->headerSz, output + args->headerSz, args->size,
11513                 asyncOkay);
11514             break;
11515         }
11516     }
11517 
11518 exit_buildmsg:
11519 
11520     WOLFSSL_LEAVE("BuildMessage", ret);
11521 
11522 #ifdef WOLFSSL_ASYNC_CRYPT
11523     if (ret == WC_PENDING_E) {
11524         return ret;
11525     }
11526 #endif
11527 
11528     /* make sure build message state is reset */
11529     ssl->options.buildMsgState = BUILD_MSG_BEGIN;
11530 
11531     /* return sz on success */
11532     if (ret == 0)
11533         ret = args->sz;
11534 
11535     /* Final cleanup */
11536     FreeBuildMsgArgs(ssl, args);
11537 
11538     return ret;
11539 }
11540 
11541 
11542 int SendFinished(WOLFSSL* ssl)
11543 {
11544     int              sendSz,
11545                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
11546                                                      FINISHED_SZ;
11547     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
11548     byte            *output;
11549     Hashes*          hashes;
11550     int              ret;
11551     int              headerSz = HANDSHAKE_HEADER_SZ;
11552     int              outputSz;
11553 
11554     /* setup encrypt keys */
11555     if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
11556         return ret;
11557 
11558     /* check for available size */
11559     outputSz = sizeof(input) + MAX_MSG_EXTRA;
11560     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
11561         return ret;
11562 
11563     #ifdef WOLFSSL_DTLS
11564         if (ssl->options.dtls) {
11565             headerSz += DTLS_HANDSHAKE_EXTRA;
11566             ssl->keys.dtls_epoch++;
11567             ssl->keys.dtls_prev_sequence_number_hi =
11568                     ssl->keys.dtls_sequence_number_hi;
11569             ssl->keys.dtls_prev_sequence_number_lo =
11570                     ssl->keys.dtls_sequence_number_lo;
11571             ssl->keys.dtls_sequence_number_hi = 0;
11572             ssl->keys.dtls_sequence_number_lo = 0;
11573         }
11574     #endif
11575 
11576     /* get output buffer */
11577     output = ssl->buffers.outputBuffer.buffer +
11578              ssl->buffers.outputBuffer.length;
11579 
11580     AddHandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
11581 
11582     /* make finished hashes */
11583     hashes = (Hashes*)&input[headerSz];
11584     ret = BuildFinished(ssl, hashes,
11585                      ssl->options.side == WOLFSSL_CLIENT_END ? client : server);
11586     if (ret != 0) return ret;
11587 
11588 #ifdef HAVE_SECURE_RENEGOTIATION
11589     if (ssl->secure_renegotiation) {
11590         if (ssl->options.side == WOLFSSL_CLIENT_END)
11591             XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
11592                     TLS_FINISHED_SZ);
11593         else
11594             XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
11595                     TLS_FINISHED_SZ);
11596     }
11597 #endif
11598 
11599     #ifdef WOLFSSL_DTLS
11600         if (IsDtlsNotSctpMode(ssl)) {
11601             if ((ret = DtlsMsgPoolSave(ssl, input, headerSz + finishedSz)) != 0)
11602                 return ret;
11603         }
11604     #endif
11605 
11606     sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
11607                                                           handshake, 1, 0, 0);
11608     if (sendSz < 0)
11609         return BUILD_MSG_ERROR;
11610 
11611     if (!ssl->options.resuming) {
11612 #ifndef NO_SESSION_CACHE
11613         AddSession(ssl);    /* just try */
11614 #endif
11615         if (ssl->options.side == WOLFSSL_SERVER_END) {
11616             ssl->options.handShakeState = HANDSHAKE_DONE;
11617             ssl->options.handShakeDone  = 1;
11618         }
11619     }
11620     else {
11621         if (ssl->options.side == WOLFSSL_CLIENT_END) {
11622             ssl->options.handShakeState = HANDSHAKE_DONE;
11623             ssl->options.handShakeDone  = 1;
11624         }
11625     }
11626 
11627     #ifdef WOLFSSL_CALLBACKS
11628         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
11629         if (ssl->toInfoOn)
11630             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
11631                           ssl->heap);
11632     #endif
11633 
11634     ssl->buffers.outputBuffer.length += sendSz;
11635 
11636     return SendBuffered(ssl);
11637 }
11638 
11639 
11640 #ifndef NO_CERTS
11641 int SendCertificate(WOLFSSL* ssl)
11642 {
11643     int    ret = 0;
11644     word32 certSz, certChainSz, headerSz, listSz, payloadSz;
11645     word32 length, maxFragment;
11646 
11647     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
11648         return 0;  /* not needed */
11649 
11650     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
11651         certSz = 0;
11652         certChainSz = 0;
11653         headerSz = CERT_HEADER_SZ;
11654         length = CERT_HEADER_SZ;
11655         listSz = 0;
11656     }
11657     else {
11658         if (!ssl->buffers.certificate) {
11659             WOLFSSL_MSG("Send Cert missing certificate buffer");
11660             return BUFFER_ERROR;
11661         }
11662         certSz = ssl->buffers.certificate->length;
11663         headerSz = 2 * CERT_HEADER_SZ;
11664         /* list + cert size */
11665         length = certSz + headerSz;
11666         listSz = certSz + CERT_HEADER_SZ;
11667 
11668         /* may need to send rest of chain, already has leading size(s) */
11669         if (certSz && ssl->buffers.certChain) {
11670             certChainSz = ssl->buffers.certChain->length;
11671             length += certChainSz;
11672             listSz += certChainSz;
11673         }
11674         else
11675             certChainSz = 0;
11676     }
11677 
11678     payloadSz = length;
11679 
11680     if (ssl->fragOffset != 0)
11681         length -= (ssl->fragOffset + headerSz);
11682 
11683     maxFragment = MAX_RECORD_SIZE;
11684     if (ssl->options.dtls) {
11685     #ifdef WOLFSSL_DTLS
11686         maxFragment = MAX_MTU - DTLS_RECORD_HEADER_SZ
11687                       - DTLS_HANDSHAKE_HEADER_SZ - 100;
11688     #endif /* WOLFSSL_DTLS */
11689     }
11690 
11691     #ifdef HAVE_MAX_FRAGMENT
11692     if (ssl->max_fragment != 0 && maxFragment >= ssl->max_fragment)
11693         maxFragment = ssl->max_fragment;
11694     #endif /* HAVE_MAX_FRAGMENT */
11695 
11696     while (length > 0 && ret == 0) {
11697         byte*  output = NULL;
11698         word32 fragSz = 0;
11699         word32 i = RECORD_HEADER_SZ;
11700         int    sendSz = RECORD_HEADER_SZ;
11701 
11702         if (!ssl->options.dtls) {
11703             if (ssl->fragOffset == 0)  {
11704                 if (headerSz + certSz + certChainSz <=
11705                     maxFragment - HANDSHAKE_HEADER_SZ) {
11706 
11707                     fragSz = headerSz + certSz + certChainSz;
11708                 }
11709                 else {
11710                     fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
11711                 }
11712                 sendSz += fragSz + HANDSHAKE_HEADER_SZ;
11713                 i += HANDSHAKE_HEADER_SZ;
11714             }
11715             else {
11716                 fragSz = min(length, maxFragment);
11717                 sendSz += fragSz;
11718             }
11719 
11720             if (IsEncryptionOn(ssl, 1))
11721                 sendSz += MAX_MSG_EXTRA;
11722         }
11723         else {
11724         #ifdef WOLFSSL_DTLS
11725             fragSz = min(length, maxFragment);
11726             sendSz += fragSz + DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
11727                       + HANDSHAKE_HEADER_SZ;
11728             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
11729                       + HANDSHAKE_HEADER_SZ;
11730         #endif
11731         }
11732 
11733         /* check for available size */
11734         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
11735             return ret;
11736 
11737         /* get output buffer */
11738         output = ssl->buffers.outputBuffer.buffer +
11739                  ssl->buffers.outputBuffer.length;
11740 
11741         if (ssl->fragOffset == 0) {
11742             if (!ssl->options.dtls) {
11743                 AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
11744                 if (!IsEncryptionOn(ssl, 1))
11745                     HashOutputRaw(ssl, output + RECORD_HEADER_SZ,
11746                                   HANDSHAKE_HEADER_SZ);
11747             }
11748             else {
11749             #ifdef WOLFSSL_DTLS
11750                 AddHeaders(output, payloadSz, certificate, ssl);
11751                 if (!IsEncryptionOn(ssl, 1))
11752                     HashOutputRaw(ssl,
11753                                   output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA,
11754                                   HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
11755                 /* Adding the headers increments these, decrement them for
11756                  * actual message header. */
11757                 ssl->keys.dtls_handshake_number--;
11758                 AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
11759                 ssl->keys.dtls_handshake_number--;
11760             #endif /* WOLFSSL_DTLS */
11761             }
11762 
11763             /* list total */
11764             c32to24(listSz, output + i);
11765             if (!IsEncryptionOn(ssl, 1))
11766                 HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
11767             i += CERT_HEADER_SZ;
11768             length -= CERT_HEADER_SZ;
11769             fragSz -= CERT_HEADER_SZ;
11770             if (certSz) {
11771                 c32to24(certSz, output + i);
11772                 if (!IsEncryptionOn(ssl, 1))
11773                     HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
11774                 i += CERT_HEADER_SZ;
11775                 length -= CERT_HEADER_SZ;
11776                 fragSz -= CERT_HEADER_SZ;
11777 
11778                 if (!IsEncryptionOn(ssl, 1)) {
11779                     HashOutputRaw(ssl, ssl->buffers.certificate->buffer, certSz);
11780                     if (certChainSz)
11781                         HashOutputRaw(ssl, ssl->buffers.certChain->buffer,
11782                                       certChainSz);
11783                 }
11784             }
11785         }
11786         else {
11787             if (!ssl->options.dtls) {
11788                 AddRecordHeader(output, fragSz, handshake, ssl);
11789             }
11790             else {
11791             #ifdef WOLFSSL_DTLS
11792                 AddFragHeaders(output, fragSz, ssl->fragOffset + headerSz,
11793                                payloadSz, certificate, ssl);
11794                 ssl->keys.dtls_handshake_number--;
11795             #endif /* WOLFSSL_DTLS */
11796             }
11797         }
11798 
11799         /* member */
11800         if (certSz && ssl->fragOffset < certSz) {
11801             word32 copySz = min(certSz - ssl->fragOffset, fragSz);
11802             XMEMCPY(output + i,
11803                     ssl->buffers.certificate->buffer + ssl->fragOffset, copySz);
11804             i += copySz;
11805             ssl->fragOffset += copySz;
11806             length -= copySz;
11807             fragSz -= copySz;
11808         }
11809         if (certChainSz && fragSz) {
11810             word32 copySz = min(certChainSz + certSz - ssl->fragOffset, fragSz);
11811             XMEMCPY(output + i,
11812                     ssl->buffers.certChain->buffer + ssl->fragOffset - certSz,
11813                     copySz);
11814             i += copySz;
11815             ssl->fragOffset += copySz;
11816             length -= copySz;
11817         }
11818 
11819         if (IsEncryptionOn(ssl, 1)) {
11820             byte* input = NULL;
11821             int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
11822 
11823             if (inputSz < 0) {
11824                 WOLFSSL_MSG("Send Cert bad inputSz");
11825                 return BUFFER_E;
11826             }
11827 
11828             if (inputSz > 0) {  /* clang thinks could be zero, let's help */
11829                 input = (byte*)XMALLOC(inputSz, ssl->heap,
11830                                        DYNAMIC_TYPE_TMP_BUFFER);
11831                 if (input == NULL)
11832                     return MEMORY_E;
11833                 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
11834             }
11835 
11836             sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
11837                                                           handshake, 1, 0, 0);
11838 
11839             if (inputSz > 0)
11840                 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
11841 
11842             if (sendSz < 0)
11843                 return sendSz;
11844         }
11845         else {
11846         #ifdef WOLFSSL_DTLS
11847             if (ssl->options.dtls)
11848                 DtlsSEQIncrement(ssl, CUR_ORDER);
11849         #endif
11850         }
11851 
11852     #ifdef WOLFSSL_DTLS
11853         if (IsDtlsNotSctpMode(ssl)) {
11854             if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
11855                 return ret;
11856         }
11857     #endif
11858 
11859     #ifdef WOLFSSL_CALLBACKS
11860         if (ssl->hsInfoOn)
11861             AddPacketName("Certificate", &ssl->handShakeInfo);
11862         if (ssl->toInfoOn)
11863             AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
11864                            ssl->heap);
11865     #endif
11866 
11867         ssl->buffers.outputBuffer.length += sendSz;
11868         if (!ssl->options.groupMessages)
11869             ret = SendBuffered(ssl);
11870     }
11871 
11872     if (ret != WANT_WRITE) {
11873         /* Clean up the fragment offset. */
11874         ssl->fragOffset = 0;
11875         #ifdef WOLFSSL_DTLS
11876             if (ssl->options.dtls)
11877                 ssl->keys.dtls_handshake_number++;
11878         #endif
11879         if (ssl->options.side == WOLFSSL_SERVER_END)
11880             ssl->options.serverState = SERVER_CERT_COMPLETE;
11881     }
11882 
11883     return ret;
11884 }
11885 
11886 
11887 int SendCertificateRequest(WOLFSSL* ssl)
11888 {
11889     byte   *output;
11890     int    ret;
11891     int    sendSz;
11892     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11893 
11894     int  typeTotal = 1;  /* only 1 for now */
11895     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
11896 
11897     if (IsAtLeastTLSv1_2(ssl))
11898         reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
11899 
11900     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
11901         return 0;  /* not needed */
11902 
11903     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
11904 
11905     #ifdef WOLFSSL_DTLS
11906         if (ssl->options.dtls) {
11907             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11908             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
11909         }
11910     #endif
11911     /* check for available size */
11912     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
11913         return ret;
11914 
11915     /* get output buffer */
11916     output = ssl->buffers.outputBuffer.buffer +
11917              ssl->buffers.outputBuffer.length;
11918 
11919     AddHeaders(output, reqSz, certificate_request, ssl);
11920 
11921     /* write to output */
11922     output[i++] = (byte)typeTotal;  /* # of types */
11923 #ifdef HAVE_ECC
11924     if ((ssl->options.cipherSuite0 == ECC_BYTE ||
11925          ssl->options.cipherSuite0 == CHACHA_BYTE) &&
11926                      ssl->specs.sig_algo == ecc_dsa_sa_algo) {
11927         output[i++] = ecdsa_sign;
11928     } else
11929 #endif /* HAVE_ECC */
11930     {
11931         output[i++] = rsa_sign;
11932     }
11933 
11934     /* supported hash/sig */
11935     if (IsAtLeastTLSv1_2(ssl)) {
11936         c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
11937         i += LENGTH_SZ;
11938 
11939         XMEMCPY(&output[i],
11940                          ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
11941         i += ssl->suites->hashSigAlgoSz;
11942     }
11943 
11944     c16toa(0, &output[i]);  /* auth's */
11945     /* if add more to output, adjust i
11946     i += REQ_HEADER_SZ; */
11947 
11948     #ifdef WOLFSSL_DTLS
11949         if (IsDtlsNotSctpMode(ssl)) {
11950             if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
11951                 return ret;
11952         }
11953         if (ssl->options.dtls)
11954             DtlsSEQIncrement(ssl, CUR_ORDER);
11955     #endif
11956 
11957     ret = HashOutput(ssl, output, sendSz, 0);
11958     if (ret != 0)
11959         return ret;
11960 
11961     #ifdef WOLFSSL_CALLBACKS
11962         if (ssl->hsInfoOn)
11963             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
11964         if (ssl->toInfoOn)
11965             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
11966                           sendSz, ssl->heap);
11967     #endif
11968     ssl->buffers.outputBuffer.length += sendSz;
11969     if (ssl->options.groupMessages)
11970         return 0;
11971     else
11972         return SendBuffered(ssl);
11973 }
11974 
11975 #ifndef NO_WOLFSSL_SERVER
11976 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
11977  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
11978 static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
11979                                                                      byte count)
11980 {
11981     byte*  output  = NULL;
11982     word32 idx     = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
11983     word32 length  = ENUM_LEN;
11984     int    sendSz  = 0;
11985     int    ret     = 0;
11986     int    i       = 0;
11987 
11988     WOLFSSL_ENTER("BuildCertificateStatus");
11989 
11990     switch (type) {
11991         case WOLFSSL_CSR2_OCSP_MULTI:
11992             length += OPAQUE24_LEN;
11993             /* followed by */
11994 
11995         case WOLFSSL_CSR2_OCSP:
11996             for (i = 0; i < count; i++)
11997                 length += OPAQUE24_LEN + status[i].length;
11998         break;
11999 
12000         default:
12001             return 0;
12002     }
12003 
12004     sendSz = idx + length;
12005 
12006     if (ssl->keys.encryptionOn)
12007         sendSz += MAX_MSG_EXTRA;
12008 
12009     if ((ret = CheckAvailableSize(ssl, sendSz)) == 0) {
12010         output = ssl->buffers.outputBuffer.buffer +
12011                  ssl->buffers.outputBuffer.length;
12012 
12013         AddHeaders(output, length, certificate_status, ssl);
12014 
12015         output[idx++] = type;
12016 
12017         if (type == WOLFSSL_CSR2_OCSP_MULTI) {
12018             c32to24(length - (ENUM_LEN + OPAQUE24_LEN), output + idx);
12019             idx += OPAQUE24_LEN;
12020         }
12021 
12022         for (i = 0; i < count; i++) {
12023             c32to24(status[i].length, output + idx);
12024             idx += OPAQUE24_LEN;
12025 
12026             XMEMCPY(output + idx, status[i].buffer, status[i].length);
12027             idx += status[i].length;
12028         }
12029 
12030         if (IsEncryptionOn(ssl, 1)) {
12031             byte* input;
12032             int   inputSz = idx - RECORD_HEADER_SZ;
12033 
12034             input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12035             if (input == NULL)
12036                 return MEMORY_E;
12037 
12038             XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
12039             sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
12040                                                            handshake, 1, 0, 0);
12041             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12042 
12043             if (sendSz < 0)
12044                 ret = sendSz;
12045         }
12046         else {
12047             #ifdef WOLFSSL_DTLS
12048                 if (ssl->options.dtls)
12049                     DtlsSEQIncrement(ssl, CUR_ORDER);
12050             #endif
12051             ret = HashOutput(ssl, output, sendSz, 0);
12052         }
12053 
12054     #ifdef WOLFSSL_DTLS
12055         if (ret == 0 && IsDtlsNotSctpMode(ssl))
12056             ret = DtlsMsgPoolSave(ssl, output, sendSz);
12057     #endif
12058 
12059     #ifdef WOLFSSL_CALLBACKS
12060         if (ret == 0 && ssl->hsInfoOn)
12061             AddPacketName("CertificateStatus", &ssl->handShakeInfo);
12062         if (ret == 0 && ssl->toInfoOn)
12063             AddPacketInfo("CertificateStatus", &ssl->timeoutInfo, output,
12064                                                              sendSz, ssl->heap);
12065     #endif
12066 
12067         if (ret == 0) {
12068             ssl->buffers.outputBuffer.length += sendSz;
12069             if (!ssl->options.groupMessages)
12070                 ret = SendBuffered(ssl);
12071         }
12072     }
12073 
12074     WOLFSSL_LEAVE("BuildCertificateStatus", ret);
12075     return ret;
12076 }
12077 #endif
12078 #endif /* NO_WOLFSSL_SERVER */
12079 
12080 
12081 int SendCertificateStatus(WOLFSSL* ssl)
12082 {
12083     int ret = 0;
12084     byte status_type = 0;
12085 
12086     WOLFSSL_ENTER("SendCertificateStatus");
12087 
12088     (void) ssl;
12089 
12090 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
12091     status_type = ssl->status_request;
12092 #endif
12093 
12094 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
12095     status_type = status_type ? status_type : ssl->status_request_v2;
12096 #endif
12097 
12098     switch (status_type) {
12099 
12100     #ifndef NO_WOLFSSL_SERVER
12101     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
12102      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
12103         /* case WOLFSSL_CSR_OCSP: */
12104         case WOLFSSL_CSR2_OCSP:
12105         {
12106             OcspRequest* request = ssl->ctx->certOcspRequest;
12107             buffer response;
12108 
12109             XMEMSET(&response, 0, sizeof(response));
12110 
12111             /* unable to fetch status. skip. */
12112             if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
12113                 return 0;
12114 
12115             if (request == NULL || ssl->buffers.weOwnCert) {
12116                 DerBuffer* der = ssl->buffers.certificate;
12117                 #ifdef WOLFSSL_SMALL_STACK
12118                     DecodedCert* cert = NULL;
12119                 #else
12120                     DecodedCert  cert[1];
12121                 #endif
12122 
12123                 /* unable to fetch status. skip. */
12124                 if (der->buffer == NULL || der->length == 0)
12125                     return 0;
12126 
12127             #ifdef WOLFSSL_SMALL_STACK
12128                 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
12129                                                    DYNAMIC_TYPE_TMP_BUFFER);
12130                 if (cert == NULL)
12131                     return MEMORY_E;
12132             #endif
12133 
12134                 InitDecodedCert(cert, der->buffer, der->length, ssl->heap);
12135                 /* TODO: Setup async support here */
12136                 if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
12137                                                           ssl->ctx->cm)) != 0) {
12138                     WOLFSSL_MSG("ParseCert failed");
12139                 }
12140                 else {
12141                     request = (OcspRequest*)XMALLOC(sizeof(OcspRequest),
12142                                           ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12143                     if (request) {
12144                         ret = InitOcspRequest(request, cert, 0, ssl->heap);
12145                         if (ret == 0) {
12146                             /* make sure ctx OCSP request is updated */
12147                             if (!ssl->buffers.weOwnCert) {
12148                                 wolfSSL_Mutex* ocspLock =
12149                                     &ssl->ctx->cm->ocsp_stapling->ocspLock;
12150                                 if (wc_LockMutex(ocspLock) == 0) {
12151                                     if (ssl->ctx->certOcspRequest == NULL)
12152                                         ssl->ctx->certOcspRequest = request;
12153                                     wc_UnLockMutex(ocspLock);
12154                                 }
12155                             }
12156                         }
12157                         else {
12158                             XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12159                             request = NULL;
12160                         }
12161                     }
12162                     else {
12163                         ret = MEMORY_E;
12164                     }
12165                 }
12166 
12167                 FreeDecodedCert(cert);
12168 
12169             #ifdef WOLFSSL_SMALL_STACK
12170                 XFREE(cert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12171             #endif
12172             }
12173 
12174             if (ret == 0) {
12175             #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12176                 request->ssl = ssl;
12177             #endif
12178                 ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
12179                                                                      &response);
12180 
12181                 /* Suppressing, not critical */
12182                 if (ret == OCSP_CERT_REVOKED ||
12183                     ret == OCSP_CERT_UNKNOWN ||
12184                     ret == OCSP_LOOKUP_FAIL) {
12185                     ret = 0;
12186                 }
12187 
12188                 if (response.buffer) {
12189                     if (ret == 0)
12190                         ret = BuildCertificateStatus(ssl, status_type,
12191                                                                   &response, 1);
12192 
12193                     XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12194                 }
12195 
12196             }
12197 
12198             if (request != ssl->ctx->certOcspRequest)
12199                 XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12200 
12201             break;
12202         }
12203 
12204     #endif /* HAVE_CERTIFICATE_STATUS_REQUEST    */
12205            /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
12206 
12207     #if defined HAVE_CERTIFICATE_STATUS_REQUEST_V2
12208         case WOLFSSL_CSR2_OCSP_MULTI:
12209         {
12210             OcspRequest* request = ssl->ctx->certOcspRequest;
12211             buffer responses[1 + MAX_CHAIN_DEPTH];
12212             int i = 0;
12213 
12214             XMEMSET(responses, 0, sizeof(responses));
12215 
12216             /* unable to fetch status. skip. */
12217             if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
12218                 return 0;
12219 
12220             if (!request || ssl->buffers.weOwnCert) {
12221                 DerBuffer* der = ssl->buffers.certificate;
12222             #ifdef WOLFSSL_SMALL_STACK
12223                 DecodedCert* cert = NULL;
12224             #else
12225                 DecodedCert  cert[1];
12226             #endif
12227 
12228                 /* unable to fetch status. skip. */
12229                 if (der->buffer == NULL || der->length == 0)
12230                     return 0;
12231 
12232             #ifdef WOLFSSL_SMALL_STACK
12233                 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
12234                                                DYNAMIC_TYPE_TMP_BUFFER);
12235                 if (cert == NULL)
12236                     return MEMORY_E;
12237             #endif
12238 
12239                 InitDecodedCert(cert, der->buffer, der->length, ssl->heap);
12240                 /* TODO: Setup async support here */
12241                 if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
12242                                                           ssl->ctx->cm)) != 0) {
12243                     WOLFSSL_MSG("ParseCert failed");
12244                 }
12245                 else {
12246                     request = (OcspRequest*)XMALLOC(sizeof(OcspRequest),
12247                                           ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12248                     if (request) {
12249                         ret = InitOcspRequest(request, cert, 0, ssl->heap);
12250                         if (ret == 0) {
12251                             /* make sure ctx OCSP request is updated */
12252                             if (!ssl->buffers.weOwnCert) {
12253                                 wolfSSL_Mutex* ocspLock =
12254                                     &ssl->ctx->cm->ocsp_stapling->ocspLock;
12255                                 if (wc_LockMutex(ocspLock) == 0) {
12256                                     if (ssl->ctx->certOcspRequest == NULL)
12257                                         ssl->ctx->certOcspRequest = request;
12258                                     wc_UnLockMutex(ocspLock);
12259                                 }
12260                             }
12261                         }
12262                         else {
12263                             XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12264                             request = NULL;
12265                         }
12266                     }
12267                     else {
12268                         ret = MEMORY_E;
12269                     }
12270                 }
12271 
12272                 FreeDecodedCert(cert);
12273 
12274             #ifdef WOLFSSL_SMALL_STACK
12275                 XFREE(cert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12276             #endif
12277             }
12278 
12279             if (ret == 0) {
12280             #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12281                 request->ssl = ssl;
12282             #endif
12283                 ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
12284                                                                  &responses[0]);
12285 
12286                 /* Suppressing, not critical */
12287                 if (ret == OCSP_CERT_REVOKED ||
12288                     ret == OCSP_CERT_UNKNOWN ||
12289                     ret == OCSP_LOOKUP_FAIL) {
12290                     ret = 0;
12291                 }
12292             }
12293 
12294             if (request != ssl->ctx->certOcspRequest)
12295                 XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12296 
12297             if (ret == 0 && (!ssl->ctx->chainOcspRequest[0]
12298                                               || ssl->buffers.weOwnCertChain)) {
12299                 buffer der;
12300                 word32 idx = 0;
12301             #ifdef WOLFSSL_SMALL_STACK
12302                 DecodedCert* cert = NULL;
12303             #else
12304                 DecodedCert  cert[1];
12305             #endif
12306 
12307                 XMEMSET(&der, 0, sizeof(buffer));
12308 
12309             #ifdef WOLFSSL_SMALL_STACK
12310                 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
12311                                                DYNAMIC_TYPE_TMP_BUFFER);
12312                 if (cert == NULL)
12313                     return MEMORY_E;
12314             #endif
12315 
12316                 while (idx + OPAQUE24_LEN < ssl->buffers.certChain->length) {
12317                     c24to32(ssl->buffers.certChain->buffer + idx, &der.length);
12318                     idx += OPAQUE24_LEN;
12319 
12320                     der.buffer = ssl->buffers.certChain->buffer + idx;
12321                     idx += der.length;
12322 
12323                     if (idx > ssl->buffers.certChain->length)
12324                         break;
12325 
12326                     InitDecodedCert(cert, der.buffer, der.length, ssl->heap);
12327                     /* TODO: Setup async support here */
12328                     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
12329                                                       ssl->ctx->cm)) != 0) {
12330                         WOLFSSL_MSG("ParseCert failed");
12331                         break;
12332                     }
12333                     else {
12334                         request = (OcspRequest*)XMALLOC(sizeof(OcspRequest),
12335                                           ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12336                         if (request == NULL) {
12337                             FreeDecodedCert(cert);
12338 
12339                             ret = MEMORY_E;
12340                             break;
12341                         }
12342 
12343                         ret = InitOcspRequest(request, cert, 0, ssl->heap);
12344                         if (ret == 0) {
12345                             /* make sure ctx OCSP request is updated */
12346                             if (!ssl->buffers.weOwnCertChain) {
12347                                 wolfSSL_Mutex* ocspLock =
12348                                     &ssl->ctx->cm->ocsp_stapling->ocspLock;
12349                                 if (wc_LockMutex(ocspLock) == 0) {
12350                                     if (ssl->ctx->chainOcspRequest[i] == NULL)
12351                                         ssl->ctx->chainOcspRequest[i] = request;
12352                                     wc_UnLockMutex(ocspLock);
12353                                 }
12354                             }
12355                         }
12356                         else {
12357                             FreeDecodedCert(cert);
12358                             XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12359                             request = NULL;
12360                             break;
12361                         }
12362 
12363                     #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12364                         request->ssl = ssl;
12365                     #endif
12366                         ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
12367                                                     request, &responses[i + 1]);
12368 
12369                         /* Suppressing, not critical */
12370                         if (ret == OCSP_CERT_REVOKED ||
12371                             ret == OCSP_CERT_UNKNOWN ||
12372                             ret == OCSP_LOOKUP_FAIL) {
12373                             ret = 0;
12374                         }
12375 
12376                         if (request != ssl->ctx->chainOcspRequest[i])
12377                             XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
12378 
12379                         i++;
12380                     }
12381 
12382                     FreeDecodedCert(cert);
12383                 }
12384 
12385             #ifdef WOLFSSL_SMALL_STACK
12386                 XFREE(cert, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
12387             #endif
12388             }
12389             else {
12390                 while (ret == 0 &&
12391                             NULL != (request = ssl->ctx->chainOcspRequest[i])) {
12392                 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
12393                     request->ssl = ssl;
12394                 #endif
12395                     ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
12396                                                 request, &responses[++i]);
12397 
12398                     /* Suppressing, not critical */
12399                     if (ret == OCSP_CERT_REVOKED ||
12400                         ret == OCSP_CERT_UNKNOWN ||
12401                         ret == OCSP_LOOKUP_FAIL) {
12402                         ret = 0;
12403                     }
12404                 }
12405             }
12406 
12407             if (responses[0].buffer) {
12408                 if (ret == 0)
12409                     ret = BuildCertificateStatus(ssl, status_type,
12410                                                         responses, (byte)i + 1);
12411 
12412                 for (i = 0; i < 1 + MAX_CHAIN_DEPTH; i++)
12413                     if (responses[i].buffer)
12414                         XFREE(responses[i].buffer, ssl->heap,
12415                                                        DYNAMIC_TYPE_TMP_BUFFER);
12416             }
12417 
12418             break;
12419         }
12420     #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
12421     #endif /* NO_WOLFSSL_SERVER */
12422 
12423         default:
12424             break;
12425     }
12426 
12427     return ret;
12428 }
12429 
12430 #endif /* !NO_CERTS */
12431 
12432 
12433 int SendData(WOLFSSL* ssl, const void* data, int sz)
12434 {
12435     int sent = 0,  /* plainText size */
12436         sendSz,
12437         ret,
12438         dtlsExtra = 0;
12439 
12440     if (ssl->error == WANT_WRITE || ssl->error == WC_PENDING_E)
12441         ssl->error = 0;
12442 
12443     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
12444         int err;
12445         WOLFSSL_MSG("handshake not complete, trying to finish");
12446         if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) {
12447             /* if async would block return WANT_WRITE */
12448             if (ssl->error == WC_PENDING_E) {
12449                 return WOLFSSL_CBIO_ERR_WANT_WRITE;
12450             }
12451             return  err;
12452         }
12453     }
12454 
12455     /* last time system socket output buffer was full, try again to send */
12456     if (ssl->buffers.outputBuffer.length > 0) {
12457         WOLFSSL_MSG("output buffer was full, trying to send again");
12458         if ( (ssl->error = SendBuffered(ssl)) < 0) {
12459             WOLFSSL_ERROR(ssl->error);
12460             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
12461                 return 0;     /* peer reset */
12462             return ssl->error;
12463         }
12464         else {
12465             /* advance sent to previous sent + plain size just sent */
12466             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
12467             WOLFSSL_MSG("sent write buffered data");
12468 
12469             if (sent > sz) {
12470                 WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
12471                 return ssl->error = BAD_FUNC_ARG;
12472             }
12473         }
12474     }
12475 
12476 #ifdef WOLFSSL_DTLS
12477     if (ssl->options.dtls) {
12478         dtlsExtra = DTLS_RECORD_EXTRA;
12479     }
12480 #endif
12481 
12482     for (;;) {
12483         int   len;
12484         byte* out;
12485         byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
12486         int   buffSz;                           /* may switch on comp */
12487         int   outputSz;
12488 #ifdef HAVE_LIBZ
12489         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
12490 #endif
12491 
12492         if (sent == sz) break;
12493 
12494         len = min(sz - sent, OUTPUT_RECORD_SIZE);
12495 #ifdef HAVE_MAX_FRAGMENT
12496         len = min(len, ssl->max_fragment);
12497 #endif
12498 
12499 #ifdef WOLFSSL_DTLS
12500         if (IsDtlsNotSctpMode(ssl)) {
12501             len = min(len, MAX_UDP_SIZE);
12502         }
12503 #endif
12504         buffSz = len;
12505 
12506         /* check for available size */
12507         outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
12508         if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
12509             return ssl->error = ret;
12510 
12511         /* get output buffer */
12512         out = ssl->buffers.outputBuffer.buffer +
12513               ssl->buffers.outputBuffer.length;
12514 
12515 #ifdef HAVE_LIBZ
12516         if (ssl->options.usingCompression) {
12517             buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
12518             if (buffSz < 0) {
12519                 return buffSz;
12520             }
12521             sendBuffer = comp;
12522         }
12523 #endif
12524         if (!ssl->options.tls1_3) {
12525             sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
12526                                   application_data, 0, 0, 1);
12527         }
12528         else {
12529 #ifdef WOLFSSL_TLS13
12530             sendSz = BuildTls13Message(ssl, out, outputSz, sendBuffer, buffSz,
12531                                        application_data, 0, 0);
12532 #else
12533             sendSz = BUFFER_ERROR;
12534 #endif
12535         }
12536         if (sendSz < 0) {
12537         #ifdef WOLFSSL_ASYNC_CRYPT
12538             if (sendSz == WC_PENDING_E)
12539                 ssl->error = sendSz;
12540         #endif
12541             return BUILD_MSG_ERROR;
12542         }
12543 
12544         ssl->buffers.outputBuffer.length += sendSz;
12545 
12546         if ( (ret = SendBuffered(ssl)) < 0) {
12547             WOLFSSL_ERROR(ret);
12548             /* store for next call if WANT_WRITE or user embedSend() that
12549                doesn't present like WANT_WRITE */
12550             ssl->buffers.plainSz  = len;
12551             ssl->buffers.prevSent = sent;
12552             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
12553                 return 0;  /* peer reset */
12554             return ssl->error = ret;
12555         }
12556 
12557         sent += len;
12558 
12559         /* only one message per attempt */
12560         if (ssl->options.partialWrite == 1) {
12561             WOLFSSL_MSG("Paritial Write on, only sending one record");
12562             break;
12563         }
12564     }
12565 
12566     return sent;
12567 }
12568 
12569 /* process input data */
12570 int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
12571 {
12572     int size;
12573 
12574     WOLFSSL_ENTER("ReceiveData()");
12575 
12576     /* reset error state */
12577     if (ssl->error == WANT_READ || ssl->error == WC_PENDING_E) {
12578         ssl->error = 0;
12579     }
12580 
12581 #ifdef WOLFSSL_DTLS
12582     if (ssl->options.dtls) {
12583         /* In DTLS mode, we forgive some errors and allow the session
12584          * to continue despite them. */
12585         if (ssl->error == VERIFY_MAC_ERROR || ssl->error == DECRYPT_ERROR)
12586             ssl->error = 0;
12587     }
12588 #endif /* WOLFSSL_DTLS */
12589 
12590     if (ssl->error != 0 && ssl->error != WANT_WRITE) {
12591         WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
12592         return ssl->error;
12593     }
12594 
12595     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
12596         int err;
12597         WOLFSSL_MSG("Handshake not complete, trying to finish");
12598         if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS) {
12599         #ifdef WOLFSSL_ASYNC_CRYPT
12600             /* if async would block return WANT_WRITE */
12601             if (ssl->error == WC_PENDING_E) {
12602                 return WOLFSSL_CBIO_ERR_WANT_READ;
12603             }
12604         #endif
12605             return  err;
12606         }
12607     }
12608 
12609 #ifdef HAVE_SECURE_RENEGOTIATION
12610 startScr:
12611     if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
12612         int err;
12613         ssl->secure_renegotiation->startScr = 0;  /* only start once */
12614         WOLFSSL_MSG("Need to start scr, server requested");
12615         if ( (err = wolfSSL_Rehandshake(ssl)) != SSL_SUCCESS)
12616             return  err;
12617     }
12618 #endif
12619 
12620     while (ssl->buffers.clearOutputBuffer.length == 0) {
12621         if ( (ssl->error = ProcessReply(ssl)) < 0) {
12622             WOLFSSL_ERROR(ssl->error);
12623             if (ssl->error == ZERO_RETURN) {
12624                 WOLFSSL_MSG("Zero return, no more data coming");
12625                 return 0;         /* no more data coming */
12626             }
12627             if (ssl->error == SOCKET_ERROR_E) {
12628                 if (ssl->options.connReset || ssl->options.isClosed) {
12629                     WOLFSSL_MSG("Peer reset or closed, connection done");
12630                     ssl->error = SOCKET_PEER_CLOSED_E;
12631                     WOLFSSL_ERROR(ssl->error);
12632                     return 0;     /* peer reset or closed */
12633                 }
12634             }
12635             return ssl->error;
12636         }
12637         #ifdef HAVE_SECURE_RENEGOTIATION
12638             if (ssl->secure_renegotiation &&
12639                 ssl->secure_renegotiation->startScr) {
12640                 goto startScr;
12641             }
12642         #endif
12643     }
12644 
12645     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
12646         size = sz;
12647     else
12648         size = ssl->buffers.clearOutputBuffer.length;
12649 
12650     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
12651 
12652     if (peek == 0) {
12653         ssl->buffers.clearOutputBuffer.length -= size;
12654         ssl->buffers.clearOutputBuffer.buffer += size;
12655     }
12656 
12657     if (ssl->buffers.clearOutputBuffer.length == 0 &&
12658                                            ssl->buffers.inputBuffer.dynamicFlag)
12659        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
12660 
12661     WOLFSSL_LEAVE("ReceiveData()", size);
12662     return size;
12663 }
12664 
12665 
12666 /* send alert message */
12667 int SendAlert(WOLFSSL* ssl, int severity, int type)
12668 {
12669     byte input[ALERT_SIZE];
12670     byte *output;
12671     int  sendSz;
12672     int  ret;
12673     int  outputSz;
12674     int  dtlsExtra = 0;
12675 
12676 #ifdef HAVE_WRITE_DUP
12677     if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
12678         int notifyErr = 0;
12679 
12680         WOLFSSL_MSG("Read dup side cannot write alerts, notifying sibling");
12681 
12682         if (type == close_notify) {
12683             notifyErr = ZERO_RETURN;
12684         } else if (severity == alert_fatal) {
12685             notifyErr = FATAL_ERROR;
12686         }
12687 
12688         if (notifyErr != 0) {
12689             return NotifyWriteSide(ssl, notifyErr);
12690         }
12691 
12692         return 0;
12693     }
12694 #endif
12695 
12696     /* if sendalert is called again for nonblocking */
12697     if (ssl->options.sendAlertState != 0) {
12698         ret = SendBuffered(ssl);
12699         if (ret == 0)
12700             ssl->options.sendAlertState = 0;
12701         return ret;
12702     }
12703 
12704    #ifdef WOLFSSL_DTLS
12705         if (ssl->options.dtls)
12706            dtlsExtra = DTLS_RECORD_EXTRA;
12707    #endif
12708 
12709     /* check for available size */
12710     outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
12711     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
12712         return ret;
12713 
12714     /* get output buffer */
12715     output = ssl->buffers.outputBuffer.buffer +
12716              ssl->buffers.outputBuffer.length;
12717 
12718     input[0] = (byte)severity;
12719     input[1] = (byte)type;
12720     ssl->alert_history.last_tx.code = type;
12721     ssl->alert_history.last_tx.level = severity;
12722     if (severity == alert_fatal) {
12723         ssl->options.isClosed = 1;  /* Don't send close_notify */
12724     }
12725 
12726     /* only send encrypted alert if handshake actually complete, otherwise
12727        other side may not be able to handle it */
12728     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
12729         sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE,
12730                                                           alert, 0, 0, 0);
12731     else {
12732 
12733         AddRecordHeader(output, ALERT_SIZE, alert, ssl);
12734         output += RECORD_HEADER_SZ;
12735         #ifdef WOLFSSL_DTLS
12736             if (ssl->options.dtls)
12737                 output += DTLS_RECORD_EXTRA;
12738         #endif
12739         XMEMCPY(output, input, ALERT_SIZE);
12740 
12741         sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
12742         #ifdef WOLFSSL_DTLS
12743             if (ssl->options.dtls)
12744                 sendSz += DTLS_RECORD_EXTRA;
12745         #endif
12746     }
12747     if (sendSz < 0)
12748         return BUILD_MSG_ERROR;
12749 
12750     #ifdef WOLFSSL_CALLBACKS
12751         if (ssl->hsInfoOn)
12752             AddPacketName("Alert", &ssl->handShakeInfo);
12753         if (ssl->toInfoOn)
12754             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
12755     #endif
12756 
12757     ssl->buffers.outputBuffer.length += sendSz;
12758     ssl->options.sendAlertState = 1;
12759 
12760     return SendBuffered(ssl);
12761 }
12762 
12763 const char* wolfSSL_ERR_reason_error_string(unsigned long e)
12764 {
12765 #ifdef NO_ERROR_STRINGS
12766 
12767     (void)e;
12768     return "no support for error strings built in";
12769 
12770 #else
12771 
12772     int error = (int)e;
12773 
12774     /* pass to wolfCrypt */
12775     if (error < MAX_CODE_E && error > MIN_CODE_E) {
12776         return wc_GetErrorString(error);
12777     }
12778 
12779     switch (error) {
12780 
12781     case UNSUPPORTED_SUITE :
12782         return "unsupported cipher suite";
12783 
12784     case INPUT_CASE_ERROR :
12785         return "input state error";
12786 
12787     case PREFIX_ERROR :
12788         return "bad index to key rounds";
12789 
12790     case MEMORY_ERROR :
12791         return "out of memory";
12792 
12793     case VERIFY_FINISHED_ERROR :
12794         return "verify problem on finished";
12795 
12796     case VERIFY_MAC_ERROR :
12797         return "verify mac problem";
12798 
12799     case PARSE_ERROR :
12800         return "parse error on header";
12801 
12802     case SIDE_ERROR :
12803         return "wrong client/server type";
12804 
12805     case NO_PEER_CERT :
12806         return "peer didn't send cert";
12807 
12808     case UNKNOWN_HANDSHAKE_TYPE :
12809         return "weird handshake type";
12810 
12811     case SOCKET_ERROR_E :
12812         return "error state on socket";
12813 
12814     case SOCKET_NODATA :
12815         return "expected data, not there";
12816 
12817     case INCOMPLETE_DATA :
12818         return "don't have enough data to complete task";
12819 
12820     case UNKNOWN_RECORD_TYPE :
12821         return "unknown type in record hdr";
12822 
12823     case DECRYPT_ERROR :
12824         return "error during decryption";
12825 
12826     case FATAL_ERROR :
12827         return "revcd alert fatal error";
12828 
12829     case ENCRYPT_ERROR :
12830         return "error during encryption";
12831 
12832     case FREAD_ERROR :
12833         return "fread problem";
12834 
12835     case NO_PEER_KEY :
12836         return "need peer's key";
12837 
12838     case NO_PRIVATE_KEY :
12839         return "need the private key";
12840 
12841     case NO_DH_PARAMS :
12842         return "server missing DH params";
12843 
12844     case RSA_PRIVATE_ERROR :
12845         return "error during rsa priv op";
12846 
12847     case MATCH_SUITE_ERROR :
12848         return "can't match cipher suite";
12849 
12850     case COMPRESSION_ERROR :
12851         return "compression mismatch error";
12852 
12853     case BUILD_MSG_ERROR :
12854         return "build message failure";
12855 
12856     case BAD_HELLO :
12857         return "client hello malformed";
12858 
12859     case DOMAIN_NAME_MISMATCH :
12860         return "peer subject name mismatch";
12861 
12862     case WANT_READ :
12863     case SSL_ERROR_WANT_READ :
12864         return "non-blocking socket wants data to be read";
12865 
12866     case NOT_READY_ERROR :
12867         return "handshake layer not ready yet, complete first";
12868 
12869     case PMS_VERSION_ERROR :
12870         return "premaster secret version mismatch error";
12871 
12872     case VERSION_ERROR :
12873         return "record layer version error";
12874 
12875     case WANT_WRITE :
12876     case SSL_ERROR_WANT_WRITE :
12877         return "non-blocking socket write buffer full";
12878 
12879     case BUFFER_ERROR :
12880         return "malformed buffer input error";
12881 
12882     case VERIFY_CERT_ERROR :
12883         return "verify problem on certificate";
12884 
12885     case VERIFY_SIGN_ERROR :
12886         return "verify problem based on signature";
12887 
12888     case CLIENT_ID_ERROR :
12889         return "psk client identity error";
12890 
12891     case SERVER_HINT_ERROR:
12892         return "psk server hint error";
12893 
12894     case PSK_KEY_ERROR:
12895         return "psk key callback error";
12896 
12897     case NTRU_KEY_ERROR:
12898         return "NTRU key error";
12899 
12900     case NTRU_DRBG_ERROR:
12901         return "NTRU drbg error";
12902 
12903     case NTRU_ENCRYPT_ERROR:
12904         return "NTRU encrypt error";
12905 
12906     case NTRU_DECRYPT_ERROR:
12907         return "NTRU decrypt error";
12908 
12909     case ZLIB_INIT_ERROR:
12910         return "zlib init error";
12911 
12912     case ZLIB_COMPRESS_ERROR:
12913         return "zlib compress error";
12914 
12915     case ZLIB_DECOMPRESS_ERROR:
12916         return "zlib decompress error";
12917 
12918     case GETTIME_ERROR:
12919         return "gettimeofday() error";
12920 
12921     case GETITIMER_ERROR:
12922         return "getitimer() error";
12923 
12924     case SIGACT_ERROR:
12925         return "sigaction() error";
12926 
12927     case SETITIMER_ERROR:
12928         return "setitimer() error";
12929 
12930     case LENGTH_ERROR:
12931         return "record layer length error";
12932 
12933     case PEER_KEY_ERROR:
12934         return "cant decode peer key";
12935 
12936     case ZERO_RETURN:
12937     case SSL_ERROR_ZERO_RETURN:
12938         return "peer sent close notify alert";
12939 
12940     case ECC_CURVETYPE_ERROR:
12941         return "Bad ECC Curve Type or unsupported";
12942 
12943     case ECC_CURVE_ERROR:
12944         return "Bad ECC Curve or unsupported";
12945 
12946     case ECC_PEERKEY_ERROR:
12947         return "Bad ECC Peer Key";
12948 
12949     case ECC_MAKEKEY_ERROR:
12950         return "ECC Make Key failure";
12951 
12952     case ECC_EXPORT_ERROR:
12953         return "ECC Export Key failure";
12954 
12955     case ECC_SHARED_ERROR:
12956         return "ECC DHE shared failure";
12957 
12958     case NOT_CA_ERROR:
12959         return "Not a CA by basic constraint error";
12960 
12961     case HTTP_TIMEOUT:
12962         return "HTTP timeout for OCSP or CRL req";
12963 
12964     case BAD_CERT_MANAGER_ERROR:
12965         return "Bad Cert Manager error";
12966 
12967     case OCSP_CERT_REVOKED:
12968         return "OCSP Cert revoked";
12969 
12970     case CRL_CERT_REVOKED:
12971         return "CRL Cert revoked";
12972 
12973     case CRL_MISSING:
12974         return "CRL missing, not loaded";
12975 
12976     case MONITOR_SETUP_E:
12977         return "CRL monitor setup error";
12978 
12979     case THREAD_CREATE_E:
12980         return "Thread creation problem";
12981 
12982     case OCSP_NEED_URL:
12983         return "OCSP need URL";
12984 
12985     case OCSP_CERT_UNKNOWN:
12986         return "OCSP Cert unknown";
12987 
12988     case OCSP_LOOKUP_FAIL:
12989         return "OCSP Responder lookup fail";
12990 
12991     case MAX_CHAIN_ERROR:
12992         return "Maximum Chain Depth Exceeded";
12993 
12994     case COOKIE_ERROR:
12995         return "DTLS Cookie Error";
12996 
12997     case SEQUENCE_ERROR:
12998         return "DTLS Sequence Error";
12999 
13000     case SUITES_ERROR:
13001         return "Suites Pointer Error";
13002 
13003     case SSL_NO_PEM_HEADER:
13004         return "No PEM Header Error";
13005 
13006     case OUT_OF_ORDER_E:
13007         return "Out of order message, fatal";
13008 
13009     case BAD_KEA_TYPE_E:
13010         return "Bad KEA type found";
13011 
13012     case SANITY_CIPHER_E:
13013         return "Sanity check on ciphertext failed";
13014 
13015     case RECV_OVERFLOW_E:
13016         return "Receive callback returned more than requested";
13017 
13018     case GEN_COOKIE_E:
13019         return "Generate Cookie Error";
13020 
13021     case NO_PEER_VERIFY:
13022         return "Need peer certificate verify Error";
13023 
13024     case FWRITE_ERROR:
13025         return "fwrite Error";
13026 
13027     case CACHE_MATCH_ERROR:
13028         return "Cache restore header match Error";
13029 
13030     case UNKNOWN_SNI_HOST_NAME_E:
13031         return "Unrecognized host name Error";
13032 
13033     case UNKNOWN_MAX_FRAG_LEN_E:
13034         return "Unrecognized max frag len Error";
13035 
13036     case KEYUSE_SIGNATURE_E:
13037         return "Key Use digitalSignature not set Error";
13038 
13039     case KEYUSE_ENCIPHER_E:
13040         return "Key Use keyEncipherment not set Error";
13041 
13042     case EXTKEYUSE_AUTH_E:
13043         return "Ext Key Use server/client auth not set Error";
13044 
13045     case SEND_OOB_READ_E:
13046         return "Send Callback Out of Bounds Read Error";
13047 
13048     case SECURE_RENEGOTIATION_E:
13049         return "Invalid Renegotiation Error";
13050 
13051     case SESSION_TICKET_LEN_E:
13052         return "Session Ticket Too Long Error";
13053 
13054     case SESSION_TICKET_EXPECT_E:
13055         return "Session Ticket Error";
13056 
13057     case SCR_DIFFERENT_CERT_E:
13058         return "Peer sent different cert during SCR";
13059 
13060     case SESSION_SECRET_CB_E:
13061         return "Session Secret Callback Error";
13062 
13063     case NO_CHANGE_CIPHER_E:
13064         return "Finished received from peer before Change Cipher Error";
13065 
13066     case SANITY_MSG_E:
13067         return "Sanity Check on message order Error";
13068 
13069     case DUPLICATE_MSG_E:
13070         return "Duplicate HandShake message Error";
13071 
13072     case SNI_UNSUPPORTED:
13073         return "Protocol version does not support SNI Error";
13074 
13075     case SOCKET_PEER_CLOSED_E:
13076         return "Peer closed underlying transport Error";
13077 
13078     case BAD_TICKET_KEY_CB_SZ:
13079         return "Bad user session ticket key callback Size Error";
13080 
13081     case BAD_TICKET_MSG_SZ:
13082         return "Bad session ticket message Size Error";
13083 
13084     case BAD_TICKET_ENCRYPT:
13085         return "Bad user ticket callback encrypt Error";
13086 
13087     case DH_KEY_SIZE_E:
13088         return "DH key too small Error";
13089 
13090     case SNI_ABSENT_ERROR:
13091         return "No Server Name Indication extension Error";
13092 
13093     case RSA_SIGN_FAULT:
13094         return "RSA Signature Fault Error";
13095 
13096     case HANDSHAKE_SIZE_ERROR:
13097         return "Handshake message too large Error";
13098 
13099     case UNKNOWN_ALPN_PROTOCOL_NAME_E:
13100         return "Unrecognized protocol name Error";
13101 
13102     case BAD_CERTIFICATE_STATUS_ERROR:
13103         return "Bad Certificate Status Message Error";
13104 
13105     case OCSP_INVALID_STATUS:
13106         return "Invalid OCSP Status Error";
13107 
13108     case RSA_KEY_SIZE_E:
13109         return "RSA key too small";
13110 
13111     case ECC_KEY_SIZE_E:
13112         return "ECC key too small";
13113 
13114     case DTLS_EXPORT_VER_E:
13115         return "Version needs updated after code change or version mismatch";
13116 
13117     case INPUT_SIZE_E:
13118         return "Input size too large Error";
13119 
13120     case CTX_INIT_MUTEX_E:
13121         return "Initialize ctx mutex error";
13122 
13123     case EXT_MASTER_SECRET_NEEDED_E:
13124         return "Extended Master Secret must be enabled to resume EMS session";
13125 
13126     case DTLS_POOL_SZ_E:
13127         return "Maximum DTLS pool size exceeded";
13128 
13129     case DECODE_E:
13130         return "Decode handshake message error";
13131 
13132     case WRITE_DUP_READ_E:
13133         return "Write dup write side can't read error";
13134 
13135     case WRITE_DUP_WRITE_E:
13136         return "Write dup read side can't write error";
13137 
13138     case INVALID_CERT_CTX_E:
13139         return "Certificate context does not match request or not empty";
13140 
13141     case BAD_KEY_SHARE_DATA:
13142         return "The Key Share data contains group that was in Client Hello";
13143 
13144     case MISSING_HANDSHAKE_DATA:
13145         return "The handshake message is missing required data";
13146 
13147     case BAD_BINDER:
13148         return "Binder value does not match value server calculated";
13149 
13150     case EXT_NOT_ALLOWED:
13151         return "Extension type not allowed in handshake message type";
13152 
13153     case INVALID_PARAMETER:
13154         return "The security parameter is invalid";
13155 
13156     case KEY_SHARE_ERROR:
13157         return "Key share extension did not contain a valid named group";
13158 
13159     default :
13160         return "unknown error number";
13161     }
13162 
13163 #endif /* NO_ERROR_STRINGS */
13164 }
13165 
13166 void SetErrorString(int error, char* str)
13167 {
13168     XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ);
13169 }
13170 
13171 
13172 /* be sure to add to cipher_name_idx too !!!! */
13173 static const char* const cipher_names[] =
13174 {
13175 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
13176     "RC4-SHA",
13177 #endif
13178 
13179 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
13180     "RC4-MD5",
13181 #endif
13182 
13183 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
13184     "DES-CBC3-SHA",
13185 #endif
13186 
13187 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
13188     "AES128-SHA",
13189 #endif
13190 
13191 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
13192     "AES256-SHA",
13193 #endif
13194 
13195 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
13196     "NULL-SHA",
13197 #endif
13198 
13199 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
13200     "NULL-SHA256",
13201 #endif
13202 
13203 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
13204     "DHE-RSA-AES128-SHA",
13205 #endif
13206 
13207 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
13208     "DHE-RSA-AES256-SHA",
13209 #endif
13210 
13211 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
13212     "DHE-PSK-AES256-GCM-SHA384",
13213 #endif
13214 
13215 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
13216     "DHE-PSK-AES128-GCM-SHA256",
13217 #endif
13218 
13219 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
13220     "PSK-AES256-GCM-SHA384",
13221 #endif
13222 
13223 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
13224     "PSK-AES128-GCM-SHA256",
13225 #endif
13226 
13227 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
13228     "DHE-PSK-AES256-CBC-SHA384",
13229 #endif
13230 
13231 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
13232     "DHE-PSK-AES128-CBC-SHA256",
13233 #endif
13234 
13235 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
13236     "PSK-AES256-CBC-SHA384",
13237 #endif
13238 
13239 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
13240     "PSK-AES128-CBC-SHA256",
13241 #endif
13242 
13243 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
13244     "PSK-AES128-CBC-SHA",
13245 #endif
13246 
13247 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
13248     "PSK-AES256-CBC-SHA",
13249 #endif
13250 
13251 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
13252     "DHE-PSK-AES128-CCM",
13253 #endif
13254 
13255 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
13256     "DHE-PSK-AES256-CCM",
13257 #endif
13258 
13259 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
13260     "PSK-AES128-CCM",
13261 #endif
13262 
13263 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
13264     "PSK-AES256-CCM",
13265 #endif
13266 
13267 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
13268     "PSK-AES128-CCM-8",
13269 #endif
13270 
13271 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
13272     "PSK-AES256-CCM-8",
13273 #endif
13274 
13275 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
13276     "DHE-PSK-NULL-SHA384",
13277 #endif
13278 
13279 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
13280     "DHE-PSK-NULL-SHA256",
13281 #endif
13282 
13283 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
13284     "PSK-NULL-SHA384",
13285 #endif
13286 
13287 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
13288     "PSK-NULL-SHA256",
13289 #endif
13290 
13291 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
13292     "PSK-NULL-SHA",
13293 #endif
13294 
13295 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
13296     "HC128-MD5",
13297 #endif
13298 
13299 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
13300     "HC128-SHA",
13301 #endif
13302 
13303 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
13304     "HC128-B2B256",
13305 #endif
13306 
13307 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
13308     "AES128-B2B256",
13309 #endif
13310 
13311 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
13312     "AES256-B2B256",
13313 #endif
13314 
13315 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
13316     "RABBIT-SHA",
13317 #endif
13318 
13319 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
13320     "NTRU-RC4-SHA",
13321 #endif
13322 
13323 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
13324     "NTRU-DES-CBC3-SHA",
13325 #endif
13326 
13327 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
13328     "NTRU-AES128-SHA",
13329 #endif
13330 
13331 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
13332     "NTRU-AES256-SHA",
13333 #endif
13334 
13335 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
13336     "AES128-CCM-8",
13337 #endif
13338 
13339 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
13340     "AES256-CCM-8",
13341 #endif
13342 
13343 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
13344     "ECDHE-ECDSA-AES128-CCM",
13345 #endif
13346 
13347 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
13348     "ECDHE-ECDSA-AES128-CCM-8",
13349 #endif
13350 
13351 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
13352     "ECDHE-ECDSA-AES256-CCM-8",
13353 #endif
13354 
13355 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
13356     "ECDHE-RSA-AES128-SHA",
13357 #endif
13358 
13359 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
13360     "ECDHE-RSA-AES256-SHA",
13361 #endif
13362 
13363 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
13364     "ECDHE-ECDSA-AES128-SHA",
13365 #endif
13366 
13367 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
13368     "ECDHE-ECDSA-AES256-SHA",
13369 #endif
13370 
13371 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
13372     "ECDHE-RSA-RC4-SHA",
13373 #endif
13374 
13375 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
13376     "ECDHE-RSA-DES-CBC3-SHA",
13377 #endif
13378 
13379 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
13380     "ECDHE-ECDSA-RC4-SHA",
13381 #endif
13382 
13383 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
13384     "ECDHE-ECDSA-DES-CBC3-SHA",
13385 #endif
13386 
13387 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
13388     "AES128-SHA256",
13389 #endif
13390 
13391 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
13392     "AES256-SHA256",
13393 #endif
13394 
13395 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
13396     "DHE-RSA-AES128-SHA256",
13397 #endif
13398 
13399 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
13400     "DHE-RSA-AES256-SHA256",
13401 #endif
13402 
13403 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
13404     "ECDH-RSA-AES128-SHA",
13405 #endif
13406 
13407 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
13408     "ECDH-RSA-AES256-SHA",
13409 #endif
13410 
13411 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
13412     "ECDH-ECDSA-AES128-SHA",
13413 #endif
13414 
13415 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
13416     "ECDH-ECDSA-AES256-SHA",
13417 #endif
13418 
13419 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
13420     "ECDH-RSA-RC4-SHA",
13421 #endif
13422 
13423 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
13424     "ECDH-RSA-DES-CBC3-SHA",
13425 #endif
13426 
13427 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
13428     "ECDH-ECDSA-RC4-SHA",
13429 #endif
13430 
13431 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
13432     "ECDH-ECDSA-DES-CBC3-SHA",
13433 #endif
13434 
13435 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
13436     "AES128-GCM-SHA256",
13437 #endif
13438 
13439 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
13440     "AES256-GCM-SHA384",
13441 #endif
13442 
13443 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
13444     "DHE-RSA-AES128-GCM-SHA256",
13445 #endif
13446 
13447 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
13448     "DHE-RSA-AES256-GCM-SHA384",
13449 #endif
13450 
13451 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
13452     "ECDHE-RSA-AES128-GCM-SHA256",
13453 #endif
13454 
13455 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
13456     "ECDHE-RSA-AES256-GCM-SHA384",
13457 #endif
13458 
13459 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
13460     "ECDHE-ECDSA-AES128-GCM-SHA256",
13461 #endif
13462 
13463 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
13464     "ECDHE-ECDSA-AES256-GCM-SHA384",
13465 #endif
13466 
13467 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
13468     "ECDH-RSA-AES128-GCM-SHA256",
13469 #endif
13470 
13471 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
13472     "ECDH-RSA-AES256-GCM-SHA384",
13473 #endif
13474 
13475 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
13476     "ECDH-ECDSA-AES128-GCM-SHA256",
13477 #endif
13478 
13479 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
13480     "ECDH-ECDSA-AES256-GCM-SHA384",
13481 #endif
13482 
13483 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
13484     "CAMELLIA128-SHA",
13485 #endif
13486 
13487 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
13488     "DHE-RSA-CAMELLIA128-SHA",
13489 #endif
13490 
13491 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
13492     "CAMELLIA256-SHA",
13493 #endif
13494 
13495 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
13496     "DHE-RSA-CAMELLIA256-SHA",
13497 #endif
13498 
13499 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
13500     "CAMELLIA128-SHA256",
13501 #endif
13502 
13503 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
13504     "DHE-RSA-CAMELLIA128-SHA256",
13505 #endif
13506 
13507 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
13508     "CAMELLIA256-SHA256",
13509 #endif
13510 
13511 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
13512     "DHE-RSA-CAMELLIA256-SHA256",
13513 #endif
13514 
13515 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
13516     "ECDHE-RSA-AES128-SHA256",
13517 #endif
13518 
13519 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
13520     "ECDHE-ECDSA-AES128-SHA256",
13521 #endif
13522 
13523 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
13524     "ECDH-RSA-AES128-SHA256",
13525 #endif
13526 
13527 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
13528     "ECDH-ECDSA-AES128-SHA256",
13529 #endif
13530 
13531 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
13532     "ECDHE-RSA-AES256-SHA384",
13533 #endif
13534 
13535 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
13536     "ECDHE-ECDSA-AES256-SHA384",
13537 #endif
13538 
13539 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
13540     "ECDH-RSA-AES256-SHA384",
13541 #endif
13542 
13543 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
13544     "ECDH-ECDSA-AES256-SHA384",
13545 #endif
13546 
13547 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
13548     "ECDHE-RSA-CHACHA20-POLY1305",
13549 #endif
13550 
13551 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
13552     "ECDHE-ECDSA-CHACHA20-POLY1305",
13553 #endif
13554 
13555 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
13556     "DHE-RSA-CHACHA20-POLY1305",
13557 #endif
13558 
13559 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
13560     "ECDHE-RSA-CHACHA20-POLY1305-OLD",
13561 #endif
13562 
13563 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
13564     "ECDHE-ECDSA-CHACHA20-POLY1305-OLD",
13565 #endif
13566 
13567 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
13568     "DHE-RSA-CHACHA20-POLY1305-OLD",
13569 #endif
13570 
13571 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
13572     "ADH-AES128-SHA",
13573 #endif
13574 
13575 #ifdef BUILD_TLS_QSH
13576     "QSH",
13577 #endif
13578 
13579 #ifdef HAVE_RENEGOTIATION_INDICATION
13580     "RENEGOTIATION-INFO",
13581 #endif
13582 
13583 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
13584     "IDEA-CBC-SHA",
13585 #endif
13586 
13587 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
13588     "ECDHE-ECDSA-NULL-SHA",
13589 #endif
13590 
13591 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
13592     "ECDHE-PSK-NULL-SHA256",
13593 #endif
13594 
13595 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
13596     "ECDHE-PSK-AES128-CBC-SHA256",
13597 #endif
13598 
13599 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
13600     "PSK-CHACHA20-POLY1305",
13601 #endif
13602 
13603 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
13604     "ECDHE-PSK-CHACHA20-POLY1305",
13605 #endif
13606 
13607 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
13608     "DHE-PSK-CHACHA20-POLY1305",
13609 #endif
13610 
13611 #ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
13612     "EDH-RSA-DES-CBC3-SHA",
13613 #endif
13614 
13615 #ifdef BUILD_TLS_AES_128_GCM_SHA256
13616     "TLS13-AES128-GCM-SHA256",
13617 #endif
13618 
13619 #ifdef BUILD_TLS_AES_256_GCM_SHA384
13620     "TLS13-AES256-GCM-SHA384",
13621 #endif
13622 
13623 #ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
13624     "TLS13-CHACHA20-POLY1305-SHA256",
13625 #endif
13626 
13627 #ifdef BUILD_TLS_AES_128_CCM_SHA256
13628     "TLS13-AES128-CCM-SHA256",
13629 #endif
13630 
13631 #ifdef BUILD_TLS_AES_128_CCM_8_SHA256
13632     "TLS13-AES128-CCM-8-SHA256",
13633 #endif
13634 
13635 };
13636 
13637 
13638 /* cipher suite number that matches above name table */
13639 static int cipher_name_idx[] =
13640 {
13641 
13642 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
13643     SSL_RSA_WITH_RC4_128_SHA,
13644 #endif
13645 
13646 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
13647     SSL_RSA_WITH_RC4_128_MD5,
13648 #endif
13649 
13650 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
13651     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
13652 #endif
13653 
13654 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
13655     TLS_RSA_WITH_AES_128_CBC_SHA,
13656 #endif
13657 
13658 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
13659     TLS_RSA_WITH_AES_256_CBC_SHA,
13660 #endif
13661 
13662 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
13663     TLS_RSA_WITH_NULL_SHA,
13664 #endif
13665 
13666 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
13667     TLS_RSA_WITH_NULL_SHA256,
13668 #endif
13669 
13670 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
13671     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
13672 #endif
13673 
13674 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
13675     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
13676 #endif
13677 
13678 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
13679     TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
13680 #endif
13681 
13682 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
13683     TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
13684 #endif
13685 
13686 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
13687     TLS_PSK_WITH_AES_256_GCM_SHA384,
13688 #endif
13689 
13690 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
13691     TLS_PSK_WITH_AES_128_GCM_SHA256,
13692 #endif
13693 
13694 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
13695     TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
13696 #endif
13697 
13698 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
13699     TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
13700 #endif
13701 
13702 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
13703     TLS_PSK_WITH_AES_256_CBC_SHA384,
13704 #endif
13705 
13706 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
13707     TLS_PSK_WITH_AES_128_CBC_SHA256,
13708 #endif
13709 
13710 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
13711     TLS_PSK_WITH_AES_128_CBC_SHA,
13712 #endif
13713 
13714 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
13715     TLS_PSK_WITH_AES_256_CBC_SHA,
13716 #endif
13717 
13718 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
13719     TLS_DHE_PSK_WITH_AES_128_CCM,
13720 #endif
13721 
13722 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
13723     TLS_DHE_PSK_WITH_AES_256_CCM,
13724 #endif
13725 
13726 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
13727     TLS_PSK_WITH_AES_128_CCM,
13728 #endif
13729 
13730 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
13731     TLS_PSK_WITH_AES_256_CCM,
13732 #endif
13733 
13734 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
13735     TLS_PSK_WITH_AES_128_CCM_8,
13736 #endif
13737 
13738 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
13739     TLS_PSK_WITH_AES_256_CCM_8,
13740 #endif
13741 
13742 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
13743     TLS_DHE_PSK_WITH_NULL_SHA384,
13744 #endif
13745 
13746 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
13747     TLS_DHE_PSK_WITH_NULL_SHA256,
13748 #endif
13749 
13750 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
13751     TLS_PSK_WITH_NULL_SHA384,
13752 #endif
13753 
13754 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
13755     TLS_PSK_WITH_NULL_SHA256,
13756 #endif
13757 
13758 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
13759     TLS_PSK_WITH_NULL_SHA,
13760 #endif
13761 
13762 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
13763     TLS_RSA_WITH_HC_128_MD5,
13764 #endif
13765 
13766 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
13767     TLS_RSA_WITH_HC_128_SHA,
13768 #endif
13769 
13770 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
13771     TLS_RSA_WITH_HC_128_B2B256,
13772 #endif
13773 
13774 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
13775     TLS_RSA_WITH_AES_128_CBC_B2B256,
13776 #endif
13777 
13778 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
13779     TLS_RSA_WITH_AES_256_CBC_B2B256,
13780 #endif
13781 
13782 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
13783     TLS_RSA_WITH_RABBIT_SHA,
13784 #endif
13785 
13786 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
13787     TLS_NTRU_RSA_WITH_RC4_128_SHA,
13788 #endif
13789 
13790 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
13791     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
13792 #endif
13793 
13794 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
13795     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
13796 #endif
13797 
13798 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
13799     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
13800 #endif
13801 
13802 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
13803     TLS_RSA_WITH_AES_128_CCM_8,
13804 #endif
13805 
13806 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
13807     TLS_RSA_WITH_AES_256_CCM_8,
13808 #endif
13809 
13810 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
13811     TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
13812 #endif
13813 
13814 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
13815     TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
13816 #endif
13817 
13818 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
13819     TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
13820 #endif
13821 
13822 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
13823     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
13824 #endif
13825 
13826 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
13827     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
13828 #endif
13829 
13830 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
13831     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
13832 #endif
13833 
13834 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
13835     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
13836 #endif
13837 
13838 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
13839     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
13840 #endif
13841 
13842 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
13843     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
13844 #endif
13845 
13846 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
13847     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
13848 #endif
13849 
13850 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
13851     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
13852 #endif
13853 
13854 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
13855     TLS_RSA_WITH_AES_128_CBC_SHA256,
13856 #endif
13857 
13858 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
13859     TLS_RSA_WITH_AES_256_CBC_SHA256,
13860 #endif
13861 
13862 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
13863     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
13864 #endif
13865 
13866 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
13867     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
13868 #endif
13869 
13870 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
13871     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
13872 #endif
13873 
13874 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
13875     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
13876 #endif
13877 
13878 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
13879     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
13880 #endif
13881 
13882 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
13883     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
13884 #endif
13885 
13886 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
13887     TLS_ECDH_RSA_WITH_RC4_128_SHA,
13888 #endif
13889 
13890 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
13891     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
13892 #endif
13893 
13894 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
13895     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
13896 #endif
13897 
13898 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
13899     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
13900 #endif
13901 
13902 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
13903     TLS_RSA_WITH_AES_128_GCM_SHA256,
13904 #endif
13905 
13906 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
13907     TLS_RSA_WITH_AES_256_GCM_SHA384,
13908 #endif
13909 
13910 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
13911     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
13912 #endif
13913 
13914 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
13915     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
13916 #endif
13917 
13918 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
13919     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
13920 #endif
13921 
13922 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
13923     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
13924 #endif
13925 
13926 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
13927     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
13928 #endif
13929 
13930 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
13931     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
13932 #endif
13933 
13934 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
13935     TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
13936 #endif
13937 
13938 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
13939     TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
13940 #endif
13941 
13942 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
13943     TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
13944 #endif
13945 
13946 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
13947     TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
13948 #endif
13949 
13950 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
13951     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
13952 #endif
13953 
13954 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
13955     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
13956 #endif
13957 
13958 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
13959     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
13960 #endif
13961 
13962 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
13963     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
13964 #endif
13965 
13966 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
13967     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
13968 #endif
13969 
13970 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
13971     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
13972 #endif
13973 
13974 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
13975     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
13976 #endif
13977 
13978 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
13979     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
13980 #endif
13981 
13982 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
13983     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
13984 #endif
13985 
13986 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
13987     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
13988 #endif
13989 
13990 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
13991     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
13992 #endif
13993 
13994 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
13995     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
13996 #endif
13997 
13998 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
13999     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
14000 #endif
14001 
14002 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
14003     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
14004 #endif
14005 
14006 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
14007     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
14008 #endif
14009 
14010 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
14011     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
14012 #endif
14013 
14014 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
14015     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
14016 #endif
14017 
14018 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
14019     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
14020 #endif
14021 
14022 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
14023     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
14024 #endif
14025 
14026 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
14027     TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
14028 #endif
14029 
14030 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
14031     TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
14032 #endif
14033 
14034 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
14035     TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
14036 #endif
14037 
14038 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
14039     TLS_DH_anon_WITH_AES_128_CBC_SHA,
14040 #endif
14041 
14042 #ifdef BUILD_TLS_QSH
14043     TLS_QSH,
14044 #endif
14045 
14046 #ifdef HAVE_RENEGOTIATION_INDICATION
14047     TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
14048 #endif
14049 
14050 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
14051     SSL_RSA_WITH_IDEA_CBC_SHA,
14052 #endif
14053 
14054 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
14055     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
14056 #endif
14057 
14058 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
14059     TLS_ECDHE_PSK_WITH_NULL_SHA256,
14060 #endif
14061 
14062 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
14063     TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
14064 #endif
14065 
14066 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
14067     TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
14068 #endif
14069 
14070 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
14071     TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
14072 #endif
14073 
14074 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
14075     TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
14076 #endif
14077 
14078 #ifdef BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
14079     TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
14080 #endif
14081 
14082 #ifdef BUILD_TLS_AES_128_GCM_SHA256
14083     TLS_AES_128_GCM_SHA256,
14084 #endif
14085 
14086 #ifdef BUILD_TLS_AES_256_GCM_SHA384
14087     TLS_AES_256_GCM_SHA384,
14088 #endif
14089 
14090 #ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
14091     TLS_CHACHA20_POLY1305_SHA256,
14092 #endif
14093 
14094 #ifdef BUILD_TLS_AES_128_CCM_SHA256
14095     TLS_AES_128_CCM_SHA256,
14096 #endif
14097 
14098 #ifdef BUILD_TLS_AES_128_CCM_8_SHA256
14099     TLS_AES_128_CCM_8_SHA256,
14100 #endif
14101 
14102 };
14103 
14104 
14105 /* returns the cipher_names array */
14106 const char* const* GetCipherNames(void)
14107 {
14108     return cipher_names;
14109 }
14110 
14111 
14112 /* returns the size of the cipher_names array */
14113 int GetCipherNamesSize(void)
14114 {
14115     return (int)(sizeof(cipher_names) / sizeof(char*));
14116 }
14117 
14118 /* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
14119 const char* GetCipherNameInternal(const char* cipherName, int cipherSuite)
14120 {
14121     const char* result = NULL;
14122     const char* first;
14123     int i;
14124 
14125     if (cipherName == NULL) {
14126         WOLFSSL_MSG("Bad argument");
14127         return NULL;
14128     }
14129 
14130     first = (XSTRSTR(cipherName, "CHACHA")) ? "CHACHA"
14131           : (XSTRSTR(cipherName, "EC"))     ? "EC"
14132           : (XSTRSTR(cipherName, "CCM"))    ? "CCM"
14133           : NULL; /* normal */
14134 
14135     for (i = 0; i < (int)(sizeof(cipher_name_idx)/sizeof(int)); i++) {
14136         if (cipher_name_idx[i] == cipherSuite) {
14137             const char* nameFound = cipher_names[i];
14138 
14139             /* extra sanity check on returned cipher name */
14140             if (nameFound == NULL) {
14141                 continue;
14142             }
14143 
14144             /* if first is null then not any */
14145             if (first == NULL) {
14146                 if (    !XSTRSTR(nameFound, "CHACHA") &&
14147                         !XSTRSTR(nameFound, "EC") &&
14148                         !XSTRSTR(nameFound, "CCM")) {
14149                     result = nameFound;
14150                     break;
14151                 }
14152             }
14153             else if (XSTRSTR(nameFound, first)) {
14154                 result = nameFound;
14155                 break;
14156             }
14157         }
14158     }
14159 
14160     return result;
14161 }
14162 
14163 const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl)
14164 {
14165     if (ssl == NULL) {
14166         WOLFSSL_MSG("Bad argument");
14167         return NULL;
14168     }
14169 
14170     return GetCipherNameInternal(
14171         wolfSSL_CIPHER_get_name(&ssl->cipher),
14172         ssl->options.cipherSuite);
14173 }
14174 
14175 
14176 const char* wolfSSL_get_cipher_name_from_suite(const unsigned char cipherSuite,
14177     const unsigned char cipherSuite0)
14178 {
14179 
14180     WOLFSSL_ENTER("wolfSSL_get_cipher_name_from_suite");
14181 
14182     (void)cipherSuite;
14183     (void)cipherSuite0;
14184 
14185 #ifndef NO_ERROR_STRINGS
14186 
14187 #if defined(HAVE_CHACHA)
14188     if (cipherSuite0 == CHACHA_BYTE) {
14189         /* ChaCha suites */
14190         switch (cipherSuite) {
14191 #ifdef HAVE_POLY1305
14192 #ifndef NO_RSA
14193             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
14194                 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
14195 
14196             case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
14197                 return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
14198 
14199             case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
14200                 return "TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
14201 
14202             case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
14203                 return "TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
14204 #endif
14205             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
14206                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
14207 
14208             case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
14209                 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256";
14210 #ifndef NO_PSK
14211             case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
14212                 return "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
14213             case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 :
14214                 return "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256";
14215             case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
14216                 return "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
14217 #endif /* NO_PSK */
14218 #endif /* HAVE_POLY1305 */
14219         } /* switch */
14220     } /* chacha */
14221 #endif /* HAVE_CHACHA */
14222 
14223 #if defined(HAVE_ECC) || defined(HAVE_AESCCM)
14224         /* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
14225          * but the AES-CCM cipher suites also use it, even the ones that
14226          * aren't ECC. */
14227     if (cipherSuite0 == ECC_BYTE) {
14228         /* ECC suites */
14229         switch (cipherSuite) {
14230 #ifdef HAVE_ECC
14231     #ifndef NO_RSA
14232             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
14233                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
14234     #endif /* !NO_RSA */
14235             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
14236                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
14237     #ifndef NO_RSA
14238             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
14239                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
14240     #endif /* !NO_RSA */
14241             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
14242                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
14243     #ifndef NO_RSA
14244             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
14245                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
14246     #endif /* !NO_RSA */
14247             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
14248                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
14249     #ifndef NO_RSA
14250             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
14251                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
14252     #endif /* !NO_RSA */
14253             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
14254                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
14255 #ifndef NO_SHA
14256     #ifndef NO_RSA
14257             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
14258                 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
14259             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
14260                 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
14261     #endif /* !NO_RSA */
14262             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
14263                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
14264             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
14265                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
14266     #ifndef NO_RC4
14267         #ifndef NO_RSA
14268             case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
14269                 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
14270         #endif /* !NO_RSA */
14271             case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
14272                 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
14273     #endif /* !NO_RC4 */
14274     #ifndef NO_DES3
14275         #ifndef NO_RSA
14276             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
14277                 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
14278         #endif /* !NO_RSA */
14279             case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
14280                 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
14281     #endif /* !NO_DES3 */
14282 
14283     #ifndef NO_RSA
14284             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
14285                 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
14286             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
14287                 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
14288     #endif /* !NO_RSA */
14289             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
14290                 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
14291             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
14292                 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
14293     #ifndef NO_RC4
14294         #ifndef NO_RSA
14295             case TLS_ECDH_RSA_WITH_RC4_128_SHA :
14296                 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
14297         #endif /* !NO_RSA */
14298             case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
14299                 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
14300     #endif /* !NO_RC4 */
14301     #ifndef NO_DES3
14302         #ifndef NO_RSA
14303             case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
14304                 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
14305         #endif /* !NO_RSA */
14306             case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
14307                 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
14308     #endif /* !NO_DES3 */
14309 #endif /* HAVE_ECC */
14310 
14311 #ifdef HAVE_AESGCM
14312     #ifndef NO_RSA
14313             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
14314                 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
14315             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
14316                 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
14317     #endif /* !NO_RSA */
14318             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
14319                 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
14320             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
14321                 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
14322     #ifndef NO_RSA
14323             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
14324                 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
14325             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
14326                 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
14327     #endif /* !NO_RSA */
14328             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
14329                 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
14330             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
14331                 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
14332 #endif /* HAVE_AESGCM */
14333 
14334             case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
14335                 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
14336     #ifndef NO_PSK
14337             case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
14338                 return "TLS_ECDHE_PSK_WITH_NULL_SHA256";
14339             case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
14340                 return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256";
14341     #endif /* !NO_PSK */
14342     #ifndef NO_RSA
14343             case TLS_RSA_WITH_AES_128_CCM_8 :
14344                 return "TLS_RSA_WITH_AES_128_CCM_8";
14345             case TLS_RSA_WITH_AES_256_CCM_8 :
14346                 return "TLS_RSA_WITH_AES_256_CCM_8";
14347     #endif /* !NO_RSA */
14348     #ifndef NO_PSK
14349             case TLS_PSK_WITH_AES_128_CCM_8 :
14350                 return "TLS_PSK_WITH_AES_128_CCM_8";
14351             case TLS_PSK_WITH_AES_256_CCM_8 :
14352                 return "TLS_PSK_WITH_AES_256_CCM_8";
14353             case TLS_PSK_WITH_AES_128_CCM :
14354                 return "TLS_PSK_WITH_AES_128_CCM";
14355             case TLS_PSK_WITH_AES_256_CCM :
14356                 return "TLS_PSK_WITH_AES_256_CCM";
14357             case TLS_DHE_PSK_WITH_AES_128_CCM :
14358                 return "TLS_DHE_PSK_WITH_AES_128_CCM";
14359             case TLS_DHE_PSK_WITH_AES_256_CCM :
14360                 return "TLS_DHE_PSK_WITH_AES_256_CCM";
14361     #endif /* !NO_PSK */
14362     #ifdef HAVE_ECC
14363             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
14364                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM";
14365             case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
14366                 return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8";
14367             case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
14368                 return "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8";
14369     #endif /* HAVE_ECC */
14370 #endif /* HAVE_AESGCM */
14371 
14372             default:
14373                 return "NONE";
14374         } /* switch */
14375     } /* ECC and AES CCM/GCM */
14376 #endif  /* HAVE_ECC || HAVE_AESCCM*/
14377 
14378     if (cipherSuite0 == TLS13_BYTE) {
14379         /* TLS v1.3 suites */
14380         switch (cipherSuite) {
14381 #ifdef WOLFSSL_TLS13
14382     #ifdef HAVE_AESGCM
14383             case TLS_AES_128_GCM_SHA256 :
14384                 return "TLS_AES_128_GCM_SHA256";
14385             case TLS_AES_256_GCM_SHA384 :
14386                 return "TLS_AES_256_GCM_SHA384";
14387     #endif
14388 
14389     #ifdef HAVE_CHACHA
14390             case TLS_CHACHA20_POLY1305_SHA256 :
14391                 return "TLS_CHACHA20_POLY1305_SHA256";
14392     #endif
14393 
14394     #ifdef HAVE_AESCCM
14395             case TLS_AES_128_CCM_SHA256 :
14396                 return "TLS_AES_128_CCM_SHA256";
14397             case TLS_AES_128_CCM_8_SHA256 :
14398                 return "TLS_AES_256_CCM_8_SHA256";
14399     #endif
14400 #endif
14401 
14402             default:
14403                 return "NONE";
14404         }
14405     }
14406 
14407     if (cipherSuite0 != ECC_BYTE &&
14408         cipherSuite0 != CHACHA_BYTE &&
14409         cipherSuite0 != TLS13_BYTE) {
14410 
14411         /* normal suites */
14412         switch (cipherSuite) {
14413 #ifndef NO_RSA
14414     #ifndef NO_RC4
14415         #ifndef NO_SHA
14416             case SSL_RSA_WITH_RC4_128_SHA :
14417                 return "SSL_RSA_WITH_RC4_128_SHA";
14418         #endif /* !NO_SHA */
14419         #ifndef NO_MD5
14420             case SSL_RSA_WITH_RC4_128_MD5 :
14421                 return "SSL_RSA_WITH_RC4_128_MD5";
14422         #endif /* !NO_MD5 */
14423     #endif /* !NO_RC4 */
14424     #ifndef NO_SHA
14425         #ifndef NO_DES3
14426             case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
14427                 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
14428         #endif /* !NO_DES3 */
14429         #ifdef HAVE_IDEA
14430             case SSL_RSA_WITH_IDEA_CBC_SHA :
14431                 return "SSL_RSA_WITH_IDEA_CBC_SHA";
14432         #endif /* HAVE_IDEA */
14433 
14434             case TLS_RSA_WITH_AES_128_CBC_SHA :
14435                 return "TLS_RSA_WITH_AES_128_CBC_SHA";
14436             case TLS_RSA_WITH_AES_256_CBC_SHA :
14437                 return "TLS_RSA_WITH_AES_256_CBC_SHA";
14438     #endif /* !NO_SHA */
14439             case TLS_RSA_WITH_AES_128_CBC_SHA256 :
14440                 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
14441             case TLS_RSA_WITH_AES_256_CBC_SHA256 :
14442                 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
14443     #ifdef HAVE_BLAKE2
14444             case TLS_RSA_WITH_AES_128_CBC_B2B256:
14445                 return "TLS_RSA_WITH_AES_128_CBC_B2B256";
14446             case TLS_RSA_WITH_AES_256_CBC_B2B256:
14447                 return "TLS_RSA_WITH_AES_256_CBC_B2B256";
14448     #endif /* HAVE_BLAKE2 */
14449     #ifndef NO_SHA
14450             case TLS_RSA_WITH_NULL_SHA :
14451                 return "TLS_RSA_WITH_NULL_SHA";
14452     #endif /* !NO_SHA */
14453             case TLS_RSA_WITH_NULL_SHA256 :
14454                 return "TLS_RSA_WITH_NULL_SHA256";
14455 #endif /* NO_RSA */
14456 
14457 #ifndef NO_PSK
14458     #ifndef NO_SHA
14459             case TLS_PSK_WITH_AES_128_CBC_SHA :
14460                 return "TLS_PSK_WITH_AES_128_CBC_SHA";
14461             case TLS_PSK_WITH_AES_256_CBC_SHA :
14462                 return "TLS_PSK_WITH_AES_256_CBC_SHA";
14463     #endif /* !NO_SHA */
14464     #ifndef NO_SHA256
14465             case TLS_PSK_WITH_AES_128_CBC_SHA256 :
14466                 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
14467             case TLS_PSK_WITH_NULL_SHA256 :
14468                 return "TLS_PSK_WITH_NULL_SHA256";
14469             case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
14470                 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
14471             case TLS_DHE_PSK_WITH_NULL_SHA256 :
14472                 return "TLS_DHE_PSK_WITH_NULL_SHA256";
14473         #ifdef HAVE_AESGCM
14474             case TLS_PSK_WITH_AES_128_GCM_SHA256 :
14475                 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
14476             case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
14477                 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
14478         #endif /* HAVE_AESGCM */
14479     #endif /* !NO_SHA256 */
14480     #ifdef WOLFSSL_SHA384
14481             case TLS_PSK_WITH_AES_256_CBC_SHA384 :
14482                 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
14483             case TLS_PSK_WITH_NULL_SHA384 :
14484                 return "TLS_PSK_WITH_NULL_SHA384";
14485             case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
14486                 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
14487             case TLS_DHE_PSK_WITH_NULL_SHA384 :
14488                 return "TLS_DHE_PSK_WITH_NULL_SHA384";
14489         #ifdef HAVE_AESGCM
14490             case TLS_PSK_WITH_AES_256_GCM_SHA384 :
14491                 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
14492             case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
14493                 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
14494         #endif /* HAVE_AESGCM */
14495     #endif /* WOLFSSL_SHA384 */
14496     #ifndef NO_SHA
14497             case TLS_PSK_WITH_NULL_SHA :
14498                 return "TLS_PSK_WITH_NULL_SHA";
14499     #endif /* !NO_SHA */
14500     #endif /* NO_PSK */
14501 
14502     #ifndef NO_RSA
14503             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
14504                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
14505             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
14506                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
14507     #ifndef NO_SHA
14508             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
14509                 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
14510             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
14511                 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
14512         #ifndef NO_DES3
14513             case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
14514                 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
14515          #endif
14516     #endif /* !NO_RSA */
14517     #ifndef NO_HC128
14518         #ifndef NO_MD5
14519             case TLS_RSA_WITH_HC_128_MD5 :
14520                 return "TLS_RSA_WITH_HC_128_MD5";
14521         #endif /* !NO_MD5 */
14522         #ifndef NO_SHA
14523             case TLS_RSA_WITH_HC_128_SHA :
14524                 return "TLS_RSA_WITH_HC_128_SHA";
14525         #endif /* !NO_SHA */
14526         #ifdef HAVE_BLAKE2
14527             case TLS_RSA_WITH_HC_128_B2B256:
14528                 return "TLS_RSA_WITH_HC_128_B2B256";
14529         #endif /* HAVE_BLAKE2 */
14530     #endif /* !NO_HC128 */
14531     #ifndef NO_SHA
14532         #ifndef NO_RABBIT
14533             case TLS_RSA_WITH_RABBIT_SHA :
14534                 return "TLS_RSA_WITH_RABBIT_SHA";
14535         #endif /* !NO_RABBIT */
14536         #ifdef HAVE_NTRU
14537             #ifndef NO_RC4
14538             case TLS_NTRU_RSA_WITH_RC4_128_SHA :
14539                 return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
14540             #endif /* !NO_RC4 */
14541             #ifndef NO_DES3
14542             case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
14543                 return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
14544             #endif /* !NO_DES3 */
14545             case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
14546                 return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
14547             case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
14548                 return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
14549         #endif /* HAVE_NTRU */
14550 
14551         #ifdef HAVE_QSH
14552             case TLS_QSH :
14553                 return "TLS_QSH";
14554         #endif /* HAVE_QSH */
14555     #endif /* !NO_SHA */
14556 
14557             case TLS_RSA_WITH_AES_128_GCM_SHA256 :
14558                 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
14559             case TLS_RSA_WITH_AES_256_GCM_SHA384 :
14560                 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
14561             case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
14562                 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
14563             case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
14564                 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
14565     #ifndef NO_SHA
14566             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
14567                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA";
14568             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
14569                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA";
14570     #endif /* !NO_SHA */
14571             case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
14572                 return "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256";
14573             case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
14574                 return "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256";
14575     #ifndef NO_SHA
14576             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
14577                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA";
14578             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
14579                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA";
14580     #endif /* !NO_SHA */
14581             case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
14582                 return "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256";
14583             case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
14584                 return "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256";
14585 #endif /* !NO_PSK */
14586 
14587 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
14588             case TLS_DH_anon_WITH_AES_128_CBC_SHA :
14589                 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
14590 #endif
14591             default:
14592                 return "NONE";
14593         } /* switch */
14594     } /* normal / PSK */
14595 #endif /* NO_ERROR_STRINGS */
14596 
14597     return "NONE";
14598 }
14599 
14600 
14601 /**
14602 Set the enabled cipher suites.
14603 
14604 @param [out] suites Suites structure.
14605 @param [in]  list   List of cipher suites, only supports full name from
14606                     cipher_names[] delimited by ':'.
14607 
14608 @return true on success, else false.
14609 */
14610 int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
14611 {
14612     int       ret          = 0;
14613     int       idx          = 0;
14614     int       haveRSAsig   = 0;
14615     int       haveECDSAsig = 0;
14616     int       haveAnon     = 0;
14617     const int suiteSz      = GetCipherNamesSize();
14618     char*     next         = (char*)list;
14619 
14620     if (suites == NULL || list == NULL) {
14621         WOLFSSL_MSG("SetCipherList parameter error");
14622         return 0;
14623     }
14624 
14625     if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0 ||
14626                         XSTRNCMP(next, "DEFAULT", 7) == 0)
14627         return 1; /* wolfSSL defualt */
14628 
14629     do {
14630         char*  current = next;
14631         char   name[MAX_SUITE_NAME + 1];
14632         int    i;
14633         word32 length;
14634 
14635         next   = XSTRSTR(next, ":");
14636         length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
14637                                          : (word32)(next - current));
14638 
14639         XSTRNCPY(name, current, length);
14640         name[(length == sizeof(name)) ? length - 1 : length] = 0;
14641 
14642         for (i = 0; i < suiteSz; i++) {
14643             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
14644             #ifdef WOLFSSL_DTLS
14645                 /* don't allow stream ciphers with DTLS */
14646                 if (ctx->method->version.major == DTLS_MAJOR) {
14647                     if (XSTRSTR(name, "RC4") ||
14648                         XSTRSTR(name, "HC128") ||
14649                         XSTRSTR(name, "RABBIT"))
14650                     {
14651                         WOLFSSL_MSG("Stream ciphers not supported with DTLS");
14652                         continue;
14653                     }
14654 
14655                 }
14656             #endif /* WOLFSSL_DTLS */
14657 
14658                 suites->suites[idx++] = (XSTRSTR(name, "TLS13"))  ? TLS13_BYTE
14659                                       : (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
14660                                       : (XSTRSTR(name, "QSH"))    ? QSH_BYTE
14661                                       : (XSTRSTR(name, "EC"))     ? ECC_BYTE
14662                                       : (XSTRSTR(name, "CCM"))    ? ECC_BYTE
14663                                       : 0x00; /* normal */
14664                 suites->suites[idx++] = (byte)cipher_name_idx[i];
14665 
14666                 /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
14667                  * suites don't necessarily have RSA in the name. */
14668                 if (XSTRSTR(name, "TLS13")) {
14669                     haveRSAsig = 1;
14670                     haveECDSAsig = 1;
14671                 }
14672                 else if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
14673                     haveECDSAsig = 1;
14674                 else if (XSTRSTR(name, "ADH"))
14675                     haveAnon = 1;
14676                 else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
14677                     haveRSAsig = 1;
14678 
14679                 ret = 1; /* found at least one */
14680                 break;
14681             }
14682         }
14683     }
14684     while (next++); /* ++ needed to skip ':' */
14685 
14686     if (ret) {
14687         suites->setSuites = 1;
14688         suites->suiteSz   = (word16)idx;
14689         InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
14690     }
14691 
14692     (void)ctx;
14693 
14694     return ret;
14695 }
14696 
14697 #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)
14698 void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
14699 {
14700     word32 i;
14701 
14702     ssl->suites->sigAlgo = ssl->specs.sig_algo;
14703 
14704     /* set defaults */
14705     if (IsAtLeastTLSv1_2(ssl)) {
14706     #ifdef WOLFSSL_ALLOW_TLS_SHA1
14707         ssl->suites->hashAlgo = sha_mac;
14708     #else
14709         ssl->suites->hashAlgo = sha256_mac;
14710     #endif
14711     }
14712     else {
14713         ssl->suites->hashAlgo = sha_mac;
14714     }
14715 
14716     /* i+1 since peek a byte ahead for type */
14717     for (i = 0; (i+1) < hashSigAlgoSz; i += HELLO_EXT_SIGALGO_SZ) {
14718         if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
14719             if (hashSigAlgo[i] == sha_mac) {
14720                 break;
14721             }
14722             #ifndef NO_SHA256
14723             else if (hashSigAlgo[i] == sha256_mac) {
14724                 ssl->suites->hashAlgo = sha256_mac;
14725                 break;
14726             }
14727             #endif
14728             #ifdef WOLFSSL_SHA384
14729             else if (hashSigAlgo[i] == sha384_mac) {
14730                 ssl->suites->hashAlgo = sha384_mac;
14731                 break;
14732             }
14733             #endif
14734             #ifdef WOLFSSL_SHA512
14735             else if (hashSigAlgo[i] == sha512_mac) {
14736                 ssl->suites->hashAlgo = sha512_mac;
14737                 break;
14738             }
14739             #endif
14740         }
14741         else if (ssl->specs.sig_algo == 0) {
14742             ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
14743         }
14744     }
14745 }
14746 #endif /* !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) */
14747 
14748 #ifdef WOLFSSL_CALLBACKS
14749 
14750     /* Initialisze HandShakeInfo */
14751     void InitHandShakeInfo(HandShakeInfo* info, WOLFSSL* ssl)
14752     {
14753         int i;
14754 
14755         info->ssl = ssl;
14756         info->cipherName[0] = 0;
14757         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
14758             info->packetNames[i][0] = 0;
14759         info->numberPackets = 0;
14760         info->negotiationError = 0;
14761     }
14762 
14763     /* Set Final HandShakeInfo parameters */
14764     void FinishHandShakeInfo(HandShakeInfo* info)
14765     {
14766         int i;
14767         int sz = sizeof(cipher_name_idx)/sizeof(int);
14768 
14769         for (i = 0; i < sz; i++)
14770             if (info->ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
14771                 if (info->ssl->options.cipherSuite0 == ECC_BYTE)
14772                     continue;   /* ECC suites at end */
14773                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
14774                 break;
14775             }
14776 
14777         /* error max and min are negative numbers */
14778         if (info->ssl->error <= MIN_PARAM_ERR && info->ssl->error >= MAX_PARAM_ERR)
14779             info->negotiationError = info->ssl->error;
14780     }
14781 
14782 
14783     /* Add name to info packet names, increase packet name count */
14784     void AddPacketName(const char* name, HandShakeInfo* info)
14785     {
14786         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
14787             XSTRNCPY(info->packetNames[info->numberPackets++], name,
14788                     MAX_PACKETNAME_SZ);
14789         }
14790     }
14791 
14792 
14793     /* Initialisze TimeoutInfo */
14794     void InitTimeoutInfo(TimeoutInfo* info)
14795     {
14796         int i;
14797 
14798         info->timeoutName[0] = 0;
14799         info->flags          = 0;
14800 
14801         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
14802             info->packets[i].packetName[0]     = 0;
14803             info->packets[i].timestamp.tv_sec  = 0;
14804             info->packets[i].timestamp.tv_usec = 0;
14805             info->packets[i].bufferValue       = 0;
14806             info->packets[i].valueSz           = 0;
14807         }
14808         info->numberPackets        = 0;
14809         info->timeoutValue.tv_sec  = 0;
14810         info->timeoutValue.tv_usec = 0;
14811     }
14812 
14813 
14814     /* Free TimeoutInfo */
14815     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
14816     {
14817         int i;
14818         (void)heap;
14819         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
14820             if (info->packets[i].bufferValue) {
14821                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
14822                 info->packets[i].bufferValue = 0;
14823             }
14824 
14825     }
14826 
14827 
14828     /* Add PacketInfo to TimeoutInfo */
14829     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
14830                        int sz, void* heap)
14831     {
14832         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
14833             Timeval currTime;
14834 
14835             /* may add name after */
14836             if (name)
14837                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
14838                         MAX_PACKETNAME_SZ);
14839 
14840             /* add data, put in buffer if bigger than static buffer */
14841             info->packets[info->numberPackets].valueSz = sz;
14842             if (sz < MAX_VALUE_SZ)
14843                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
14844             else {
14845                 info->packets[info->numberPackets].bufferValue =
14846                                     (byte*)XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
14847                 if (!info->packets[info->numberPackets].bufferValue)
14848                     /* let next alloc catch, just don't fill, not fatal here  */
14849                     info->packets[info->numberPackets].valueSz = 0;
14850                 else
14851                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
14852                            data, sz);
14853             }
14854             gettimeofday(&currTime, 0);
14855             info->packets[info->numberPackets].timestamp.tv_sec  =
14856                                                              currTime.tv_sec;
14857             info->packets[info->numberPackets].timestamp.tv_usec =
14858                                                              currTime.tv_usec;
14859             info->numberPackets++;
14860         }
14861     }
14862 
14863 
14864     /* Add packet name to previsouly added packet info */
14865     void AddLateName(const char* name, TimeoutInfo* info)
14866     {
14867         /* make sure we have a valid previous one */
14868         if (info->numberPackets > 0 && info->numberPackets <
14869                                                         MAX_PACKETS_HANDSHAKE) {
14870             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
14871                     MAX_PACKETNAME_SZ);
14872         }
14873     }
14874 
14875     /* Add record header to previsouly added packet info */
14876     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
14877     {
14878         /* make sure we have a valid previous one */
14879         if (info->numberPackets > 0 && info->numberPackets <
14880                                                         MAX_PACKETS_HANDSHAKE) {
14881             if (info->packets[info->numberPackets - 1].bufferValue)
14882                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
14883                        RECORD_HEADER_SZ);
14884             else
14885                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
14886                        RECORD_HEADER_SZ);
14887         }
14888     }
14889 
14890 #endif /* WOLFSSL_CALLBACKS */
14891 
14892 
14893 
14894 /* client only parts */
14895 #ifndef NO_WOLFSSL_CLIENT
14896 
14897     int SendClientHello(WOLFSSL* ssl)
14898     {
14899         byte              *output;
14900         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
14901         int                sendSz;
14902         int                idSz = ssl->options.resuming
14903                                 ? ssl->session.sessionIDSz
14904                                 : 0;
14905         int                ret;
14906         word16             extSz = 0;
14907 
14908 
14909 #ifdef WOLFSSL_TLS13
14910         if (IsAtLeastTLSv1_3(ssl->version))
14911             return SendTls13ClientHello(ssl);
14912 #endif
14913 
14914         if (ssl->suites == NULL) {
14915             WOLFSSL_MSG("Bad suites pointer in SendClientHello");
14916             return SUITES_ERROR;
14917         }
14918 
14919 #ifdef HAVE_SESSION_TICKET
14920         if (ssl->options.resuming && ssl->session.ticketLen > 0) {
14921             SessionTicket* ticket;
14922 
14923             ticket = TLSX_SessionTicket_Create(0, ssl->session.ticket,
14924                                              ssl->session.ticketLen, ssl->heap);
14925             if (ticket == NULL) return MEMORY_E;
14926 
14927             ret = TLSX_UseSessionTicket(&ssl->extensions, ticket, ssl->heap);
14928             if (ret != SSL_SUCCESS) return ret;
14929 
14930             idSz = 0;
14931         }
14932 #endif
14933         length = VERSION_SZ + RAN_LEN
14934                + idSz + ENUM_LEN
14935                + ssl->suites->suiteSz + SUITE_LEN
14936                + COMP_LEN + ENUM_LEN;
14937 
14938 #ifdef HAVE_TLS_EXTENSIONS
14939         /* auto populate extensions supported unless user defined */
14940         if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
14941             return ret;
14942     #ifdef HAVE_QSH
14943         if (QSH_Init(ssl) != 0)
14944             return MEMORY_E;
14945     #endif
14946         extSz = TLSX_GetRequestSize(ssl);
14947         if (extSz != 0)
14948             length += extSz;
14949 #else
14950         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
14951             extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ
14952                    + ssl->suites->hashSigAlgoSz;
14953 #ifdef HAVE_EXTENDED_MASTER
14954         if (ssl->options.haveEMS)
14955             extSz += HELLO_EXT_SZ;
14956 #endif
14957         if (extSz != 0)
14958             length += extSz + HELLO_EXT_SZ_SZ;
14959 #endif
14960         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
14961 
14962 #ifdef WOLFSSL_DTLS
14963         if (ssl->options.dtls) {
14964             length += ENUM_LEN;   /* cookie */
14965             if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
14966             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
14967             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
14968         }
14969 #endif
14970 
14971         if (IsEncryptionOn(ssl, 1))
14972             sendSz += MAX_MSG_EXTRA;
14973 
14974         /* check for available size */
14975         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
14976             return ret;
14977 
14978         /* get output buffer */
14979         output = ssl->buffers.outputBuffer.buffer +
14980                  ssl->buffers.outputBuffer.length;
14981 
14982         AddHeaders(output, length, client_hello, ssl);
14983 
14984         /* client hello, first version */
14985         output[idx++] = ssl->version.major;
14986         output[idx++] = ssl->version.minor;
14987         ssl->chVersion = ssl->version;  /* store in case changed */
14988 
14989         /* then random */
14990         if (ssl->options.connectState == CONNECT_BEGIN) {
14991             ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
14992             if (ret != 0)
14993                 return ret;
14994 
14995             /* store random */
14996             XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
14997         } else {
14998 #ifdef WOLFSSL_DTLS
14999             /* send same random on hello again */
15000             XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
15001 #endif
15002         }
15003         idx += RAN_LEN;
15004 
15005         /* then session id */
15006         output[idx++] = (byte)idSz;
15007         if (idSz) {
15008             XMEMCPY(output + idx, ssl->session.sessionID,
15009                                                       ssl->session.sessionIDSz);
15010             idx += ssl->session.sessionIDSz;
15011         }
15012 
15013         /* then DTLS cookie */
15014 #ifdef WOLFSSL_DTLS
15015         if (ssl->options.dtls) {
15016             byte cookieSz = ssl->arrays->cookieSz;
15017 
15018             output[idx++] = cookieSz;
15019             if (cookieSz) {
15020                 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
15021                 idx += cookieSz;
15022             }
15023         }
15024 #endif
15025         /* then cipher suites */
15026         c16toa(ssl->suites->suiteSz, output + idx);
15027         idx += OPAQUE16_LEN;
15028         XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
15029         idx += ssl->suites->suiteSz;
15030 
15031         /* last, compression */
15032         output[idx++] = COMP_LEN;
15033         if (ssl->options.usingCompression)
15034             output[idx++] = ZLIB_COMPRESSION;
15035         else
15036             output[idx++] = NO_COMPRESSION;
15037 
15038 #ifdef HAVE_TLS_EXTENSIONS
15039         idx += TLSX_WriteRequest(ssl, output + idx);
15040 
15041         (void)idx; /* suppress analyzer warning, keep idx current */
15042 #else
15043         if (extSz != 0) {
15044             c16toa(extSz, output + idx);
15045             idx += HELLO_EXT_SZ_SZ;
15046 
15047             if (IsAtLeastTLSv1_2(ssl)) {
15048                 if (ssl->suites->hashSigAlgoSz) {
15049                     int i;
15050                     /* extension type */
15051                     c16toa(HELLO_EXT_SIG_ALGO, output + idx);
15052                     idx += HELLO_EXT_TYPE_SZ;
15053                     /* extension data length */
15054                     c16toa(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz,
15055                            output + idx);
15056                     idx += HELLO_EXT_SZ_SZ;
15057                     /* sig algos length */
15058                     c16toa(ssl->suites->hashSigAlgoSz, output + idx);
15059                     idx += HELLO_EXT_SIGALGO_SZ;
15060                     for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
15061                         output[idx] = ssl->suites->hashSigAlgo[i];
15062                     }
15063                 }
15064             }
15065 #ifdef HAVE_EXTENDED_MASTER
15066             if (ssl->options.haveEMS) {
15067                 c16toa(HELLO_EXT_EXTMS, output + idx);
15068                 idx += HELLO_EXT_TYPE_SZ;
15069                 c16toa(0, output + idx);
15070                 idx += HELLO_EXT_SZ_SZ;
15071             }
15072 #endif
15073         }
15074 #endif
15075 
15076         if (IsEncryptionOn(ssl, 1)) {
15077             byte* input;
15078             int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
15079 
15080             input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
15081             if (input == NULL)
15082                 return MEMORY_E;
15083 
15084             XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
15085             sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
15086                                   handshake, 1, 0, 0);
15087             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
15088 
15089             if (sendSz < 0)
15090                 return sendSz;
15091         } else {
15092             #ifdef WOLFSSL_DTLS
15093                 if (ssl->options.dtls)
15094                     DtlsSEQIncrement(ssl, CUR_ORDER);
15095             #endif
15096             ret = HashOutput(ssl, output, sendSz, 0);
15097             if (ret != 0)
15098                 return ret;
15099         }
15100 
15101         #ifdef WOLFSSL_DTLS
15102             if (IsDtlsNotSctpMode(ssl)) {
15103                 if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
15104                     return ret;
15105             }
15106         #endif
15107 
15108         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
15109 
15110 #ifdef WOLFSSL_CALLBACKS
15111         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
15112         if (ssl->toInfoOn)
15113             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
15114                           ssl->heap);
15115 #endif
15116 
15117         ssl->buffers.outputBuffer.length += sendSz;
15118 
15119         return SendBuffered(ssl);
15120     }
15121 
15122 
15123     static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
15124                                     word32* inOutIdx, word32 size)
15125     {
15126         ProtocolVersion pv;
15127         byte            cookieSz;
15128         word32          begin = *inOutIdx;
15129 
15130 #ifdef WOLFSSL_CALLBACKS
15131         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
15132                                          &ssl->handShakeInfo);
15133         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
15134 #endif
15135 
15136 #ifdef WOLFSSL_DTLS
15137         if (ssl->options.dtls) {
15138             DtlsMsgPoolReset(ssl);
15139         }
15140 #endif
15141 
15142         if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
15143             return BUFFER_ERROR;
15144 
15145         XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
15146         *inOutIdx += OPAQUE16_LEN;
15147 
15148         if (pv.major != DTLS_MAJOR ||
15149                          (pv.minor != DTLS_MINOR && pv.minor != DTLSv1_2_MINOR))
15150             return VERSION_ERROR;
15151 
15152         cookieSz = input[(*inOutIdx)++];
15153 
15154         if (cookieSz) {
15155             if ((*inOutIdx - begin) + cookieSz > size)
15156                 return BUFFER_ERROR;
15157 
15158 #ifdef WOLFSSL_DTLS
15159             if (cookieSz <= MAX_COOKIE_LEN) {
15160                 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
15161                 ssl->arrays->cookieSz = cookieSz;
15162             }
15163 #endif
15164             *inOutIdx += cookieSz;
15165         }
15166 
15167         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
15168         return 0;
15169     }
15170 
15171 
15172     static INLINE int DSH_CheckSessionId(WOLFSSL* ssl)
15173     {
15174         int ret = 0;
15175 
15176 #ifdef HAVE_SECRET_CALLBACK
15177         /* If a session secret callback exists, we are using that
15178          * key instead of the saved session key. */
15179         ret = ret || (ssl->sessionSecretCb != NULL);
15180 #endif
15181 
15182 #ifdef HAVE_SESSION_TICKET
15183         /* server may send blank ticket which may not be expected to indicate
15184          * existing one ok but will also be sending a new one */
15185         ret = ret || (ssl->session.ticketLen > 0);
15186 #endif
15187 
15188         ret = ret ||
15189               (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
15190                                           ssl->session.sessionID, ID_LEN) == 0);
15191 
15192         return ret;
15193     }
15194 
15195     /* Check the version in the received message is valid and set protocol
15196      * version to use.
15197      *
15198      * ssl  The SSL/TLS object.
15199      * pv   The protocol version from the packet.
15200      * returns 0 on success, otherwise failure.
15201      */
15202     int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv)
15203     {
15204 #ifdef WOLFSSL_TLS13
15205         /* TODO: [TLS13] Remove this.
15206          * Translate the draft TLS v1.3 version to final version.
15207          */
15208         if (pv.major == TLS_DRAFT_MAJOR) {
15209             pv.major = SSLv3_MAJOR;
15210             pv.minor = TLSv1_3_MINOR;
15211         }
15212 #endif
15213 
15214         /* Check for upgrade attack. */
15215         if (pv.minor > ssl->version.minor) {
15216             WOLFSSL_MSG("Server using higher version, fatal error");
15217             return VERSION_ERROR;
15218         }
15219         if (pv.minor < ssl->version.minor) {
15220             WOLFSSL_MSG("server using lower version");
15221 
15222             /* Check for downgrade attack. */
15223             if (!ssl->options.downgrade) {
15224                 WOLFSSL_MSG("\tno downgrade allowed, fatal error");
15225                 return VERSION_ERROR;
15226             }
15227             if (pv.minor < ssl->options.minDowngrade) {
15228                 WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
15229                 return VERSION_ERROR;
15230             }
15231 
15232             #ifdef HAVE_SECURE_RENEGOTIATION
15233                 if (ssl->secure_renegotiation &&
15234                                          ssl->secure_renegotiation->enabled &&
15235                                          ssl->options.handShakeDone) {
15236                     WOLFSSL_MSG("Server changed version during scr");
15237                     return VERSION_ERROR;
15238                 }
15239             #endif
15240 
15241             /* Checks made - OK to downgrade. */
15242             if (pv.minor == SSLv3_MINOR) {
15243                 /* turn off tls */
15244                 WOLFSSL_MSG("\tdowngrading to SSLv3");
15245                 ssl->options.tls    = 0;
15246                 ssl->options.tls1_1 = 0;
15247                 ssl->version.minor  = SSLv3_MINOR;
15248             }
15249             else if (pv.minor == TLSv1_MINOR) {
15250                 /* turn off tls 1.1+ */
15251                 WOLFSSL_MSG("\tdowngrading to TLSv1");
15252                 ssl->options.tls1_1 = 0;
15253                 ssl->version.minor  = TLSv1_MINOR;
15254             }
15255             else if (pv.minor == TLSv1_1_MINOR) {
15256                 WOLFSSL_MSG("\tdowngrading to TLSv1.1");
15257                 ssl->version.minor  = TLSv1_1_MINOR;
15258             }
15259             else if (pv.minor == TLSv1_2_MINOR) {
15260                 WOLFSSL_MSG("    downgrading to TLSv1.2");
15261                 ssl->version.minor  = TLSv1_2_MINOR;
15262             }
15263         }
15264 
15265         return 0;
15266     }
15267 
15268     int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
15269                       word32 helloSz)
15270     {
15271         byte            cs0;   /* cipher suite bytes 0, 1 */
15272         byte            cs1;
15273         ProtocolVersion pv;
15274         byte            compression;
15275         word32          i = *inOutIdx;
15276         word32          begin = i;
15277         int             ret;
15278 
15279 #ifdef WOLFSSL_CALLBACKS
15280         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
15281         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
15282 #endif
15283 
15284         /* protocol version, random and session id length check */
15285         if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
15286             return BUFFER_ERROR;
15287 
15288         /* protocol version */
15289         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
15290         i += OPAQUE16_LEN;
15291 
15292         ret = CheckVersion(ssl, pv);
15293         if (ret != 0)
15294             return ret;
15295 
15296 #ifdef WOLFSSL_TLS13
15297         if (IsAtLeastTLSv1_3(pv))
15298             return DoTls13ServerHello(ssl, input, inOutIdx, helloSz);
15299 #endif
15300 
15301         /* random */
15302         XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
15303         i += RAN_LEN;
15304 
15305         /* session id */
15306         ssl->arrays->sessionIDSz = input[i++];
15307 
15308         if (ssl->arrays->sessionIDSz > ID_LEN) {
15309             WOLFSSL_MSG("Invalid session ID size");
15310             ssl->arrays->sessionIDSz = 0;
15311             return BUFFER_ERROR;
15312         }
15313         else if (ssl->arrays->sessionIDSz) {
15314             if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
15315                 return BUFFER_ERROR;
15316 
15317             XMEMCPY(ssl->arrays->sessionID, input + i,
15318                                                       ssl->arrays->sessionIDSz);
15319             i += ssl->arrays->sessionIDSz;
15320             ssl->options.haveSessionId = 1;
15321         }
15322 
15323 
15324         /* suite and compression */
15325         if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
15326             return BUFFER_ERROR;
15327 
15328         cs0 = input[i++];
15329         cs1 = input[i++];
15330 
15331 #ifdef HAVE_SECURE_RENEGOTIATION
15332         if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
15333                                          ssl->options.handShakeDone) {
15334             if (ssl->options.cipherSuite0 != cs0 ||
15335                 ssl->options.cipherSuite  != cs1) {
15336                 WOLFSSL_MSG("Server changed cipher suite during scr");
15337                 return MATCH_SUITE_ERROR;
15338             }
15339         }
15340 #endif
15341 
15342         ssl->options.cipherSuite0 = cs0;
15343         ssl->options.cipherSuite  = cs1;
15344         compression = input[i++];
15345 
15346         if (compression != NO_COMPRESSION && !ssl->options.usingCompression) {
15347             WOLFSSL_MSG("Server forcing compression w/o support");
15348             return COMPRESSION_ERROR;
15349         }
15350 
15351         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
15352             WOLFSSL_MSG("Server refused compression, turning off");
15353             ssl->options.usingCompression = 0;  /* turn off if server refused */
15354         }
15355 
15356         *inOutIdx = i;
15357 
15358 #ifdef HAVE_TLS_EXTENSIONS
15359         if ( (i - begin) < helloSz) {
15360             if (TLSX_SupportExtensions(ssl)) {
15361                 word16 totalExtSz;
15362 
15363                 if ((i - begin) + OPAQUE16_LEN > helloSz)
15364                     return BUFFER_ERROR;
15365 
15366                 ato16(&input[i], &totalExtSz);
15367                 i += OPAQUE16_LEN;
15368 
15369                 if ((i - begin) + totalExtSz > helloSz)
15370                     return BUFFER_ERROR;
15371 
15372                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
15373                                                           totalExtSz, 0, NULL)))
15374                     return ret;
15375 
15376                 i += totalExtSz;
15377                 *inOutIdx = i;
15378             }
15379             else
15380                 *inOutIdx = begin + helloSz; /* skip extensions */
15381         }
15382         else
15383             ssl->options.haveEMS = 0; /* If no extensions, no EMS */
15384 #else
15385         {
15386             int allowExt = 0;
15387             byte pendingEMS = 0;
15388 
15389             if ( (i - begin) < helloSz) {
15390                 if (ssl->version.major == SSLv3_MAJOR &&
15391                     ssl->version.minor >= TLSv1_MINOR) {
15392 
15393                     allowExt = 1;
15394                 }
15395 #ifdef WOLFSSL_DTLS
15396                 if (ssl->version.major == DTLS_MAJOR)
15397                     allowExt = 1;
15398 #endif
15399 
15400                 if (allowExt) {
15401                     word16 totalExtSz;
15402 
15403                     if ((i - begin) + OPAQUE16_LEN > helloSz)
15404                         return BUFFER_ERROR;
15405 
15406                     ato16(&input[i], &totalExtSz);
15407                     i += OPAQUE16_LEN;
15408 
15409                     if ((i - begin) + totalExtSz > helloSz)
15410                         return BUFFER_ERROR;
15411 
15412                     while (totalExtSz) {
15413                         word16 extId, extSz;
15414 
15415                         if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
15416                             return BUFFER_ERROR;
15417 
15418                         ato16(&input[i], &extId);
15419                         i += OPAQUE16_LEN;
15420                         ato16(&input[i], &extSz);
15421                         i += OPAQUE16_LEN;
15422 
15423                         if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
15424                             return BUFFER_ERROR;
15425 
15426                         if (extId == HELLO_EXT_EXTMS)
15427                             pendingEMS = 1;
15428                         else
15429                             i += extSz;
15430 
15431                         totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
15432                     }
15433 
15434                     *inOutIdx = i;
15435                 }
15436                 else
15437                     *inOutIdx = begin + helloSz; /* skip extensions */
15438             }
15439 
15440             if (!pendingEMS && ssl->options.haveEMS)
15441                 ssl->options.haveEMS = 0;
15442         }
15443 #endif
15444 
15445         ssl->options.serverState = SERVER_HELLO_COMPLETE;
15446 
15447         if (IsEncryptionOn(ssl, 0)) {
15448             *inOutIdx += ssl->keys.padSz;
15449         }
15450 
15451 #ifdef HAVE_SECRET_CALLBACK
15452         if (ssl->sessionSecretCb != NULL) {
15453             int secretSz = SECRET_LEN;
15454             ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
15455                                               &secretSz, ssl->sessionSecretCtx);
15456             if (ret != 0 || secretSz != SECRET_LEN)
15457                 return SESSION_SECRET_CB_E;
15458         }
15459 #endif /* HAVE_SECRET_CALLBACK */
15460 
15461         if (ssl->options.resuming) {
15462             if (DSH_CheckSessionId(ssl)) {
15463                 if (SetCipherSpecs(ssl) == 0) {
15464                     ret = -1;
15465 
15466                     XMEMCPY(ssl->arrays->masterSecret,
15467                             ssl->session.masterSecret, SECRET_LEN);
15468                     #ifdef NO_OLD_TLS
15469                         ret = DeriveTlsKeys(ssl);
15470                     #else
15471                         #ifndef NO_TLS
15472                             if (ssl->options.tls)
15473                                 ret = DeriveTlsKeys(ssl);
15474                         #endif
15475                             if (!ssl->options.tls)
15476                                 ret = DeriveKeys(ssl);
15477                     #endif
15478                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
15479 
15480                     return ret;
15481                 }
15482                 else {
15483                     WOLFSSL_MSG("Unsupported cipher suite, DoServerHello");
15484                     return UNSUPPORTED_SUITE;
15485                 }
15486             }
15487             else {
15488                 WOLFSSL_MSG("Server denied resumption attempt");
15489                 ssl->options.resuming = 0; /* server denied resumption try */
15490             }
15491         }
15492         #ifdef WOLFSSL_DTLS
15493             if (ssl->options.dtls) {
15494                 DtlsMsgPoolReset(ssl);
15495             }
15496         #endif
15497 
15498         return SetCipherSpecs(ssl);
15499     }
15500 
15501 
15502     /* Make sure client setup is valid for this suite, true on success */
15503     int VerifyClientSuite(WOLFSSL* ssl)
15504     {
15505         int  havePSK = 0;
15506         byte first   = ssl->options.cipherSuite0;
15507         byte second  = ssl->options.cipherSuite;
15508 
15509         WOLFSSL_ENTER("VerifyClientSuite");
15510 
15511         #ifndef NO_PSK
15512             havePSK = ssl->options.havePSK;
15513         #endif
15514 
15515         if (CipherRequires(first, second, REQUIRES_PSK)) {
15516             WOLFSSL_MSG("Requires PSK");
15517             if (havePSK == 0) {
15518                 WOLFSSL_MSG("Don't have PSK");
15519                 return 0;
15520             }
15521         }
15522 
15523         return 1;  /* success */
15524     }
15525 
15526 
15527 #ifndef NO_CERTS
15528     /* just read in and ignore for now TODO: */
15529     static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*
15530                                     inOutIdx, word32 size)
15531     {
15532         word16 len;
15533         word32 begin = *inOutIdx;
15534 
15535         #ifdef WOLFSSL_CALLBACKS
15536             if (ssl->hsInfoOn)
15537                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
15538             if (ssl->toInfoOn)
15539                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
15540         #endif
15541 
15542         if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
15543             return BUFFER_ERROR;
15544 
15545         len = input[(*inOutIdx)++];
15546 
15547         if ((*inOutIdx - begin) + len > size)
15548             return BUFFER_ERROR;
15549 
15550         /* types, read in here */
15551         *inOutIdx += len;
15552 
15553         /* signature and hash signature algorithm */
15554         if (IsAtLeastTLSv1_2(ssl)) {
15555             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
15556                 return BUFFER_ERROR;
15557 
15558             ato16(input + *inOutIdx, &len);
15559             *inOutIdx += OPAQUE16_LEN;
15560 
15561             if ((*inOutIdx - begin) + len > size)
15562                 return BUFFER_ERROR;
15563 
15564             PickHashSigAlgo(ssl, input + *inOutIdx, len);
15565             *inOutIdx += len;
15566         }
15567 
15568         /* authorities */
15569         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
15570             return BUFFER_ERROR;
15571 
15572         ato16(input + *inOutIdx, &len);
15573         *inOutIdx += OPAQUE16_LEN;
15574 
15575         if ((*inOutIdx - begin) + len > size)
15576             return BUFFER_ERROR;
15577 
15578         while (len) {
15579             word16 dnSz;
15580 
15581             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
15582                 return BUFFER_ERROR;
15583 
15584             ato16(input + *inOutIdx, &dnSz);
15585             *inOutIdx += OPAQUE16_LEN;
15586 
15587             if ((*inOutIdx - begin) + dnSz > size)
15588                 return BUFFER_ERROR;
15589 
15590             *inOutIdx += dnSz;
15591             len -= OPAQUE16_LEN + dnSz;
15592         }
15593 
15594         /* don't send client cert or cert verify if user hasn't provided
15595            cert and private key */
15596         if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
15597             ssl->buffers.key && ssl->buffers.key->buffer)
15598             ssl->options.sendVerify = SEND_CERT;
15599         else if (IsTLS(ssl))
15600             ssl->options.sendVerify = SEND_BLANK_CERT;
15601 
15602         if (IsEncryptionOn(ssl, 0))
15603             *inOutIdx += ssl->keys.padSz;
15604 
15605         return 0;
15606     }
15607 #endif /* !NO_CERTS */
15608 
15609 
15610 #ifdef HAVE_ECC
15611 
15612     static int CheckCurveId(int tlsCurveId)
15613     {
15614         int ret = ECC_CURVE_ERROR;
15615 
15616         switch (tlsCurveId) {
15617     #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
15618         #ifndef NO_ECC_SECP
15619             case WOLFSSL_ECC_SECP160R1: return ECC_SECP160R1_OID;
15620         #endif /* !NO_ECC_SECP */
15621         #ifdef HAVE_ECC_SECPR2
15622             case WOLFSSL_ECC_SECP160R2: return ECC_SECP160R2_OID;
15623         #endif /* HAVE_ECC_SECPR2 */
15624         #ifdef HAVE_ECC_KOBLITZ
15625             case WOLFSSL_ECC_SECP160K1: return ECC_SECP160K1_OID;
15626         #endif /* HAVE_ECC_KOBLITZ */
15627     #endif
15628     #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
15629         #ifndef NO_ECC_SECP
15630             case WOLFSSL_ECC_SECP192R1: return ECC_SECP192R1_OID;
15631         #endif /* !NO_ECC_SECP */
15632         #ifdef HAVE_ECC_KOBLITZ
15633             case WOLFSSL_ECC_SECP192K1: return ECC_SECP192K1_OID;
15634         #endif /* HAVE_ECC_KOBLITZ */
15635     #endif
15636     #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
15637         #ifndef NO_ECC_SECP
15638             case WOLFSSL_ECC_SECP224R1: return ECC_SECP224R1_OID;
15639         #endif /* !NO_ECC_SECP */
15640         #ifdef HAVE_ECC_KOBLITZ
15641             case WOLFSSL_ECC_SECP224K1: return ECC_SECP224K1_OID;
15642         #endif /* HAVE_ECC_KOBLITZ */
15643     #endif
15644     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
15645         #ifndef NO_ECC_SECP
15646             case WOLFSSL_ECC_SECP256R1: return ECC_SECP256R1_OID;
15647         #endif /* !NO_ECC_SECP */
15648         #ifdef HAVE_ECC_KOBLITZ
15649             case WOLFSSL_ECC_SECP256K1: return ECC_SECP256K1_OID;
15650         #endif /* HAVE_ECC_KOBLITZ */
15651         #ifdef HAVE_ECC_BRAINPOOL
15652             case WOLFSSL_ECC_BRAINPOOLP256R1: return ECC_BRAINPOOLP256R1_OID;
15653         #endif /* HAVE_ECC_BRAINPOOL */
15654     #endif
15655     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
15656         #ifndef NO_ECC_SECP
15657             case WOLFSSL_ECC_SECP384R1: return ECC_SECP384R1_OID;
15658         #endif /* !NO_ECC_SECP */
15659         #ifdef HAVE_ECC_BRAINPOOL
15660             case WOLFSSL_ECC_BRAINPOOLP384R1: return ECC_BRAINPOOLP384R1_OID;
15661         #endif /* HAVE_ECC_BRAINPOOL */
15662     #endif
15663     #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
15664         #ifdef HAVE_ECC_BRAINPOOL
15665             case WOLFSSL_ECC_BRAINPOOLP512R1: return ECC_BRAINPOOLP512R1_OID;
15666         #endif /* HAVE_ECC_BRAINPOOL */
15667     #endif
15668     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
15669         #ifndef NO_ECC_SECP
15670             case WOLFSSL_ECC_SECP521R1: return ECC_SECP521R1_OID;
15671         #endif /* !NO_ECC_SECP */
15672     #endif
15673         }
15674 
15675         return ret;
15676     }
15677 
15678 #endif /* HAVE_ECC */
15679 
15680 
15681 /* Persistable DoServerKeyExchange arguments */
15682 typedef struct DskeArgs {
15683     byte*  output; /* not allocated */
15684 #if !defined(NO_DH) || defined(HAVE_ECC)
15685     byte*  verifySig;
15686 #endif
15687     word32 idx;
15688     word32 begin;
15689 #ifndef NO_RSA
15690     int    typeH;
15691 #endif
15692 #if !defined(NO_DH) || defined(HAVE_ECC)
15693     word16 verifySigSz;
15694 #endif
15695     word16 sigSz;
15696     byte   sigAlgo;
15697 } DskeArgs;
15698 
15699 static void FreeDskeArgs(WOLFSSL* ssl, void* pArgs)
15700 {
15701     DskeArgs* args = (DskeArgs*)pArgs;
15702 
15703     (void)ssl;
15704     (void)args;
15705 
15706 #if !defined(NO_DH) || defined(HAVE_ECC)
15707     if (args->verifySig) {
15708         XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
15709         args->verifySig = NULL;
15710     }
15711 #endif
15712 }
15713 
15714 static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
15715                                word32* inOutIdx, word32 size)
15716 {
15717     int ret = 0;
15718 #ifdef WOLFSSL_ASYNC_CRYPT
15719     DskeArgs* args = (DskeArgs*)ssl->async.args;
15720     typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
15721     (void)sizeof(args_test);
15722 #else
15723     DskeArgs  args[1];
15724 #endif
15725 
15726     WOLFSSL_ENTER("DoServerKeyExchange");
15727 
15728 #ifdef WOLFSSL_ASYNC_CRYPT
15729     ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
15730     if (ret != WC_NOT_PENDING_E) {
15731         /* Check for error */
15732         if (ret < 0)
15733             goto exit_dske;
15734     }
15735     else
15736 #endif
15737     {
15738         /* Reset state */
15739         ret = 0;
15740         ssl->options.asyncState = TLS_ASYNC_BEGIN;
15741         XMEMSET(args, 0, sizeof(DskeArgs));
15742         args->idx = *inOutIdx;
15743         args->begin = *inOutIdx;
15744         args->sigAlgo = ssl->specs.sig_algo;
15745     #ifdef WOLFSSL_ASYNC_CRYPT
15746         ssl->async.freeArgs = FreeDskeArgs;
15747     #endif
15748     }
15749 
15750     switch(ssl->options.asyncState)
15751     {
15752         case TLS_ASYNC_BEGIN:
15753         {
15754         #ifdef WOLFSSL_CALLBACKS
15755             if (ssl->hsInfoOn)
15756                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
15757             if (ssl->toInfoOn)
15758                 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
15759         #endif
15760 
15761             switch(ssl->specs.kea)
15762             {
15763             #ifndef NO_PSK
15764                 case psk_kea:
15765                 {
15766                     int srvHintLen;
15767                     word16 length;
15768 
15769                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15770                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15771                     }
15772 
15773                     ato16(input + args->idx, &length);
15774                     args->idx += OPAQUE16_LEN;
15775 
15776                     if ((args->idx - args->begin) + length > size) {
15777                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15778                     }
15779 
15780                     /* get PSK server hint from the wire */
15781                     srvHintLen = min(length, MAX_PSK_ID_LEN);
15782                     XMEMCPY(ssl->arrays->server_hint, input + args->idx,
15783                                                                     srvHintLen);
15784                     ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
15785                     args->idx += length;
15786                     break;
15787                 }
15788             #endif /* !NO_PSK */
15789             #ifndef NO_DH
15790                 case diffie_hellman_kea:
15791                 {
15792                     word16 length;
15793 
15794                     /* p */
15795                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15796                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15797                     }
15798 
15799                     ato16(input + args->idx, &length);
15800                     args->idx += OPAQUE16_LEN;
15801 
15802                     if ((args->idx - args->begin) + length > size) {
15803                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15804                     }
15805 
15806                     if (length < ssl->options.minDhKeySz) {
15807                         WOLFSSL_MSG("Server using a DH key that is too small");
15808                         SendAlert(ssl, alert_fatal, handshake_failure);
15809                         ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
15810                     }
15811 
15812                     ssl->buffers.serverDH_P.buffer =
15813                         (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15814                     if (ssl->buffers.serverDH_P.buffer) {
15815                         ssl->buffers.serverDH_P.length = length;
15816                     }
15817                     else {
15818                         ERROR_OUT(MEMORY_ERROR, exit_dske);
15819                     }
15820 
15821                     XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
15822                                                                         length);
15823                     args->idx += length;
15824 
15825                     ssl->options.dhKeySz = length;
15826 
15827                     /* g */
15828                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15829                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15830                     }
15831 
15832                     ato16(input + args->idx, &length);
15833                     args->idx += OPAQUE16_LEN;
15834 
15835                     if ((args->idx - args->begin) + length > size) {
15836                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15837                     }
15838 
15839                     ssl->buffers.serverDH_G.buffer =
15840                         (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15841                     if (ssl->buffers.serverDH_G.buffer) {
15842                         ssl->buffers.serverDH_G.length = length;
15843                     }
15844                     else {
15845                         ERROR_OUT(MEMORY_ERROR, exit_dske);
15846                     }
15847 
15848                     XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
15849                                                                         length);
15850                     args->idx += length;
15851 
15852                     /* pub */
15853                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15854                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15855                     }
15856 
15857                     ato16(input + args->idx, &length);
15858                     args->idx += OPAQUE16_LEN;
15859 
15860                     if ((args->idx - args->begin) + length > size) {
15861                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15862                     }
15863 
15864                     ssl->buffers.serverDH_Pub.buffer =
15865                         (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15866                     if (ssl->buffers.serverDH_Pub.buffer) {
15867                         ssl->buffers.serverDH_Pub.length = length;
15868                     }
15869                     else {
15870                         ERROR_OUT(MEMORY_ERROR, exit_dske);
15871                     }
15872 
15873                     XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
15874                                                                         length);
15875                     args->idx += length;
15876                     break;
15877                 }
15878             #endif /* !NO_DH */
15879             #ifdef HAVE_ECC
15880                 case ecc_diffie_hellman_kea:
15881                 {
15882                     byte b;
15883                     int curveId, curveOid;
15884                     word16 length;
15885 
15886                     if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN +
15887                                                         OPAQUE8_LEN > size) {
15888                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15889                     }
15890 
15891                     b = input[args->idx++];
15892                     if (b != named_curve) {
15893                         ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske);
15894                     }
15895 
15896                     args->idx += 1;   /* curve type, eat leading 0 */
15897                     b = input[args->idx++];
15898                     if ((curveOid = CheckCurveId(b)) < 0) {
15899                         ERROR_OUT(ECC_CURVE_ERROR, exit_dske);
15900                     }
15901                     ssl->ecdhCurveOID = curveOid;
15902 
15903                     length = input[args->idx++];
15904                     if ((args->idx - args->begin) + length > size) {
15905                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15906                     }
15907 
15908                     if (ssl->peerEccKey == NULL) {
15909                         /* alloc/init on demand */
15910                         ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
15911                                                 ssl->heap, DYNAMIC_TYPE_ECC);
15912                         if (ssl->peerEccKey == NULL) {
15913                             WOLFSSL_MSG("PeerEccKey Memory error");
15914                             ERROR_OUT(MEMORY_E, exit_dske);
15915                         }
15916                         ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
15917                                                                 ssl->devId);
15918                         if (ret != 0) {
15919                             goto exit_dske;
15920                         }
15921                     } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
15922                         wc_ecc_free(ssl->peerEccKey);
15923                         ssl->peerEccKeyPresent = 0;
15924                         ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId);
15925                         if (ret != 0) {
15926                             goto exit_dske;
15927                         }
15928                     }
15929 
15930                     curveId = wc_ecc_get_oid(curveOid, NULL, NULL);
15931                     if (wc_ecc_import_x963_ex(input + args->idx, length,
15932                                         ssl->peerEccKey, curveId) != 0) {
15933                         ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
15934                     }
15935 
15936                     args->idx += length;
15937                     ssl->peerEccKeyPresent = 1;
15938                     break;
15939                 }
15940             #endif /* HAVE_ECC */
15941             #if !defined(NO_DH) && !defined(NO_PSK)
15942                 case dhe_psk_kea:
15943                 {
15944                     int srvHintLen;
15945                     word16 length;
15946 
15947                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15948                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15949                     }
15950 
15951                     ato16(input + args->idx, &length);
15952                     args->idx += OPAQUE16_LEN;
15953 
15954                     if ((args->idx - args->begin) + length > size) {
15955                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15956                     }
15957 
15958                     /* get PSK server hint from the wire */
15959                     srvHintLen = min(length, MAX_PSK_ID_LEN);
15960                     XMEMCPY(ssl->arrays->server_hint, input + args->idx,
15961                                                                 srvHintLen);
15962                     ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
15963                     args->idx += length;
15964 
15965                     /* p */
15966                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
15967                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15968                     }
15969 
15970                     ato16(input + args->idx, &length);
15971                     args->idx += OPAQUE16_LEN;
15972 
15973                     if ((args->idx - args->begin) + length > size) {
15974                         ERROR_OUT(BUFFER_ERROR, exit_dske);
15975                     }
15976 
15977                     if (length < ssl->options.minDhKeySz) {
15978                         WOLFSSL_MSG("Server using a DH key that is too small");
15979                         SendAlert(ssl, alert_fatal, handshake_failure);
15980                         ERROR_OUT(DH_KEY_SIZE_E, exit_dske);
15981                     }
15982 
15983                     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length,
15984                                                 ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
15985                     if (ssl->buffers.serverDH_P.buffer) {
15986                         ssl->buffers.serverDH_P.length = length;
15987                     }
15988                     else {
15989                         ERROR_OUT(MEMORY_ERROR, exit_dske);
15990                     }
15991 
15992                     XMEMCPY(ssl->buffers.serverDH_P.buffer, input + args->idx,
15993                                                                         length);
15994                     args->idx += length;
15995 
15996                     ssl->options.dhKeySz = length;
15997 
15998                     /* g */
15999                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
16000                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16001                     }
16002 
16003                     ato16(input + args->idx, &length);
16004                     args->idx += OPAQUE16_LEN;
16005 
16006                     if ((args->idx - args->begin) + length > size) {
16007                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16008                     }
16009 
16010                     ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(length,
16011                                                 ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
16012                     if (ssl->buffers.serverDH_G.buffer) {
16013                         ssl->buffers.serverDH_G.length = length;
16014                     }
16015                     else {
16016                         ERROR_OUT(MEMORY_ERROR, exit_dske);
16017                     }
16018 
16019                     XMEMCPY(ssl->buffers.serverDH_G.buffer, input + args->idx,
16020                                                                         length);
16021                     args->idx += length;
16022 
16023                     /* pub */
16024                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
16025                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16026                     }
16027 
16028                     ato16(input + args->idx, &length);
16029                     args->idx += OPAQUE16_LEN;
16030 
16031                     if ((args->idx - args->begin) + length > size) {
16032                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16033                     }
16034 
16035                     ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(length,
16036                                                 ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
16037                     if (ssl->buffers.serverDH_Pub.buffer) {
16038                         ssl->buffers.serverDH_Pub.length = length;
16039                     }
16040                     else {
16041                         ERROR_OUT(MEMORY_ERROR, exit_dske);
16042                     }
16043 
16044                     XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + args->idx,
16045                                                                         length);
16046                     args->idx += length;
16047                     break;
16048                 }
16049             #endif /* !NO_DH || !NO_PSK */
16050             #if defined(HAVE_ECC) && !defined(NO_PSK)
16051                 case ecdhe_psk_kea:
16052                 {
16053                     byte b;
16054                     int curveOid, curveId;
16055                     int srvHintLen;
16056                     word16 length;
16057 
16058                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
16059                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16060                     }
16061 
16062                     ato16(input + args->idx, &length);
16063                     args->idx += OPAQUE16_LEN;
16064 
16065                     if ((args->idx - args->begin) + length > size) {
16066                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16067                     }
16068 
16069                     /* get PSK server hint from the wire */
16070                     srvHintLen = min(length, MAX_PSK_ID_LEN);
16071                     XMEMCPY(ssl->arrays->server_hint, input + args->idx,
16072                                                                     srvHintLen);
16073                     ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */
16074 
16075                     args->idx += length;
16076 
16077                     if ((args->idx - args->begin) + ENUM_LEN + OPAQUE16_LEN +
16078                         OPAQUE8_LEN > size) {
16079                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16080                     }
16081 
16082                     /* Check curve name and ID */
16083                     b = input[args->idx++];
16084                     if (b != named_curve) {
16085                         ERROR_OUT(ECC_CURVETYPE_ERROR, exit_dske);
16086                     }
16087 
16088                     args->idx += 1;   /* curve type, eat leading 0 */
16089                     b = input[args->idx++];
16090                     if ((curveOid = CheckCurveId(b)) < 0) {
16091                         ERROR_OUT(ECC_CURVE_ERROR, exit_dske);
16092                     }
16093 
16094                     length = input[args->idx++];
16095                     if ((args->idx - args->begin) + length > size) {
16096                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16097                     }
16098 
16099                     if (ssl->peerEccKey == NULL) {
16100                         /* alloc/init on demand */
16101                         ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
16102                                                    ssl->heap, DYNAMIC_TYPE_ECC);
16103                         if (ssl->peerEccKey == NULL) {
16104                             WOLFSSL_MSG("PeerEccKey Memory error");
16105                             ERROR_OUT(MEMORY_E, exit_dske);
16106                         }
16107                         ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
16108                                                                     ssl->devId);
16109                         if (ret != 0) {
16110                             goto exit_dske;
16111                         }
16112                     } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
16113                         wc_ecc_free(ssl->peerEccKey);
16114                         ssl->peerEccKeyPresent = 0;
16115                         ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
16116                                                                     ssl->devId);
16117                         if (ret != 0) {
16118                             goto exit_dske;
16119                         }
16120                     }
16121 
16122                     curveId = wc_ecc_get_oid(curveOid, NULL, NULL);
16123                     if (wc_ecc_import_x963_ex(input + args->idx, length,
16124                         ssl->peerEccKey, curveId) != 0) {
16125                         ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske);
16126                     }
16127 
16128                     args->idx += length;
16129                     ssl->peerEccKeyPresent = 1;
16130                     break;
16131                 }
16132             #endif /* HAVE_ECC || !NO_PSK */
16133                 default:
16134                     ret = BAD_KEA_TYPE_E;
16135             } /* switch(ssl->specs.kea) */
16136 
16137             /* Check for error */
16138             if (ret != 0) {
16139                 goto exit_dske;
16140             }
16141 
16142             /* Advance state and proceed */
16143             ssl->options.asyncState = TLS_ASYNC_BUILD;
16144         } /* case TLS_ASYNC_BEGIN */
16145 
16146         case TLS_ASYNC_BUILD:
16147         {
16148             switch(ssl->specs.kea)
16149             {
16150                 case psk_kea:
16151                 case dhe_psk_kea:
16152                 case ecdhe_psk_kea:
16153                 {
16154                     /* Nothing to do in this sub-state */
16155                     break;
16156                 }
16157 
16158                 case diffie_hellman_kea:
16159                 case ecc_diffie_hellman_kea:
16160                 {
16161             #if defined(NO_DH) && !defined(HAVE_ECC)
16162                     ERROR_OUT(NOT_COMPILED_IN, exit_dske);
16163             #else
16164                     byte    hashAlgo = sha_mac;
16165                     enum wc_HashType hashType = WC_HASH_TYPE_NONE;
16166                     word16  verifySz;
16167 
16168                     if (ssl->options.usingAnon_cipher) {
16169                         break;
16170                     }
16171 
16172                     verifySz = (word16)(args->idx - args->begin);
16173                     if (verifySz > MAX_DH_SZ) {
16174                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16175                     }
16176 
16177                     if (IsAtLeastTLSv1_2(ssl)) {
16178                         if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN >
16179                                                                         size) {
16180                             ERROR_OUT(BUFFER_ERROR, exit_dske);
16181                         }
16182 
16183                         hashAlgo = input[args->idx++];
16184                         args->sigAlgo  = input[args->idx++];
16185 
16186                         switch (hashAlgo) {
16187                             case sha512_mac:
16188                             #ifdef WOLFSSL_SHA512
16189                                 hashType = WC_HASH_TYPE_SHA512;
16190                             #endif
16191                                 break;
16192                             case sha384_mac:
16193                             #ifdef WOLFSSL_SHA384
16194                                 hashType = WC_HASH_TYPE_SHA384;
16195                             #endif
16196                                 break;
16197                             case sha256_mac:
16198                             #ifndef NO_SHA256
16199                                 hashType = WC_HASH_TYPE_SHA256;
16200                             #endif
16201                                 break;
16202                             case sha_mac:
16203                                 #if !defined(NO_SHA) && \
16204                                       (!defined(NO_OLD_TLS) || \
16205                                         defined(WOLFSSL_ALLOW_TLS_SHA1))
16206                                     hashType = WC_HASH_TYPE_SHA;
16207                                 #endif
16208                                 break;
16209                             default:
16210                                 WOLFSSL_MSG("Bad hash sig algo");
16211                                 break;
16212                         }
16213 
16214                         if (hashType == WC_HASH_TYPE_NONE) {
16215                             ERROR_OUT(ALGO_ID_E, exit_dske);
16216                         }
16217                     } else {
16218                         /* only using sha and md5 for rsa */
16219                         #ifndef NO_OLD_TLS
16220                             hashType = WC_HASH_TYPE_SHA;
16221                             if (args->sigAlgo == rsa_sa_algo) {
16222                                 hashType = WC_HASH_TYPE_MD5_SHA;
16223                             }
16224                         #else
16225                             ERROR_OUT(ALGO_ID_E, exit_dske);
16226                         #endif
16227                     }
16228                 #ifndef NO_RSA
16229                     args->typeH = wc_HashGetOID(hashType);
16230                 #endif
16231 
16232                     /* signature */
16233                     if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
16234                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16235                     }
16236 
16237                     ato16(input + args->idx, &args->verifySigSz);
16238                     args->idx += OPAQUE16_LEN;
16239 
16240                     if ((args->idx - args->begin) + args->verifySigSz > size) {
16241                         ERROR_OUT(BUFFER_ERROR, exit_dske);
16242                     }
16243 
16244                     /* buffer for signature */
16245                     ssl->buffers.sig.buffer = (byte*)XMALLOC(SEED_LEN + verifySz,
16246                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16247                     if (ssl->buffers.sig.buffer == NULL) {
16248                         ERROR_OUT(MEMORY_E, exit_dske);
16249                     }
16250                     ssl->buffers.sig.length = SEED_LEN + verifySz;
16251 
16252                     /* buffer for hash */
16253                     ssl->buffers.digest.length = wc_HashGetDigestSize(hashType);
16254                     ssl->buffers.digest.buffer = (byte*)XMALLOC(
16255                         ssl->buffers.digest.length, ssl->heap,
16256                         DYNAMIC_TYPE_TMP_BUFFER);
16257                     if (ssl->buffers.digest.buffer == NULL) {
16258                         ERROR_OUT(MEMORY_E, exit_dske);
16259                     }
16260 
16261                     /* build message to hash */
16262                     XMEMCPY(ssl->buffers.sig.buffer,
16263                         ssl->arrays->clientRandom, RAN_LEN);
16264                     XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN],
16265                         ssl->arrays->serverRandom, RAN_LEN);
16266                     XMEMCPY(&ssl->buffers.sig.buffer[RAN_LEN * 2],
16267                         input + args->begin, verifySz); /* message */
16268 
16269                     /* Perform hash */
16270                     ret = wc_Hash(hashType,
16271                             ssl->buffers.sig.buffer, ssl->buffers.sig.length,
16272                             ssl->buffers.digest.buffer, ssl->buffers.digest.length);
16273                     if (ret != 0) {
16274                         goto exit_dske;
16275                     }
16276 
16277                     switch (args->sigAlgo)
16278                     {
16279                     #ifndef NO_RSA
16280                         case rsa_sa_algo:
16281                         {
16282                             if (ssl->peerRsaKey == NULL ||
16283                                                     !ssl->peerRsaKeyPresent) {
16284                                 ERROR_OUT(NO_PEER_KEY, exit_dske);
16285                             }
16286                             break;
16287                         }
16288                     #endif /* !NO_RSA */
16289                     #ifdef HAVE_ECC
16290                         case ecc_dsa_sa_algo:
16291                         {
16292                             if (!ssl->peerEccDsaKeyPresent) {
16293                                 ERROR_OUT(NO_PEER_KEY, exit_dske);
16294                             }
16295                             break;
16296                         }
16297                     #endif /* HAVE_ECC */
16298 
16299                     default:
16300                         ret = ALGO_ID_E;
16301                     } /* switch (args->sigAlgo) */
16302 
16303             #endif /* NO_DH && !HAVE_ECC */
16304                     break;
16305                 }
16306                 default:
16307                     ret = BAD_KEA_TYPE_E;
16308             } /* switch(ssl->specs.kea) */
16309 
16310             /* Check for error */
16311             if (ret != 0) {
16312                 goto exit_dske;
16313             }
16314 
16315             /* Advance state and proceed */
16316             ssl->options.asyncState = TLS_ASYNC_DO;
16317         } /* case TLS_ASYNC_BUILD */
16318 
16319         case TLS_ASYNC_DO:
16320         {
16321             switch(ssl->specs.kea)
16322             {
16323                 case psk_kea:
16324                 case dhe_psk_kea:
16325                 case ecdhe_psk_kea:
16326                 {
16327                     /* Nothing to do in this sub-state */
16328                     break;
16329                 }
16330 
16331                 case diffie_hellman_kea:
16332                 case ecc_diffie_hellman_kea:
16333                 {
16334             #if defined(NO_DH) && !defined(HAVE_ECC)
16335                     ERROR_OUT(NOT_COMPILED_IN, exit_dske);
16336             #else
16337                     if (ssl->options.usingAnon_cipher) {
16338                         break;
16339                     }
16340 
16341                     if (args->verifySig == NULL) {
16342                         args->verifySig = (byte*)XMALLOC(args->verifySigSz,
16343                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16344                         if (args->verifySig == NULL) {
16345                             ERROR_OUT(MEMORY_E, exit_dske);
16346                         }
16347                         XMEMCPY(args->verifySig, input + args->idx,
16348                                                             args->verifySigSz);
16349                     }
16350 
16351                     switch (args->sigAlgo)
16352                     {
16353                     #ifndef NO_RSA
16354                         case rsa_sa_algo:
16355                         {
16356                             ret = RsaVerify(ssl,
16357                                 args->verifySig, args->verifySigSz,
16358                                 &args->output,
16359                                 rsa_sa_algo, no_mac,
16360                                 ssl->peerRsaKey,
16361                             #ifdef HAVE_PK_CALLBACKS
16362                                 ssl->buffers.peerRsaKey.buffer,
16363                                 ssl->buffers.peerRsaKey.length,
16364                                 ssl->RsaVerifyCtx
16365                             #else
16366                                 NULL, 0, NULL
16367                             #endif
16368                             );
16369 
16370                             if (ret >= 0) {
16371                                 args->sigSz = (word16)ret;
16372                                 ret = 0;
16373                             }
16374                             break;
16375                         }
16376                     #endif /* !NO_RSA */
16377                     #ifdef HAVE_ECC
16378                         case ecc_dsa_sa_algo:
16379                         {
16380                             ret = EccVerify(ssl,
16381                                 args->verifySig, args->verifySigSz,
16382                                 ssl->buffers.digest.buffer,
16383                                 ssl->buffers.digest.length,
16384                                 ssl->peerEccDsaKey,
16385                             #ifdef HAVE_PK_CALLBACKS
16386                                 ssl->buffers.peerEccDsaKey.buffer,
16387                                 ssl->buffers.peerEccDsaKey.length,
16388                                 ssl->EccVerifyCtx
16389                             #else
16390                                 NULL, 0, NULL
16391                             #endif
16392                             );
16393 
16394                             break;
16395                         }
16396                     #endif /* HAVE_ECC */
16397 
16398                     default:
16399                         ret = ALGO_ID_E;
16400                     } /* switch (sigAlgo) */
16401             #endif /* NO_DH && !HAVE_ECC */
16402                     break;
16403                 }
16404                 default:
16405                     ret = BAD_KEA_TYPE_E;
16406             } /* switch(ssl->specs.kea) */
16407 
16408             /* Check for error */
16409             if (ret != 0) {
16410                 goto exit_dske;
16411             }
16412 
16413             /* Advance state and proceed */
16414             ssl->options.asyncState = TLS_ASYNC_VERIFY;
16415         } /* case TLS_ASYNC_DO */
16416 
16417         case TLS_ASYNC_VERIFY:
16418         {
16419             switch(ssl->specs.kea)
16420             {
16421                 case psk_kea:
16422                 case dhe_psk_kea:
16423                 case ecdhe_psk_kea:
16424                 {
16425                     /* Nothing to do in this sub-state */
16426                     break;
16427                 }
16428 
16429                 case diffie_hellman_kea:
16430                 case ecc_diffie_hellman_kea:
16431                 {
16432             #if defined(NO_DH) && !defined(HAVE_ECC)
16433                     ERROR_OUT(NOT_COMPILED_IN, exit_dske);
16434             #else
16435                     if (ssl->options.usingAnon_cipher) {
16436                         break;
16437                     }
16438 
16439                     /* increment index after verify is done */
16440                     args->idx += args->verifySigSz;
16441 
16442                     switch(args->sigAlgo)
16443                     {
16444                     #ifndef NO_RSA
16445                         case rsa_sa_algo:
16446                         {
16447                             if (IsAtLeastTLSv1_2(ssl)) {
16448                             #ifdef WOLFSSL_SMALL_STACK
16449                                 byte*  encodedSig = NULL;
16450                             #else
16451                                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
16452                             #endif
16453                                 word32 encSigSz;
16454 
16455                             #ifdef WOLFSSL_SMALL_STACK
16456                                 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
16457                                                 ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16458                                 if (encodedSig == NULL) {
16459                                     ERROR_OUT(MEMORY_E, exit_dske);
16460                                 }
16461                             #endif
16462 
16463                                 encSigSz = wc_EncodeSignature(encodedSig,
16464                                     ssl->buffers.digest.buffer,
16465                                     ssl->buffers.digest.length, args->typeH);
16466                                 if (encSigSz != args->sigSz || !args->output ||
16467                                     XMEMCMP(args->output, encodedSig,
16468                                             min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) {
16469                                     ret = VERIFY_SIGN_ERROR;
16470                                 }
16471                             #ifdef WOLFSSL_SMALL_STACK
16472                                 XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16473                             #endif
16474                                 if (ret != 0) {
16475                                     goto exit_dske;
16476                                 }
16477                             }
16478                             else if (args->sigSz != FINISHED_SZ ||
16479                                     !args->output ||
16480                                     XMEMCMP(args->output,
16481                                             ssl->buffers.digest.buffer,
16482                                             FINISHED_SZ) != 0) {
16483                                 ERROR_OUT(VERIFY_SIGN_ERROR, exit_dske);
16484                             }
16485                             break;
16486                         }
16487                     #endif /* !NO_RSA */
16488                     #ifdef HAVE_ECC
16489                         case ecc_dsa_sa_algo:
16490                             /* Nothing to do in this algo */
16491                             break;
16492                     #endif /* HAVE_ECC */
16493                         default:
16494                             ret = ALGO_ID_E;
16495                     } /* switch (sigAlgo) */
16496             #endif /* NO_DH && !HAVE_ECC */
16497                     break;
16498                 }
16499                 default:
16500                     ret = BAD_KEA_TYPE_E;
16501             } /* switch(ssl->specs.kea) */
16502 
16503             /* Check for error */
16504             if (ret != 0) {
16505                 goto exit_dske;
16506             }
16507 
16508             /* Advance state and proceed */
16509             ssl->options.asyncState = TLS_ASYNC_FINALIZE;
16510         } /* case TLS_ASYNC_VERIFY */
16511 
16512         case TLS_ASYNC_FINALIZE:
16513         {
16514             if (IsEncryptionOn(ssl, 0)) {
16515                 args->idx += ssl->keys.padSz;
16516             }
16517 
16518             /* QSH extensions */
16519         #ifdef HAVE_QSH
16520             if (ssl->peerQSHKeyPresent) {
16521                 word16 name;
16522                 int    qshSz;
16523 
16524                 /* extension name */
16525                 ato16(input + args->idx, &name);
16526                 args->idx += OPAQUE16_LEN;
16527 
16528                 if (name == TLSX_QUANTUM_SAFE_HYBRID) {
16529                     /* if qshSz is larger than 0 it is the length of
16530                        buffer used */
16531                     if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + args->idx,
16532                                                        size, 0)) < 0) {
16533                         ERROR_OUT(qshSz, exit_dske);
16534                     }
16535                     args->idx += qshSz;
16536                 }
16537                 else {
16538                     /* unknown extension sent server ignored handshake */
16539                     ERROR_OUT(BUFFER_ERROR, exit_dske);
16540                 }
16541             }
16542         #endif
16543 
16544             /* Advance state and proceed */
16545             ssl->options.asyncState = TLS_ASYNC_END;
16546         } /* case TLS_ASYNC_FINALIZE */
16547 
16548         case TLS_ASYNC_END:
16549         {
16550             /* return index */
16551             *inOutIdx = args->idx;
16552 
16553             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
16554             break;
16555         }
16556         default:
16557             ret = INPUT_CASE_ERROR;
16558     } /* switch(ssl->options.asyncState) */
16559 
16560 exit_dske:
16561 
16562     WOLFSSL_LEAVE("DoServerKeyExchange", ret);
16563 
16564 #ifdef WOLFSSL_ASYNC_CRYPT
16565     /* Handle async operation */
16566     if (ret == WC_PENDING_E) {
16567         /* Mark message as not recevied so it can process again */
16568         ssl->msgsReceived.got_server_key_exchange = 0;
16569 
16570         return ret;
16571     }
16572 #endif /* WOLFSSL_ASYNC_CRYPT */
16573 
16574     /* Final cleanup */
16575     FreeDskeArgs(ssl, args);
16576     FreeKeyExchange(ssl);
16577 
16578     return ret;
16579 }
16580 
16581 
16582 #ifdef HAVE_QSH
16583 
16584 #ifdef HAVE_NTRU
16585 /* Encrypt a byte array using ntru
16586    key    a struct containing the public key to use
16587    bufIn  array to be encrypted
16588    inSz   size of bufIn array
16589    bufOut cipher text out
16590    outSz  will be set to the new size of cipher text
16591  */
16592 static int NtruSecretEncrypt(QSHKey* key, byte* bufIn, word32 inSz,
16593         byte* bufOut, word16* outSz)
16594 {
16595     int    ret;
16596     DRBG_HANDLE drbg;
16597 
16598     /* sanity checks on input arguments */
16599     if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
16600         return BAD_FUNC_ARG;
16601 
16602     if (key->pub.buffer == NULL)
16603         return BAD_FUNC_ARG;
16604 
16605     switch (key->name) {
16606         case WOLFSSL_NTRU_EESS439:
16607         case WOLFSSL_NTRU_EESS593:
16608         case WOLFSSL_NTRU_EESS743:
16609             break;
16610         default:
16611             WOLFSSL_MSG("Unknown QSH encryption key!");
16612             return -1;
16613     }
16614 
16615     /* set up ntru drbg */
16616     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
16617     if (ret != DRBG_OK)
16618         return NTRU_DRBG_ERROR;
16619 
16620     /* encrypt the byte array */
16621     ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length, key->pub.buffer,
16622         inSz, bufIn, outSz, bufOut);
16623     ntru_crypto_drbg_uninstantiate(drbg);
16624     if (ret != NTRU_OK)
16625         return NTRU_ENCRYPT_ERROR;
16626 
16627     return ret;
16628 }
16629 
16630 /* Decrypt a byte array using ntru
16631    key    a struct containing the private key to use
16632    bufIn  array to be decrypted
16633    inSz   size of bufIn array
16634    bufOut plain text out
16635    outSz  will be set to the new size of plain text
16636  */
16637 
16638 static int NtruSecretDecrypt(QSHKey* key, byte* bufIn, word32 inSz,
16639         byte* bufOut, word16* outSz)
16640 {
16641     int    ret;
16642     DRBG_HANDLE drbg;
16643 
16644     /* sanity checks on input arguments */
16645     if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
16646         return BAD_FUNC_ARG;
16647 
16648     if (key->pri.buffer == NULL)
16649         return BAD_FUNC_ARG;
16650 
16651     switch (key->name) {
16652         case WOLFSSL_NTRU_EESS439:
16653         case WOLFSSL_NTRU_EESS593:
16654         case WOLFSSL_NTRU_EESS743:
16655             break;
16656         default:
16657             WOLFSSL_MSG("Unknown QSH decryption key!");
16658             return -1;
16659     }
16660 
16661 
16662     /* set up drbg */
16663     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
16664     if (ret != DRBG_OK)
16665         return NTRU_DRBG_ERROR;
16666 
16667     /* decrypt cipher text */
16668     ret = ntru_crypto_ntru_decrypt(key->pri.length, key->pri.buffer,
16669         inSz, bufIn, outSz, bufOut);
16670     ntru_crypto_drbg_uninstantiate(drbg);
16671     if (ret != NTRU_OK)
16672         return NTRU_ENCRYPT_ERROR;
16673 
16674     return ret;
16675 }
16676 #endif /* HAVE_NTRU */
16677 
16678 int QSH_Init(WOLFSSL* ssl)
16679 {
16680     /* check so not initialising twice when running DTLS */
16681     if (ssl->QSH_secret != NULL)
16682         return 0;
16683 
16684     /* malloc memory for holding generated secret information */
16685     if ((ssl->QSH_secret = (QSHSecret*)XMALLOC(sizeof(QSHSecret), ssl->heap,
16686                     DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
16687         return MEMORY_E;
16688 
16689     ssl->QSH_secret->CliSi = (buffer*)XMALLOC(sizeof(buffer), ssl->heap,
16690             DYNAMIC_TYPE_TMP_BUFFER);
16691     if (ssl->QSH_secret->CliSi == NULL)
16692         return MEMORY_E;
16693 
16694     ssl->QSH_secret->SerSi = (buffer*)XMALLOC(sizeof(buffer), ssl->heap,
16695             DYNAMIC_TYPE_TMP_BUFFER);
16696     if (ssl->QSH_secret->SerSi == NULL)
16697         return MEMORY_E;
16698 
16699     /* initialize variables */
16700     ssl->QSH_secret->list = NULL;
16701     ssl->QSH_secret->CliSi->length = 0;
16702     ssl->QSH_secret->CliSi->buffer = NULL;
16703     ssl->QSH_secret->SerSi->length = 0;
16704     ssl->QSH_secret->SerSi->buffer = NULL;
16705 
16706     return 0;
16707 }
16708 
16709 
16710 static int QSH_Encrypt(QSHKey* key, byte* in, word32 szIn,
16711                                                        byte* out, word32* szOut)
16712 {
16713     int ret = 0;
16714     word16 size = *szOut;
16715 
16716     (void)in;
16717     (void)szIn;
16718     (void)out;
16719     (void)szOut;
16720 
16721     WOLFSSL_MSG("Encrypting QSH key material");
16722 
16723     switch (key->name) {
16724     #ifdef HAVE_NTRU
16725         case WOLFSSL_NTRU_EESS439:
16726         case WOLFSSL_NTRU_EESS593:
16727         case WOLFSSL_NTRU_EESS743:
16728             ret = NtruSecretEncrypt(key, in, szIn, out, &size);
16729             break;
16730     #endif
16731         default:
16732             WOLFSSL_MSG("Unknown QSH encryption key!");
16733             return -1;
16734     }
16735 
16736     *szOut = size;
16737 
16738     return ret;
16739 }
16740 
16741 
16742 /* Decrypt using Quantum Safe Handshake algorithms */
16743 int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn, byte* out, word16* szOut)
16744 {
16745     int ret = 0;
16746     word16 size = *szOut;
16747 
16748     (void)in;
16749     (void)szIn;
16750     (void)out;
16751     (void)szOut;
16752 
16753     WOLFSSL_MSG("Decrypting QSH key material");
16754 
16755     switch (key->name) {
16756     #ifdef HAVE_NTRU
16757         case WOLFSSL_NTRU_EESS439:
16758         case WOLFSSL_NTRU_EESS593:
16759         case WOLFSSL_NTRU_EESS743:
16760             ret = NtruSecretDecrypt(key, in, szIn, out, &size);
16761             break;
16762     #endif
16763         default:
16764             WOLFSSL_MSG("Unknown QSH decryption key!");
16765             return -1;
16766     }
16767 
16768     *szOut = size;
16769 
16770     return ret;
16771 }
16772 
16773 
16774 /* Get the max cipher text for corresponding encryption scheme
16775    (encrypting  48 or max plain text whichever is smaller)
16776  */
16777 static word32 QSH_MaxSecret(QSHKey* key)
16778 {
16779     int ret = 0;
16780 #ifdef HAVE_NTRU
16781     byte isNtru = 0;
16782     word16 inSz = 48;
16783     word16 outSz;
16784     DRBG_HANDLE drbg = 0;
16785     byte bufIn[48];
16786 #endif
16787 
16788     if (key == NULL || key->pub.length == 0)
16789         return 0;
16790 
16791     switch(key->name) {
16792 #ifdef HAVE_NTRU
16793             case WOLFSSL_NTRU_EESS439:
16794                 isNtru   = 1;
16795                 break;
16796             case WOLFSSL_NTRU_EESS593:
16797                 isNtru   = 1;
16798                 break;
16799             case WOLFSSL_NTRU_EESS743:
16800                 isNtru   = 1;
16801                 break;
16802 #endif
16803         default:
16804             WOLFSSL_MSG("Unknown QSH encryption scheme size!");
16805             return 0;
16806     }
16807 
16808 #ifdef HAVE_NTRU
16809     if (isNtru) {
16810         ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
16811         if (ret != DRBG_OK)
16812             return NTRU_DRBG_ERROR;
16813         ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length,
16814                             key->pub.buffer, inSz, bufIn, &outSz, NULL);
16815         if (ret != NTRU_OK) {
16816             return NTRU_ENCRYPT_ERROR;
16817         }
16818         ntru_crypto_drbg_uninstantiate(drbg);
16819         ret = outSz;
16820     }
16821 #endif
16822 
16823     return ret;
16824 }
16825 
16826 /* Generate the secret byte material for pms
16827    returns length on success and -1 on fail
16828  */
16829 static int QSH_GenerateSerCliSecret(WOLFSSL* ssl, byte isServer)
16830 {
16831     int sz       = 0;
16832     int plainSz  = 48; /* lesser of 48 and max plain text able to encrypt */
16833     int offset   = 0;
16834     word32 tmpSz = 0;
16835     buffer* buf;
16836     QSHKey* current = ssl->peerQSHKey;
16837     QSHScheme* schmPre = NULL;
16838     QSHScheme* schm    = NULL;
16839 
16840     if (ssl == NULL)
16841         return -1;
16842 
16843     WOLFSSL_MSG("Generating QSH secret key material");
16844 
16845     /* get size of buffer needed */
16846     while (current) {
16847         if (current->pub.length != 0) {
16848             sz += plainSz;
16849         }
16850         current = (QSHKey*)current->next;
16851     }
16852 
16853     /* allocate memory for buffer */
16854     if (isServer) {
16855         buf = ssl->QSH_secret->SerSi;
16856     }
16857     else {
16858         buf = ssl->QSH_secret->CliSi;
16859     }
16860     buf->length = sz;
16861     buf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16862     if (buf->buffer == NULL) {
16863         WOLFSSL_ERROR(MEMORY_E);
16864     }
16865 
16866     /* create secret information */
16867     sz = 0;
16868     current = ssl->peerQSHKey;
16869     while (current) {
16870         schm = (QSHScheme*)XMALLOC(sizeof(QSHScheme), ssl->heap,
16871                                                        DYNAMIC_TYPE_TMP_BUFFER);
16872         if (schm == NULL)
16873             return MEMORY_E;
16874 
16875         /* initialize variables */
16876         schm->name  = 0;
16877         schm->PK    = NULL;
16878         schm->PKLen = 0;
16879         schm->next  = NULL;
16880         if (ssl->QSH_secret->list == NULL) {
16881             ssl->QSH_secret->list = schm;
16882         }
16883         else {
16884             if (schmPre)
16885                 schmPre->next = schm;
16886         }
16887 
16888         tmpSz = QSH_MaxSecret(current);
16889 
16890         if ((schm->PK = (byte*)XMALLOC(tmpSz, ssl->heap,
16891                                               DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
16892             return -1;
16893 
16894         /* store info for writing extension */
16895         schm->name = current->name;
16896 
16897         /* no key to use for encryption */
16898         if (tmpSz == 0) {
16899             current = (QSHKey*)current->next;
16900             continue;
16901         }
16902 
16903         if (wc_RNG_GenerateBlock(ssl->rng, buf->buffer + offset, plainSz)
16904                                                                          != 0) {
16905             return -1;
16906         }
16907         if (QSH_Encrypt(current, buf->buffer + offset, plainSz, schm->PK,
16908                                                                  &tmpSz) != 0) {
16909             return -1;
16910         }
16911         schm->PKLen = tmpSz;
16912 
16913         sz += tmpSz;
16914         offset += plainSz;
16915         schmPre = schm;
16916         current = (QSHKey*)current->next;
16917     }
16918 
16919     return sz;
16920 }
16921 
16922 
16923 static word32 QSH_KeyGetSize(WOLFSSL* ssl)
16924 {
16925     word32 sz = 0;
16926     QSHKey* current = ssl->peerQSHKey;
16927 
16928     if (ssl == NULL)
16929         return -1;
16930 
16931     sz += OPAQUE16_LEN; /* type of extension ie 0x00 0x18 */
16932     sz += OPAQUE24_LEN;
16933     /* get size of buffer needed */
16934     while (current) {
16935         sz += OPAQUE16_LEN; /* scheme id */
16936         sz += OPAQUE16_LEN; /* encrypted key len*/
16937         sz += QSH_MaxSecret(current);
16938         current = (QSHKey*)current->next;
16939     }
16940 
16941     return sz;
16942 }
16943 
16944 
16945 /* handle QSH key Exchange
16946    return 0 on success
16947  */
16948 static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
16949 {
16950     int ret = 0;
16951 
16952     WOLFSSL_ENTER("QSH KeyExchange");
16953 
16954     ret = QSH_GenerateSerCliSecret(ssl, isServer);
16955     if (ret < 0)
16956         return MEMORY_E;
16957 
16958     return 0;
16959 }
16960 
16961 #endif /* HAVE_QSH */
16962 
16963 
16964 typedef struct SckeArgs {
16965     byte*  output; /* not allocated */
16966     byte*  encSecret;
16967     byte*  input;
16968     word32 encSz;
16969     word32 length;
16970     int    sendSz;
16971     int    inputSz;
16972 } SckeArgs;
16973 
16974 static void FreeSckeArgs(WOLFSSL* ssl, void* pArgs)
16975 {
16976     SckeArgs* args = (SckeArgs*)pArgs;
16977 
16978     (void)ssl;
16979 
16980     if (args->encSecret) {
16981         XFREE(args->encSecret, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16982         args->encSecret = NULL;
16983     }
16984     if (args->input) {
16985         XFREE(args->input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16986         args->input = NULL;
16987     }
16988 }
16989 
16990 int SendClientKeyExchange(WOLFSSL* ssl)
16991 {
16992     int ret = 0;
16993 #ifdef WOLFSSL_ASYNC_CRYPT
16994     SckeArgs* args = (SckeArgs*)ssl->async.args;
16995     typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
16996     (void)sizeof(args_test);
16997 #else
16998     SckeArgs  args[1];
16999 #endif
17000 
17001     WOLFSSL_ENTER("SendClientKeyExchange");
17002 
17003 #ifdef WOLFSSL_ASYNC_CRYPT
17004     ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
17005     if (ret != WC_NOT_PENDING_E) {
17006         /* Check for error */
17007         if (ret < 0)
17008             goto exit_scke;
17009     }
17010     else
17011 #endif
17012     {
17013         /* Reset state */
17014         ret = 0;
17015         ssl->options.asyncState = TLS_ASYNC_BEGIN;
17016         XMEMSET(args, 0, sizeof(SckeArgs));
17017     #ifdef WOLFSSL_ASYNC_CRYPT
17018         ssl->async.freeArgs = FreeSckeArgs;
17019     #endif
17020     }
17021 
17022     switch(ssl->options.asyncState)
17023     {
17024         case TLS_ASYNC_BEGIN:
17025         {
17026             switch (ssl->specs.kea) {
17027             #ifndef NO_RSA
17028                 case rsa_kea:
17029                     if (ssl->peerRsaKey == NULL ||
17030                         ssl->peerRsaKeyPresent == 0) {
17031                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17032                     }
17033                     break;
17034             #endif
17035             #ifndef NO_DH
17036                 case diffie_hellman_kea:
17037                     if (ssl->buffers.serverDH_P.buffer == NULL ||
17038                         ssl->buffers.serverDH_G.buffer == NULL ||
17039                         ssl->buffers.serverDH_Pub.buffer == NULL) {
17040                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17041                     }
17042                     break;
17043             #endif /* NO_DH */
17044             #ifndef NO_PSK
17045                 case psk_kea:
17046                     /* sanity check that PSK client callback has been set */
17047                     if (ssl->options.client_psk_cb == NULL) {
17048                         WOLFSSL_MSG("No client PSK callback set");
17049                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17050                     }
17051                     break;
17052             #endif /* NO_PSK */
17053             #if !defined(NO_DH) && !defined(NO_PSK)
17054                 case dhe_psk_kea:
17055                     if (ssl->buffers.serverDH_P.buffer == NULL ||
17056                         ssl->buffers.serverDH_G.buffer == NULL ||
17057                         ssl->buffers.serverDH_Pub.buffer == NULL) {
17058                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17059                     }
17060 
17061                     /* sanity check that PSK client callback has been set */
17062                     if (ssl->options.client_psk_cb == NULL) {
17063                         WOLFSSL_MSG("No client PSK callback set");
17064                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17065                     }
17066                     break;
17067             #endif /* !NO_DH && !NO_PSK */
17068             #if defined(HAVE_ECC) && !defined(NO_PSK)
17069                 case ecdhe_psk_kea:
17070                     /* sanity check that PSK client callback has been set */
17071                     if (ssl->options.client_psk_cb == NULL) {
17072                         WOLFSSL_MSG("No client PSK callback set");
17073                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17074                     }
17075 
17076                     /* Check client ECC public key */
17077                     if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
17078                                             !ssl->peerEccKey->dp) {
17079                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17080                     }
17081 
17082                 #ifdef HAVE_PK_CALLBACKS
17083                     /* if callback then use it for shared secret */
17084                     if (ssl->ctx->EccSharedSecretCb != NULL) {
17085                         break;
17086                     }
17087                 #endif
17088 
17089                     /* create private key */
17090                     ssl->hsType = DYNAMIC_TYPE_ECC;
17091                     ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
17092                     if (ret != 0) {
17093                         goto exit_scke;
17094                     }
17095 
17096                     ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, ssl->peerEccKey);
17097 
17098                     break;
17099             #endif /* HAVE_ECC && !NO_PSK */
17100             #ifdef HAVE_NTRU
17101                 case ntru_kea:
17102                     if (ssl->peerNtruKeyPresent == 0) {
17103                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17104                     }
17105                     break;
17106             #endif /* HAVE_NTRU */
17107             #ifdef HAVE_ECC
17108                 case ecc_diffie_hellman_kea:
17109                 {
17110                     ecc_key* peerKey;
17111 
17112                 #ifdef HAVE_PK_CALLBACKS
17113                     /* if callback then use it for shared secret */
17114                     if (ssl->ctx->EccSharedSecretCb != NULL) {
17115                         break;
17116                     }
17117                 #endif
17118 
17119                     if (ssl->specs.static_ecdh) {
17120                         /* TODO: EccDsa is really fixed Ecc change naming */
17121                         if (!ssl->peerEccDsaKey ||
17122                                 !ssl->peerEccDsaKeyPresent ||
17123                                     !ssl->peerEccDsaKey->dp) {
17124                             ERROR_OUT(NO_PEER_KEY, exit_scke);
17125                         }
17126                         peerKey = ssl->peerEccDsaKey;
17127                     }
17128                     else {
17129                         if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
17130                                                 !ssl->peerEccKey->dp) {
17131                             ERROR_OUT(NO_PEER_KEY, exit_scke);
17132                         }
17133                         peerKey = ssl->peerEccKey;
17134                     }
17135                     if (peerKey == NULL) {
17136                         ERROR_OUT(NO_PEER_KEY, exit_scke);
17137                     }
17138 
17139                     /* create private key */
17140                     ssl->hsType = DYNAMIC_TYPE_ECC;
17141                     ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
17142                     if (ret != 0) {
17143                         goto exit_scke;
17144                     }
17145 
17146                     ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, peerKey);
17147 
17148                     break;
17149                 }
17150             #endif /* HAVE_ECC */
17151 
17152                 default:
17153                     ret = BAD_KEA_TYPE_E;
17154             } /* switch(ssl->specs.kea) */
17155 
17156             /* Check for error */
17157             if (ret != 0) {
17158                 goto exit_scke;
17159             }
17160 
17161             /* Advance state and proceed */
17162             ssl->options.asyncState = TLS_ASYNC_BUILD;
17163         } /* case TLS_ASYNC_BEGIN */
17164 
17165         case TLS_ASYNC_BUILD:
17166         {
17167             args->encSz = MAX_ENCRYPT_SZ;
17168             args->encSecret = (byte*)XMALLOC(args->encSz, ssl->heap,
17169                                                     DYNAMIC_TYPE_TMP_BUFFER);
17170             if (args->encSecret == NULL) {
17171                 ERROR_OUT(MEMORY_E, exit_scke);
17172             }
17173 
17174             switch(ssl->specs.kea)
17175             {
17176             #ifndef NO_RSA
17177                 case rsa_kea:
17178                 {
17179                     ret = wc_RNG_GenerateBlock(ssl->rng,
17180                         ssl->arrays->preMasterSecret, SECRET_LEN);
17181                     if (ret != 0) {
17182                         goto exit_scke;
17183                     }
17184 
17185                     ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
17186                     ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
17187                     ssl->arrays->preMasterSz = SECRET_LEN;
17188                     break;
17189                 }
17190             #endif /* !NO_RSA */
17191             #ifndef NO_DH
17192                 case diffie_hellman_kea:
17193                 {
17194                     ssl->buffers.sig.length = ENCRYPT_LEN;
17195                     ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN,
17196                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
17197                     if (ssl->buffers.sig.buffer == NULL) {
17198                         ERROR_OUT(MEMORY_E, exit_scke);
17199                     }
17200 
17201                     ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
17202                                             (void**)&ssl->buffers.serverDH_Key);
17203                     if (ret != 0) {
17204                         goto exit_scke;
17205                     }
17206 
17207                     ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
17208                         ssl->buffers.serverDH_P.buffer,
17209                         ssl->buffers.serverDH_P.length,
17210                         ssl->buffers.serverDH_G.buffer,
17211                         ssl->buffers.serverDH_G.length);
17212                     if (ret != 0) {
17213                         goto exit_scke;
17214                     }
17215 
17216                     /* for DH, encSecret is Yc, agree is pre-master */
17217                     ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
17218                         ssl->buffers.sig.buffer, &ssl->buffers.sig.length,
17219                         args->encSecret, &args->encSz);
17220                     break;
17221                 }
17222             #endif /* !NO_DH */
17223             #ifndef NO_PSK
17224                 case psk_kea:
17225                 {
17226                     byte* pms = ssl->arrays->preMasterSecret;
17227                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
17228                         ssl->arrays->server_hint, ssl->arrays->client_identity,
17229                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
17230                     if (ssl->arrays->psk_keySz == 0 ||
17231                         ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17232                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17233                     }
17234                     ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
17235                     args->encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
17236                     if (args->encSz > MAX_PSK_ID_LEN) {
17237                         ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
17238                     }
17239                     XMEMCPY(args->encSecret, ssl->arrays->client_identity,
17240                                                                 args->encSz);
17241 
17242                     /* make psk pre master secret */
17243                     /* length of key + length 0s + length of key + key */
17244                     c16toa((word16)ssl->arrays->psk_keySz, pms);
17245                     pms += OPAQUE16_LEN;
17246                     XMEMSET(pms, 0, ssl->arrays->psk_keySz);
17247                     pms += ssl->arrays->psk_keySz;
17248                     c16toa((word16)ssl->arrays->psk_keySz, pms);
17249                     pms += OPAQUE16_LEN;
17250                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17251                     ssl->arrays->preMasterSz = (ssl->arrays->psk_keySz * 2) +
17252                         (2 * OPAQUE16_LEN);
17253                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17254                     ssl->arrays->psk_keySz = 0; /* No further need */
17255                     break;
17256                 }
17257             #endif /* !NO_PSK */
17258             #if !defined(NO_DH) && !defined(NO_PSK)
17259                 case dhe_psk_kea:
17260                 {
17261                     word32 esSz = 0;
17262                     args->output = args->encSecret;
17263 
17264                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
17265                          ssl->arrays->server_hint, ssl->arrays->client_identity,
17266                          MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
17267                     if (ssl->arrays->psk_keySz == 0 ||
17268                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17269                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17270                     }
17271                     ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
17272                     esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
17273 
17274                     if (esSz > MAX_PSK_ID_LEN) {
17275                         ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
17276                     }
17277 
17278                     ssl->buffers.sig.length = ENCRYPT_LEN;
17279                     ssl->buffers.sig.buffer = (byte*)XMALLOC(ENCRYPT_LEN,
17280                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
17281                     if (ssl->buffers.sig.buffer == NULL) {
17282                         ERROR_OUT(MEMORY_E, exit_scke);
17283                     }
17284 
17285                     c16toa((word16)esSz, args->output);
17286                     args->output += OPAQUE16_LEN;
17287                     XMEMCPY(args->output, ssl->arrays->client_identity, esSz);
17288                     args->output += esSz;
17289                     args->encSz = esSz + OPAQUE16_LEN;
17290 
17291                     args->length = 0;
17292 
17293                     ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
17294                                             (void**)&ssl->buffers.serverDH_Key);
17295                     if (ret != 0) {
17296                         goto exit_scke;
17297                     }
17298 
17299                     ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
17300                         ssl->buffers.serverDH_P.buffer,
17301                         ssl->buffers.serverDH_P.length,
17302                         ssl->buffers.serverDH_G.buffer,
17303                         ssl->buffers.serverDH_G.length);
17304                     if (ret != 0) {
17305                         goto exit_scke;
17306                     }
17307 
17308                     /* for DH, encSecret is Yc, agree is pre-master */
17309                     ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
17310                         ssl->buffers.sig.buffer, &ssl->buffers.sig.length,
17311                         args->output + OPAQUE16_LEN, &args->length);
17312                     break;
17313                 }
17314             #endif /* !NO_DH && !NO_PSK */
17315             #if defined(HAVE_ECC) && !defined(NO_PSK)
17316                 case ecdhe_psk_kea:
17317                 {
17318                     word32 esSz = 0;
17319                     args->output = args->encSecret;
17320 
17321                     /* Send PSK client identity */
17322                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
17323                          ssl->arrays->server_hint, ssl->arrays->client_identity,
17324                          MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
17325                     if (ssl->arrays->psk_keySz == 0 ||
17326                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17327                         ERROR_OUT(PSK_KEY_ERROR, exit_scke);
17328                     }
17329                     ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; /* null term */
17330                     esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
17331                     if (esSz > MAX_PSK_ID_LEN) {
17332                         ERROR_OUT(CLIENT_ID_ERROR, exit_scke);
17333                     }
17334 
17335                     /* place size and identity in output buffer sz:identity */
17336                     c16toa((word16)esSz, args->output);
17337                     args->output += OPAQUE16_LEN;
17338                     XMEMCPY(args->output, ssl->arrays->client_identity, esSz);
17339                     args->output += esSz;
17340                     args->encSz = esSz + OPAQUE16_LEN;
17341 
17342                     /* length is used for public key size */
17343                     args->length = MAX_ENCRYPT_SZ;
17344 
17345                     /* Create shared ECC key leaving room at the begining
17346                        of buffer for size of shared key. */
17347                     ssl->arrays->preMasterSz = ENCRYPT_LEN - OPAQUE16_LEN;
17348 
17349                 #ifdef HAVE_PK_CALLBACKS
17350                     /* if callback then use it for shared secret */
17351                     if (ssl->ctx->EccSharedSecretCb != NULL) {
17352                         break;
17353                     }
17354                 #endif
17355 
17356                     /* Place ECC key in output buffer, leaving room for size */
17357                     ret = wc_ecc_export_x963((ecc_key*)ssl->hsKey,
17358                                     args->output + OPAQUE8_LEN, &args->length);
17359                     if (ret != 0) {
17360                         ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
17361                     }
17362 
17363                     break;
17364                 }
17365             #endif /* HAVE_ECC && !NO_PSK */
17366             #ifdef HAVE_NTRU
17367                 case ntru_kea:
17368                 {
17369                     ret = wc_RNG_GenerateBlock(ssl->rng,
17370                                   ssl->arrays->preMasterSecret, SECRET_LEN);
17371                     if (ret != 0) {
17372                         goto exit_scke;
17373                     }
17374 
17375                     ssl->arrays->preMasterSz = SECRET_LEN;
17376                     args->encSz = MAX_ENCRYPT_SZ;
17377                     break;
17378                 }
17379             #endif /* HAVE_NTRU */
17380             #ifdef HAVE_ECC
17381                 case ecc_diffie_hellman_kea:
17382                 {
17383                     ssl->arrays->preMasterSz = ENCRYPT_LEN;
17384 
17385                  #ifdef HAVE_PK_CALLBACKS
17386                     /* if callback then use it for shared secret */
17387                     if (ssl->ctx->EccSharedSecretCb != NULL) {
17388                         break;
17389                     }
17390                 #endif
17391 
17392                     /* Place ECC key in buffer, leaving room for size */
17393                     ret = wc_ecc_export_x963((ecc_key*)ssl->hsKey,
17394                                 args->encSecret + OPAQUE8_LEN, &args->encSz);
17395                     if (ret != 0) {
17396                         ERROR_OUT(ECC_EXPORT_ERROR, exit_scke);
17397                     }
17398                     break;
17399                 }
17400             #endif /* HAVE_ECC */
17401 
17402                 default:
17403                     ret = BAD_KEA_TYPE_E;
17404             } /* switch(ssl->specs.kea) */
17405 
17406             /* Check for error */
17407             if (ret != 0) {
17408                 goto exit_scke;
17409             }
17410 
17411             /* Advance state and proceed */
17412             ssl->options.asyncState = TLS_ASYNC_DO;
17413         } /* case TLS_ASYNC_BUILD */
17414 
17415         case TLS_ASYNC_DO:
17416         {
17417             switch(ssl->specs.kea)
17418             {
17419             #ifndef NO_RSA
17420                 case rsa_kea:
17421                 {
17422                     ret = RsaEnc(ssl,
17423                         ssl->arrays->preMasterSecret, SECRET_LEN,
17424                         args->encSecret, &args->encSz,
17425                         ssl->peerRsaKey,
17426                     #if defined(HAVE_PK_CALLBACKS)
17427                         ssl->buffers.peerRsaKey.buffer,
17428                         ssl->buffers.peerRsaKey.length,
17429                         ssl->RsaEncCtx
17430                     #else
17431                         NULL, 0, NULL
17432                     #endif
17433                     );
17434 
17435                     break;
17436                 }
17437             #endif /* !NO_RSA */
17438             #ifndef NO_DH
17439                 case diffie_hellman_kea:
17440                 {
17441                     ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
17442                         ssl->buffers.sig.buffer, ssl->buffers.sig.length,
17443                         ssl->buffers.serverDH_Pub.buffer,
17444                         ssl->buffers.serverDH_Pub.length,
17445                         ssl->arrays->preMasterSecret,
17446                         &ssl->arrays->preMasterSz);
17447                     break;
17448                 }
17449             #endif /* !NO_DH */
17450             #ifndef NO_PSK
17451                 case psk_kea:
17452                 {
17453                     break;
17454                 }
17455             #endif /* !NO_PSK */
17456             #if !defined(NO_DH) && !defined(NO_PSK)
17457                 case dhe_psk_kea:
17458                 {
17459                     ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
17460                         ssl->buffers.sig.buffer, ssl->buffers.sig.length,
17461                         ssl->buffers.serverDH_Pub.buffer,
17462                         ssl->buffers.serverDH_Pub.length,
17463                         ssl->arrays->preMasterSecret + OPAQUE16_LEN,
17464                         &ssl->arrays->preMasterSz);
17465                     break;
17466                 }
17467             #endif /* !NO_DH && !NO_PSK */
17468             #if defined(HAVE_ECC) && !defined(NO_PSK)
17469                 case ecdhe_psk_kea:
17470                 {
17471                     ecc_key* key = (ecc_key*)ssl->hsKey;
17472                     ret = EccSharedSecret(ssl, key, ssl->peerEccKey,
17473                         args->output + OPAQUE8_LEN, &args->length,
17474                         ssl->arrays->preMasterSecret + OPAQUE16_LEN,
17475                         &ssl->arrays->preMasterSz,
17476                         WOLFSSL_CLIENT_END,
17477                     #ifdef HAVE_PK_CALLBACKS
17478                         ssl->EccSharedSecretCtx
17479                     #else
17480                         NULL
17481                     #endif
17482                     );
17483                     break;
17484                 }
17485             #endif /* HAVE_ECC && !NO_PSK */
17486             #ifdef HAVE_NTRU
17487                 case ntru_kea:
17488                 {
17489                     word32 rc;
17490                     DRBG_HANDLE drbg;
17491 
17492                     rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
17493                     if (rc != DRBG_OK) {
17494                         ERROR_OUT(NTRU_DRBG_ERROR, exit_scke);
17495                     }
17496                     rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
17497                                                   ssl->peerNtruKey,
17498                                                   ssl->arrays->preMasterSz,
17499                                                   ssl->arrays->preMasterSecret,
17500                                                   (word16*)&args->encSz,
17501                                                   args->encSecret);
17502                     ntru_crypto_drbg_uninstantiate(drbg);
17503                     if (rc != NTRU_OK) {
17504                         ERROR_OUT(NTRU_ENCRYPT_ERROR, exit_scke);
17505                     }
17506                     ret = 0;
17507                     break;
17508                 }
17509             #endif /* HAVE_NTRU */
17510             #ifdef HAVE_ECC
17511                 case ecc_diffie_hellman_kea:
17512                 {
17513                     ecc_key* key = (ecc_key*)ssl->hsKey;
17514                     ecc_key* peerKey = (ssl->specs.static_ecdh) ?
17515                                 ssl->peerEccDsaKey : ssl->peerEccKey;
17516 
17517                     ret = EccSharedSecret(ssl,
17518                         key, peerKey,
17519                         args->encSecret + OPAQUE8_LEN, &args->encSz,
17520                         ssl->arrays->preMasterSecret,
17521                         &ssl->arrays->preMasterSz,
17522                         WOLFSSL_CLIENT_END,
17523                     #ifdef HAVE_PK_CALLBACKS
17524                         ssl->EccSharedSecretCtx
17525                     #else
17526                         NULL
17527                     #endif
17528                     );
17529 
17530                     break;
17531                 }
17532             #endif /* HAVE_ECC */
17533 
17534                 default:
17535                     ret = BAD_KEA_TYPE_E;
17536             } /* switch(ssl->specs.kea) */
17537 
17538             /* Check for error */
17539             if (ret != 0) {
17540                 goto exit_scke;
17541             }
17542 
17543             /* Advance state and proceed */
17544             ssl->options.asyncState = TLS_ASYNC_VERIFY;
17545         } /* case TLS_ASYNC_DO */
17546 
17547         case TLS_ASYNC_VERIFY:
17548         {
17549             switch(ssl->specs.kea)
17550             {
17551             #ifndef NO_RSA
17552                 case rsa_kea:
17553                 {
17554                     break;
17555                 }
17556             #endif /* !NO_RSA */
17557             #ifndef NO_DH
17558                 case diffie_hellman_kea:
17559                 {
17560                     break;
17561                 }
17562             #endif /* !NO_DH */
17563             #ifndef NO_PSK
17564                 case psk_kea:
17565                 {
17566                     break;
17567                 }
17568             #endif /* !NO_PSK */
17569             #if !defined(NO_DH) && !defined(NO_PSK)
17570                 case dhe_psk_kea:
17571                 {
17572                     byte* pms = ssl->arrays->preMasterSecret;
17573 
17574                     /* validate args */
17575                     if (args->output == NULL || args->length == 0) {
17576                         ERROR_OUT(BAD_FUNC_ARG, exit_scke);
17577                     }
17578 
17579                     c16toa((word16)args->length, args->output);
17580                     args->encSz += args->length + OPAQUE16_LEN;
17581                     c16toa((word16)ssl->arrays->preMasterSz, pms);
17582                     ssl->arrays->preMasterSz += OPAQUE16_LEN;
17583                     pms += ssl->arrays->preMasterSz;
17584 
17585                     /* make psk pre master secret */
17586                     /* length of key + length 0s + length of key + key */
17587                     c16toa((word16)ssl->arrays->psk_keySz, pms);
17588                     pms += OPAQUE16_LEN;
17589                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17590                     ssl->arrays->preMasterSz +=
17591                                          ssl->arrays->psk_keySz + OPAQUE16_LEN;
17592                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17593                     ssl->arrays->psk_keySz = 0; /* No further need */
17594                     break;
17595                 }
17596             #endif /* !NO_DH && !NO_PSK */
17597             #if defined(HAVE_ECC) && !defined(NO_PSK)
17598                 case ecdhe_psk_kea:
17599                 {
17600                     byte* pms = ssl->arrays->preMasterSecret;
17601 
17602                     /* validate args */
17603                     if (args->output == NULL || args->length > ENCRYPT_LEN) {
17604                         ERROR_OUT(BAD_FUNC_ARG, exit_scke);
17605                     }
17606 
17607                     /* place size of public key in output buffer */
17608                     *args->output = (byte)args->length;
17609                     args->encSz += args->length + OPAQUE8_LEN;
17610 
17611                     /* Create pre master secret is the concatination of
17612                        eccSize + eccSharedKey + pskSize + pskKey */
17613                     c16toa((word16)ssl->arrays->preMasterSz, pms);
17614                     ssl->arrays->preMasterSz += OPAQUE16_LEN;
17615                     pms += ssl->arrays->preMasterSz;
17616 
17617                     c16toa((word16)ssl->arrays->psk_keySz, pms);
17618                     pms += OPAQUE16_LEN;
17619                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17620                     ssl->arrays->preMasterSz +=
17621                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
17622 
17623                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17624                     ssl->arrays->psk_keySz = 0; /* No further need */
17625                     break;
17626                 }
17627             #endif /* HAVE_ECC && !NO_PSK */
17628             #ifdef HAVE_NTRU
17629                 case ntru_kea:
17630                 {
17631                     break;
17632                 }
17633             #endif /* HAVE_NTRU */
17634             #ifdef HAVE_ECC
17635                 case ecc_diffie_hellman_kea:
17636                 {
17637                     /* place size of public key in buffer */
17638                     *args->encSecret = (byte)args->encSz;
17639                     args->encSz += OPAQUE8_LEN;
17640                     break;
17641                 }
17642             #endif /* HAVE_ECC */
17643 
17644                 default:
17645                     ret = BAD_KEA_TYPE_E;
17646             } /* switch(ssl->specs.kea) */
17647 
17648             /* Check for error */
17649             if (ret != 0) {
17650                 goto exit_scke;
17651             }
17652 
17653             /* Advance state and proceed */
17654             ssl->options.asyncState = TLS_ASYNC_FINALIZE;
17655         } /* case TLS_ASYNC_VERIFY */
17656 
17657         case TLS_ASYNC_FINALIZE:
17658         {
17659             word32 tlsSz = 0;
17660             word32 idx = 0;
17661 
17662         #ifdef HAVE_QSH
17663             word32 qshSz = 0;
17664             if (ssl->peerQSHKeyPresent) {
17665                 qshSz = QSH_KeyGetSize(ssl);
17666             }
17667         #endif
17668 
17669             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea) {
17670                 tlsSz = 2;
17671             }
17672 
17673             if (ssl->specs.kea == ecc_diffie_hellman_kea ||
17674                 ssl->specs.kea == dhe_psk_kea ||
17675                 ssl->specs.kea == ecdhe_psk_kea) { /* always off */
17676                 tlsSz = 0;
17677             }
17678 
17679             idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
17680             args->sendSz = args->encSz + tlsSz + idx;
17681 
17682         #ifdef WOLFSSL_DTLS
17683             if (ssl->options.dtls) {
17684                 idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
17685                 args->sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
17686             }
17687         #endif
17688 
17689             if (IsEncryptionOn(ssl, 1)) {
17690                 args->sendSz += MAX_MSG_EXTRA;
17691             }
17692 
17693         #ifdef HAVE_QSH
17694             args->encSz += qshSz;
17695             args->sendSz += qshSz;
17696         #endif
17697 
17698             /* check for available size */
17699             if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
17700                 goto exit_scke;
17701             }
17702 
17703             /* get output buffer */
17704             args->output = ssl->buffers.outputBuffer.buffer +
17705                            ssl->buffers.outputBuffer.length;
17706 
17707         #ifdef HAVE_QSH
17708             if (ssl->peerQSHKeyPresent) {
17709                 byte idxSave = idx;
17710                 idx = args->sendSz - qshSz;
17711 
17712                 if (QSH_KeyExchangeWrite(ssl, 0) != 0) {
17713                     ERROR_OUT(MEMORY_E, exit_scke);
17714                 }
17715 
17716                 /* extension type */
17717                 c16toa(TLSX_QUANTUM_SAFE_HYBRID, args->output + idx);
17718                 idx += OPAQUE16_LEN;
17719 
17720                 /* write to output and check amount written */
17721                 if (TLSX_QSHPK_Write(ssl->QSH_secret->list,
17722                             args->output + idx) > qshSz - OPAQUE16_LEN) {
17723                     ERROR_OUT(MEMORY_E, exit_scke);
17724                 }
17725 
17726                 idx = idxSave;
17727             }
17728         #endif
17729 
17730             AddHeaders(args->output, args->encSz + tlsSz, client_key_exchange, ssl);
17731 
17732         #ifdef HAVE_QSH
17733             if (ssl->peerQSHKeyPresent) {
17734                 args->encSz -= qshSz;
17735             }
17736         #endif
17737             if (tlsSz) {
17738                 c16toa((word16)args->encSz, &args->output[idx]);
17739                 idx += OPAQUE16_LEN;
17740             }
17741             XMEMCPY(args->output + idx, args->encSecret, args->encSz);
17742             idx += args->encSz;
17743 
17744             if (IsEncryptionOn(ssl, 1)) {
17745                 args->inputSz = idx - RECORD_HEADER_SZ; /* buildmsg adds rechdr */
17746                 args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
17747                                                        DYNAMIC_TYPE_TMP_BUFFER);
17748                 if (args->input == NULL) {
17749                     ERROR_OUT(MEMORY_E, exit_scke);
17750                 }
17751 
17752                 XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
17753                                                                 args->inputSz);
17754             }
17755 
17756             /* Advance state and proceed */
17757             ssl->options.asyncState = TLS_ASYNC_END;
17758         } /* case TLS_ASYNC_FINALIZE */
17759 
17760         case TLS_ASYNC_END:
17761         {
17762             if (IsEncryptionOn(ssl, 1)) {
17763                 ret = BuildMessage(ssl, args->output, args->sendSz,
17764                             args->input, args->inputSz, handshake, 1, 0, 1);
17765             #ifdef WOLFSSL_ASYNC_CRYPT
17766                 if (ret == WC_PENDING_E)
17767                     goto exit_scke;
17768             #endif
17769                 XFREE(args->input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
17770                 args->input = NULL; /* make sure its not double free'd on cleanup */
17771 
17772                 if (ret >= 0) {
17773                     args->sendSz = ret;
17774                     ret = 0;
17775                 }
17776             }
17777             else {
17778             #ifdef WOLFSSL_DTLS
17779                 if (ssl->options.dtls)
17780                     DtlsSEQIncrement(ssl, CUR_ORDER);
17781             #endif
17782                 ret = HashOutput(ssl, args->output, args->sendSz, 0);
17783             }
17784 
17785             if (ret != 0) {
17786                 goto exit_scke;
17787             }
17788 
17789         #ifdef WOLFSSL_DTLS
17790             if (IsDtlsNotSctpMode(ssl)) {
17791                 if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz)) != 0) {
17792                     goto exit_scke;
17793                 }
17794             }
17795         #endif
17796 
17797         #ifdef WOLFSSL_CALLBACKS
17798             if (ssl->hsInfoOn)
17799                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
17800             if (ssl->toInfoOn)
17801                 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
17802                               args->output, args->sendSz, ssl->heap);
17803         #endif
17804 
17805             ssl->buffers.outputBuffer.length += args->sendSz;
17806 
17807             if (!ssl->options.groupMessages) {
17808                 ret = SendBuffered(ssl);
17809             }
17810             if (ret == 0 || ret == WANT_WRITE) {
17811                 int tmpRet = MakeMasterSecret(ssl);
17812                 if (tmpRet != 0) {
17813                     ret = tmpRet;   /* save WANT_WRITE unless more serious */
17814                 }
17815                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
17816             }
17817             break;
17818         }
17819         default:
17820             ret = INPUT_CASE_ERROR;
17821     } /* switch(ssl->options.asyncState) */
17822 
17823 exit_scke:
17824 
17825     WOLFSSL_LEAVE("SendClientKeyExchange", ret);
17826 
17827 #ifdef WOLFSSL_ASYNC_CRYPT
17828     /* Handle async operation */
17829     if (ret == WC_PENDING_E)
17830         return ret;
17831 #endif
17832 
17833     /* No further need for PMS */
17834     ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
17835     ssl->arrays->preMasterSz = 0;
17836 
17837     /* Final cleanup */
17838     FreeSckeArgs(ssl, args);
17839     FreeKeyExchange(ssl);
17840 
17841     return ret;
17842 }
17843 
17844 
17845 #ifndef NO_CERTS
17846 /* Decode the private key - RSA or ECC - and creates a key object.
17847  * The signature type is set as well.
17848  * The maximum length of a signature is returned.
17849  *
17850  * ssl     The SSL/TLS object.
17851  * length  The length of a signature.
17852  * returns 0 on success, otherwise failure.
17853  */
17854 int DecodePrivateKey(WOLFSSL *ssl, word16* length)
17855 {
17856     int      ret;
17857     int      keySz;
17858     word32   idx;
17859 
17860     /* make sure private key exists */
17861     if (ssl->buffers.key == NULL || ssl->buffers.key->buffer == NULL) {
17862         WOLFSSL_MSG("Private key missing!");
17863         ERROR_OUT(NO_PRIVATE_KEY, exit_dpk);
17864     }
17865 
17866 #ifndef NO_RSA
17867     ssl->hsType = DYNAMIC_TYPE_RSA;
17868     ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
17869     if (ret != 0) {
17870         goto exit_dpk;
17871     }
17872 
17873     WOLFSSL_MSG("Trying RSA private key");
17874 
17875     /* Set start of data to beginning of buffer. */
17876     idx = 0;
17877     /* Decode the key assuming it is an RSA private key. */
17878     ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
17879                 (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
17880     if (ret == 0) {
17881         WOLFSSL_MSG("Using RSA private key");
17882 
17883         /* It worked so check it meeets minimum key size requirements. */
17884         keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
17885         if (keySz < 0) { /* check if keySz has error case */
17886             ERROR_OUT(keySz, exit_dpk);
17887         }
17888 
17889         if (keySz < ssl->options.minRsaKeySz) {
17890             WOLFSSL_MSG("RSA key size too small");
17891             ERROR_OUT(RSA_KEY_SIZE_E, exit_dpk);
17892         }
17893 
17894         /* Return the maximum signature length. */
17895         *length = (word16)keySz;
17896 
17897         goto exit_dpk;
17898     }
17899 #endif /* !NO_RSA */
17900 
17901 #ifdef HAVE_ECC
17902 #ifndef NO_RSA
17903     FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey);
17904 #endif /* !NO_RSA */
17905 
17906     ssl->hsType = DYNAMIC_TYPE_ECC;
17907     ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
17908     if (ret != 0) {
17909         goto exit_dpk;
17910     }
17911 
17912 #ifndef NO_RSA
17913     WOLFSSL_MSG("Trying ECC private key, RSA didn't work");
17914 #else
17915     WOLFSSL_MSG("Trying ECC private key");
17916 #endif
17917 
17918     /* Set start of data to beginning of buffer. */
17919     idx = 0;
17920     /* Decode the key assuming it is an ECC private key. */
17921     ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
17922                                  (ecc_key*)ssl->hsKey,
17923                                  ssl->buffers.key->length);
17924     if (ret != 0) {
17925         WOLFSSL_MSG("Bad client cert type");
17926         goto exit_dpk;
17927     }
17928 
17929     WOLFSSL_MSG("Using ECC private key");
17930 
17931     /* Check it meets the minimum ECC key size requirements. */
17932     keySz = wc_ecc_size((ecc_key*)ssl->hsKey);
17933     if (keySz < ssl->options.minEccKeySz) {
17934         WOLFSSL_MSG("ECC key size too small");
17935         ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
17936     }
17937 
17938     /* Return the maximum signature length. */
17939     *length = wc_ecc_sig_size((ecc_key*)ssl->hsKey);
17940 #endif
17941 
17942 exit_dpk:
17943     return ret;
17944 }
17945 
17946 
17947 typedef struct ScvArgs {
17948     byte*  output; /* not allocated */
17949 #ifndef NO_RSA
17950     byte*  verifySig;
17951 #endif
17952     byte*  verify; /* not allocated */
17953     byte*  input;
17954     word32 idx;
17955     word32 extraSz;
17956     word32 sigSz;
17957     int    sendSz;
17958     int    length;
17959     int    inputSz;
17960 } ScvArgs;
17961 
17962 static void FreeScvArgs(WOLFSSL* ssl, void* pArgs)
17963 {
17964     ScvArgs* args = (ScvArgs*)pArgs;
17965 
17966     (void)ssl;
17967 
17968 #ifndef NO_RSA
17969     if (args->verifySig) {
17970         XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
17971         args->verifySig = NULL;
17972     }
17973 #endif
17974     if (args->input) {
17975         XFREE(args->input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
17976         args->input = NULL;
17977     }
17978 }
17979 
17980 int SendCertificateVerify(WOLFSSL* ssl)
17981 {
17982     int ret = 0;
17983 #ifdef WOLFSSL_ASYNC_CRYPT
17984     ScvArgs* args = (ScvArgs*)ssl->async.args;
17985     typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
17986     (void)sizeof(args_test);
17987 #else
17988     ScvArgs  args[1];
17989 #endif
17990 
17991     WOLFSSL_ENTER("SendCertificateVerify");
17992 
17993 #ifdef WOLFSSL_ASYNC_CRYPT
17994     ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
17995     if (ret != WC_NOT_PENDING_E) {
17996         /* Check for error */
17997         if (ret < 0)
17998             goto exit_scv;
17999     }
18000     else
18001 #endif
18002     {
18003         /* Reset state */
18004         ret = 0;
18005         ssl->options.asyncState = TLS_ASYNC_BEGIN;
18006         XMEMSET(args, 0, sizeof(ScvArgs));
18007     #ifdef WOLFSSL_ASYNC_CRYPT
18008         ssl->async.freeArgs = FreeScvArgs;
18009     #endif
18010     }
18011 
18012     switch(ssl->options.asyncState)
18013     {
18014         case TLS_ASYNC_BEGIN:
18015         {
18016             if (ssl->options.sendVerify == SEND_BLANK_CERT) {
18017                 return 0;  /* sent blank cert, can't verify */
18018             }
18019 
18020             args->sendSz = MAX_CERT_VERIFY_SZ;
18021             if (IsEncryptionOn(ssl, 1)) {
18022                 args->sendSz += MAX_MSG_EXTRA;
18023             }
18024 
18025             /* check for available size */
18026             if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
18027                 goto exit_scv;
18028             }
18029 
18030             /* get output buffer */
18031             args->output = ssl->buffers.outputBuffer.buffer +
18032                            ssl->buffers.outputBuffer.length;
18033 
18034             /* Advance state and proceed */
18035             ssl->options.asyncState = TLS_ASYNC_BUILD;
18036         } /* case TLS_ASYNC_BEGIN */
18037 
18038         case TLS_ASYNC_BUILD:
18039         {
18040             int    typeH;
18041 
18042             ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
18043             if (ret != 0) {
18044                 goto exit_scv;
18045             }
18046 
18047             /* Decode private key. */
18048             ret = DecodePrivateKey(ssl, (word16*)&args->length);
18049             if (ret != 0) {
18050                 goto exit_scv;
18051             }
18052 
18053             /* idx is used to track verify pointer offset to output */
18054             args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
18055             args->verify = &args->output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ];
18056             args->extraSz = 0;  /* tls 1.2 hash/sig */
18057 
18058             /* build encoded signature buffer */
18059             ssl->buffers.sig.length = MAX_ENCODED_SIG_SZ;
18060             ssl->buffers.sig.buffer = (byte*)XMALLOC(ssl->buffers.sig.length,
18061                                         ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
18062             if (ssl->buffers.sig.buffer == NULL) {
18063                 ERROR_OUT(MEMORY_E, exit_scv);
18064             }
18065 
18066         #ifdef WOLFSSL_DTLS
18067             if (ssl->options.dtls) {
18068                 args->idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
18069                 args->verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
18070             }
18071         #endif
18072 
18073     #ifndef NO_OLD_TLS
18074         #ifndef NO_SHA
18075             /* old tls default */
18076             ssl->buffers.digest.length = SHA_DIGEST_SIZE;
18077             ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha;
18078             typeH = SHAh;
18079         #endif
18080     #else
18081         #ifndef NO_SHA256
18082             /* new tls default */
18083             ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
18084             ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
18085             typeH = SHA256h;
18086         #endif
18087     #endif /* !NO_OLD_TLS */
18088 
18089             if (IsAtLeastTLSv1_2(ssl)) {
18090                 args->verify[0] = ssl->suites->hashAlgo;
18091                 args->verify[1] = (ssl->hsType == DYNAMIC_TYPE_ECC) ?
18092                                                 ecc_dsa_sa_algo : rsa_sa_algo;
18093                 args->extraSz = HASH_SIG_SIZE;
18094 
18095                 switch (ssl->suites->hashAlgo) {
18096                 #ifndef NO_SHA
18097                     case sha_mac:
18098                         ssl->buffers.digest.length = SHA_DIGEST_SIZE;
18099                         ssl->buffers.digest.buffer =
18100                             ssl->hsHashes->certHashes.sha;
18101                         typeH    = SHAh;
18102                         break;
18103                 #endif /* NO_SHA */
18104                 #ifndef NO_SHA256
18105                     case sha256_mac:
18106                         ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
18107                         ssl->buffers.digest.buffer =
18108                             ssl->hsHashes->certHashes.sha256;
18109                         typeH    = SHA256h;
18110                         break;
18111                 #endif /* !NO_SHA256 */
18112                 #ifdef WOLFSSL_SHA384
18113                     case sha384_mac:
18114                         ssl->buffers.digest.length = SHA384_DIGEST_SIZE;
18115                         ssl->buffers.digest.buffer =
18116                             ssl->hsHashes->certHashes.sha384;
18117                         typeH    = SHA384h;
18118                         break;
18119                 #endif /* WOLFSSL_SHA384 */
18120                 #ifdef WOLFSSL_SHA512
18121                     case sha512_mac:
18122                         ssl->buffers.digest.length = SHA512_DIGEST_SIZE;
18123                         ssl->buffers.digest.buffer =
18124                             ssl->hsHashes->certHashes.sha512;
18125                         typeH    = SHA512h;
18126                         break;
18127                 #endif /* WOLFSSL_SHA512 */
18128                 } /* switch */
18129             }
18130         #ifndef NO_OLD_TLS
18131             else {
18132                 /* if old TLS load MD5 and SHA hash as value to sign */
18133                 XMEMCPY(ssl->buffers.sig.buffer,
18134                     (byte*)ssl->hsHashes->certHashes.md5, FINISHED_SZ);
18135             }
18136         #endif
18137 
18138             if (typeH == 0) {
18139                 ERROR_OUT(ALGO_ID_E, exit_scv);
18140             }
18141 
18142         #ifndef NO_RSA
18143             if (ssl->hsType == DYNAMIC_TYPE_RSA) {
18144                 ssl->buffers.sig.length = FINISHED_SZ;
18145                 args->sigSz = ENCRYPT_LEN;
18146 
18147                 if (IsAtLeastTLSv1_2(ssl)) {
18148                     ssl->buffers.sig.length = wc_EncodeSignature(
18149                             ssl->buffers.sig.buffer, ssl->buffers.digest.buffer,
18150                             ssl->buffers.digest.length, typeH);
18151                 }
18152 
18153                 /* prepend hdr */
18154                 c16toa((word16)args->length, args->verify + args->extraSz);
18155             }
18156         #endif /* !NO_RSA */
18157 
18158             /* Advance state and proceed */
18159             ssl->options.asyncState = TLS_ASYNC_DO;
18160         } /* case TLS_ASYNC_BUILD */
18161 
18162         case TLS_ASYNC_DO:
18163         {
18164         #ifdef HAVE_ECC
18165            if (ssl->hsType == DYNAMIC_TYPE_ECC) {
18166                 ecc_key* key = (ecc_key*)ssl->hsKey;
18167 
18168                 ret = EccSign(ssl,
18169                     ssl->buffers.digest.buffer, ssl->buffers.digest.length,
18170                     ssl->buffers.sig.buffer, &ssl->buffers.sig.length,
18171                     key,
18172             #if defined(HAVE_PK_CALLBACKS)
18173                     ssl->buffers.key->buffer,
18174                     ssl->buffers.key->length,
18175                     ssl->EccSignCtx
18176             #else
18177                     NULL, 0, NULL
18178             #endif
18179                 );
18180             }
18181         #endif /* HAVE_ECC */
18182         #ifndef NO_RSA
18183             if (ssl->hsType == DYNAMIC_TYPE_RSA) {
18184                 RsaKey* key = (RsaKey*)ssl->hsKey;
18185 
18186                 /* restore verify pointer */
18187                 args->verify = &args->output[args->idx];
18188 
18189                 ret = RsaSign(ssl,
18190                     ssl->buffers.sig.buffer, ssl->buffers.sig.length,
18191                     args->verify + args->extraSz + VERIFY_HEADER, &args->sigSz,
18192                     key,
18193                     ssl->buffers.key->buffer,
18194                     ssl->buffers.key->length,
18195                 #ifdef HAVE_PK_CALLBACKS
18196                     ssl->RsaSignCtx
18197                 #else
18198                     NULL
18199                 #endif
18200                 );
18201             }
18202         #endif /* !NO_RSA */
18203 
18204             /* Check for error */
18205             if (ret != 0) {
18206                 goto exit_scv;
18207             }
18208 
18209             /* Advance state and proceed */
18210             ssl->options.asyncState = TLS_ASYNC_VERIFY;
18211         } /* case TLS_ASYNC_DO */
18212 
18213         case TLS_ASYNC_VERIFY:
18214         {
18215             /* restore verify pointer */
18216             args->verify = &args->output[args->idx];
18217 
18218         #ifdef HAVE_ECC
18219             if (ssl->hsType == DYNAMIC_TYPE_ECC) {
18220                 args->length = ssl->buffers.sig.length;
18221                 /* prepend hdr */
18222                 c16toa((word16)ssl->buffers.sig.length, args->verify +
18223                                                                 args->extraSz);
18224                 XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER,
18225                         ssl->buffers.sig.buffer, ssl->buffers.sig.length);
18226             }
18227         #endif /* HAVE_ECC */
18228         #ifndef NO_RSA
18229             if (ssl->hsType == DYNAMIC_TYPE_RSA) {
18230                 RsaKey* key = (RsaKey*)ssl->hsKey;
18231 
18232                 if (args->verifySig == NULL) {
18233                     args->verifySig = (byte*)XMALLOC(args->sigSz, ssl->heap,
18234                                       DYNAMIC_TYPE_TMP_BUFFER);
18235                     if (args->verifySig == NULL) {
18236                         ERROR_OUT(MEMORY_E, exit_scv);
18237                     }
18238                     XMEMCPY(args->verifySig, args->verify + args->extraSz +
18239                                                     VERIFY_HEADER, args->sigSz);
18240                 }
18241 
18242                 /* check for signature faults */
18243                 ret = VerifyRsaSign(ssl,
18244                     args->verifySig, args->sigSz,
18245                     ssl->buffers.sig.buffer, ssl->buffers.sig.length,
18246                     key
18247                 );
18248             }
18249         #endif /* !NO_RSA */
18250 
18251             /* Check for error */
18252             if (ret != 0) {
18253                 goto exit_scv;
18254             }
18255 
18256             /* Advance state and proceed */
18257             ssl->options.asyncState = TLS_ASYNC_FINALIZE;
18258         } /* case TLS_ASYNC_VERIFY */
18259 
18260         case TLS_ASYNC_FINALIZE:
18261         {
18262             if (args->output == NULL) {
18263                 ERROR_OUT(BUFFER_ERROR, exit_scv);
18264             }
18265             AddHeaders(args->output, args->length + args->extraSz +
18266                                         VERIFY_HEADER, certificate_verify, ssl);
18267 
18268             args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
18269                                     args->length + args->extraSz + VERIFY_HEADER;
18270 
18271         #ifdef WOLFSSL_DTLS
18272             if (ssl->options.dtls) {
18273                 args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
18274             }
18275         #endif
18276 
18277             if (IsEncryptionOn(ssl, 1)) {
18278                 args->inputSz = args->sendSz - RECORD_HEADER_SZ;
18279                                 /* build msg adds rec hdr */
18280                 args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
18281                                                        DYNAMIC_TYPE_TMP_BUFFER);
18282                 if (args->input == NULL) {
18283                     ERROR_OUT(MEMORY_E, exit_scv);
18284                 }
18285 
18286                 XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
18287                                                                 args->inputSz);
18288             }
18289 
18290             /* Advance state and proceed */
18291             ssl->options.asyncState = TLS_ASYNC_END;
18292         } /* case TLS_ASYNC_FINALIZE */
18293 
18294         case TLS_ASYNC_END:
18295         {
18296             if (IsEncryptionOn(ssl, 1)) {
18297                 ret = BuildMessage(ssl, args->output,
18298                                       MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
18299                                       args->input, args->inputSz, handshake,
18300                                       1, 0, 1);
18301             #ifdef WOLFSSL_ASYNC_CRYPT
18302                 if (ret == WC_PENDING_E)
18303                     goto exit_scv;
18304             #endif
18305 
18306                 XFREE(args->input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
18307                 args->input = NULL;  /* make sure its not double free'd on cleanup */
18308 
18309                 if (ret >= 0) {
18310                     args->sendSz = ret;
18311                     ret = 0;
18312                 }
18313             }
18314             else {
18315             #ifdef WOLFSSL_DTLS
18316                 if (ssl->options.dtls)
18317                     DtlsSEQIncrement(ssl, CUR_ORDER);
18318             #endif
18319                 ret = HashOutput(ssl, args->output, args->sendSz, 0);
18320             }
18321 
18322             if (ret != 0) {
18323                 goto exit_scv;
18324             }
18325 
18326         #ifdef WOLFSSL_DTLS
18327             if (IsDtlsNotSctpMode(ssl)) {
18328                 ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz);
18329             }
18330         #endif
18331 
18332 
18333         #ifdef WOLFSSL_CALLBACKS
18334             if (ssl->hsInfoOn)
18335                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
18336             if (ssl->toInfoOn)
18337                 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
18338                               args->output, args->sendSz, ssl->heap);
18339         #endif
18340 
18341             ssl->buffers.outputBuffer.length += args->sendSz;
18342 
18343             if (!ssl->options.groupMessages) {
18344                 ret = SendBuffered(ssl);
18345             }
18346             break;
18347         }
18348         default:
18349             ret = INPUT_CASE_ERROR;
18350     } /* switch(ssl->options.asyncState) */
18351 
18352 exit_scv:
18353 
18354     WOLFSSL_LEAVE("SendCertificateVerify", ret);
18355 
18356 #ifdef WOLFSSL_ASYNC_CRYPT
18357     /* Handle async operation */
18358     if (ret == WC_PENDING_E) {
18359         return ret;
18360     }
18361 #endif /* WOLFSSL_ASYNC_CRYPT */
18362 
18363     /* Digest is not allocated, so do this to prevent free */
18364     ssl->buffers.digest.buffer = NULL;
18365     ssl->buffers.digest.length = 0;
18366 
18367     /* Final cleanup */
18368     FreeScvArgs(ssl, args);
18369     FreeKeyExchange(ssl);
18370 
18371     return ret;
18372 }
18373 
18374 #endif /* NO_CERTS */
18375 
18376 
18377 #ifdef HAVE_SESSION_TICKET
18378 static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
18379     word32 size)
18380 {
18381     word32 begin = *inOutIdx;
18382     word32 lifetime;
18383     word16 length;
18384 
18385     if (ssl->expect_session_ticket == 0) {
18386         WOLFSSL_MSG("Unexpected session ticket");
18387         return SESSION_TICKET_EXPECT_E;
18388     }
18389 
18390     if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
18391         return BUFFER_ERROR;
18392 
18393     ato32(input + *inOutIdx, &lifetime);
18394     *inOutIdx += OPAQUE32_LEN;
18395 
18396     if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
18397         return BUFFER_ERROR;
18398 
18399     ato16(input + *inOutIdx, &length);
18400     *inOutIdx += OPAQUE16_LEN;
18401 
18402     if ((*inOutIdx - begin) + length > size)
18403         return BUFFER_ERROR;
18404 
18405     if (length > sizeof(ssl->session.staticTicket)) {
18406         /* Free old dynamic ticket if we already had one */
18407         if (ssl->session.isDynamic)
18408             XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
18409         ssl->session.ticket =
18410              (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
18411         if (ssl->session.ticket == NULL) {
18412             /* Set to static ticket to avoid null pointer error */
18413             ssl->session.ticket = ssl->session.staticTicket;
18414             ssl->session.isDynamic = 0;
18415             return MEMORY_E;
18416         }
18417         ssl->session.isDynamic = 1;
18418     } else {
18419         if(ssl->session.isDynamic) {
18420             XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
18421         }
18422         ssl->session.isDynamic = 0;
18423         ssl->session.ticket = ssl->session.staticTicket;
18424     }
18425 
18426     /* If the received ticket including its length is greater than
18427      * a length value, the save it. Otherwise, don't save it. */
18428     if (length > 0) {
18429         XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
18430         *inOutIdx += length;
18431         ssl->session.ticketLen = length;
18432         ssl->timeout = lifetime;
18433         if (ssl->session_ticket_cb != NULL) {
18434             ssl->session_ticket_cb(ssl,
18435                                    ssl->session.ticket, ssl->session.ticketLen,
18436                                    ssl->session_ticket_ctx);
18437         }
18438         /* Create a fake sessionID based on the ticket, this will
18439          * supercede the existing session cache info. */
18440         ssl->options.haveSessionId = 1;
18441         XMEMCPY(ssl->arrays->sessionID,
18442                                  ssl->session.ticket + length - ID_LEN, ID_LEN);
18443 #ifndef NO_SESSION_CACHE
18444         AddSession(ssl);
18445 #endif
18446 
18447     }
18448     else {
18449         ssl->session.ticketLen = 0;
18450     }
18451 
18452     if (IsEncryptionOn(ssl, 0)) {
18453         *inOutIdx += ssl->keys.padSz;
18454     }
18455 
18456     ssl->expect_session_ticket = 0;
18457 
18458     return 0;
18459 }
18460 #endif /* HAVE_SESSION_TICKET */
18461 
18462 #endif /* NO_WOLFSSL_CLIENT */
18463 
18464 
18465 #ifndef NO_WOLFSSL_SERVER
18466 
18467     int SendServerHello(WOLFSSL* ssl)
18468     {
18469         byte              *output;
18470         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
18471         int                sendSz;
18472         int                ret;
18473         byte               sessIdSz = ID_LEN;
18474         byte               echoId   = 0;  /* ticket echo id flag */
18475         byte               cacheOff = 0;  /* session cache off flag */
18476 
18477         length = VERSION_SZ + RAN_LEN
18478                + ID_LEN + ENUM_LEN
18479                + SUITE_LEN
18480                + ENUM_LEN;
18481 
18482 #ifdef HAVE_TLS_EXTENSIONS
18483         length += TLSX_GetResponseSize(ssl, server_hello);
18484     #ifdef HAVE_SESSION_TICKET
18485         if (ssl->options.useTicket) {
18486             /* echo session id sz can be 0,32 or bogus len inbetween */
18487             sessIdSz = ssl->arrays->sessionIDSz;
18488             if (sessIdSz > ID_LEN) {
18489                 WOLFSSL_MSG("Bad bogus session id len");
18490                 return BUFFER_ERROR;
18491             }
18492             if (!IsAtLeastTLSv1_3(ssl->version))
18493                 length -= (ID_LEN - sessIdSz);  /* adjust ID_LEN assumption */
18494             echoId = 1;
18495         }
18496     #endif /* HAVE_SESSION_TICKET */
18497 #else
18498         if (ssl->options.haveEMS) {
18499             length += HELLO_EXT_SZ_SZ + HELLO_EXT_SZ;
18500         }
18501 #endif
18502 
18503         /* is the session cahce off at build or runtime */
18504 #ifdef NO_SESSION_CACHE
18505         cacheOff = 1;
18506 #else
18507         if (ssl->options.sessionCacheOff == 1) {
18508             cacheOff = 1;
18509         }
18510 #endif
18511 
18512         /* if no session cache don't send a session ID unless we're echoing
18513          * an ID as part of session tickets */
18514         if (echoId == 0 && cacheOff == 1) {
18515             length -= ID_LEN;    /* adjust ID_LEN assumption */
18516             sessIdSz = 0;
18517         }
18518 
18519         /* check for avalaible size */
18520         if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
18521             return ret;
18522 
18523         /* get output buffer */
18524         output = ssl->buffers.outputBuffer.buffer +
18525                  ssl->buffers.outputBuffer.length;
18526 
18527         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
18528         #ifdef WOLFSSL_DTLS
18529         if (ssl->options.dtls) {
18530             /* Server Hello should use the same sequence number as the
18531              * Client Hello. */
18532             ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi;
18533             ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo;
18534             idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
18535             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
18536         }
18537         #endif /* WOLFSSL_DTLS */
18538         AddHeaders(output, length, server_hello, ssl);
18539 
18540         /* now write to output */
18541         /* first version */
18542         output[idx++] = ssl->version.major;
18543         output[idx++] = ssl->version.minor;
18544 
18545         /* then random and session id */
18546         if (!ssl->options.resuming) {
18547             /* generate random part and session id */
18548             ret = wc_RNG_GenerateBlock(ssl->rng, output + idx,
18549                 RAN_LEN + sizeof(sessIdSz) + sessIdSz);
18550             if (ret != 0)
18551                 return ret;
18552 
18553             /* store info in SSL for later */
18554             XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
18555             idx += RAN_LEN;
18556             output[idx++] = sessIdSz;
18557             XMEMCPY(ssl->arrays->sessionID, output + idx, sessIdSz);
18558             ssl->arrays->sessionIDSz = sessIdSz;
18559         }
18560         else {
18561             /* If resuming, use info from SSL */
18562             XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
18563             idx += RAN_LEN;
18564             output[idx++] = sessIdSz;
18565             XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
18566         }
18567         idx += sessIdSz;
18568 
18569 #ifdef SHOW_SECRETS
18570         {
18571             int j;
18572             printf("server random: ");
18573             for (j = 0; j < RAN_LEN; j++)
18574                 printf("%02x", ssl->arrays->serverRandom[j]);
18575             printf("\n");
18576         }
18577 #endif
18578 
18579         /* then cipher suite */
18580         output[idx++] = ssl->options.cipherSuite0;
18581         output[idx++] = ssl->options.cipherSuite;
18582 
18583         /* then compression */
18584         if (ssl->options.usingCompression)
18585             output[idx++] = ZLIB_COMPRESSION;
18586         else
18587             output[idx++] = NO_COMPRESSION;
18588 
18589         /* last, extensions */
18590 #ifdef HAVE_TLS_EXTENSIONS
18591         TLSX_WriteResponse(ssl, output + idx, server_hello);
18592 #else
18593 #ifdef HAVE_EXTENDED_MASTER
18594         if (ssl->options.haveEMS) {
18595             c16toa(HELLO_EXT_SZ, output + idx);
18596             idx += HELLO_EXT_SZ_SZ;
18597 
18598             c16toa(HELLO_EXT_EXTMS, output + idx);
18599             idx += HELLO_EXT_TYPE_SZ;
18600             c16toa(0, output + idx);
18601             /*idx += HELLO_EXT_SZ_SZ;*/
18602             /* idx is not used after this point. uncomment the line above
18603              * if adding any more extentions in the future. */
18604         }
18605 #endif
18606 #endif
18607 
18608         ssl->buffers.outputBuffer.length += sendSz;
18609         #ifdef WOLFSSL_DTLS
18610             if (IsDtlsNotSctpMode(ssl)) {
18611                 if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
18612                     return ret;
18613             }
18614 
18615             if (ssl->options.dtls) {
18616                 DtlsSEQIncrement(ssl, CUR_ORDER);
18617             }
18618         #endif
18619 
18620         ret = HashOutput(ssl, output, sendSz, 0);
18621         if (ret != 0)
18622             return ret;
18623 
18624 
18625     #ifdef WOLFSSL_CALLBACKS
18626         if (ssl->hsInfoOn)
18627             AddPacketName("ServerHello", &ssl->handShakeInfo);
18628         if (ssl->toInfoOn)
18629             AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
18630                           ssl->heap);
18631     #endif
18632 
18633         ssl->options.serverState = SERVER_HELLO_COMPLETE;
18634 
18635         if (ssl->options.groupMessages)
18636             return 0;
18637         else
18638             return SendBuffered(ssl);
18639     }
18640 
18641 
18642 #ifdef HAVE_ECC
18643 
18644     static byte SetCurveId(ecc_key* key)
18645     {
18646         if (key == NULL || key->dp == NULL) {
18647             WOLFSSL_MSG("SetCurveId: Invalid key!");
18648             return 0;
18649         }
18650 
18651         switch(key->dp->oidSum) {
18652         #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
18653         #ifndef NO_ECC_SECP
18654             case ECC_SECP160R1_OID:
18655                 return WOLFSSL_ECC_SECP160R1;
18656         #endif /* !NO_ECC_SECP */
18657         #ifdef HAVE_ECC_SECPR2
18658             case ECC_SECP160R2_OID:
18659                 return WOLFSSL_ECC_SECP160R2;
18660         #endif /* HAVE_ECC_SECPR2 */
18661         #ifdef HAVE_ECC_KOBLITZ
18662             case ECC_SECP160K1_OID:
18663                 return WOLFSSL_ECC_SECP160K1;
18664         #endif /* HAVE_ECC_KOBLITZ */
18665     #endif
18666     #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
18667         #ifndef NO_ECC_SECP
18668             case ECC_SECP192R1_OID:
18669                 return WOLFSSL_ECC_SECP192R1;
18670         #endif /* !NO_ECC_SECP */
18671         #ifdef HAVE_ECC_KOBLITZ
18672             case ECC_SECP192K1_OID:
18673                 return WOLFSSL_ECC_SECP192K1;
18674         #endif /* HAVE_ECC_KOBLITZ */
18675     #endif
18676     #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
18677         #ifndef NO_ECC_SECP
18678             case ECC_SECP224R1_OID:
18679                 return WOLFSSL_ECC_SECP224R1;
18680         #endif /* !NO_ECC_SECP */
18681         #ifdef HAVE_ECC_KOBLITZ
18682             case ECC_SECP224K1_OID:
18683                 return WOLFSSL_ECC_SECP224K1;
18684         #endif /* HAVE_ECC_KOBLITZ */
18685     #endif
18686     #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
18687         #ifndef NO_ECC_SECP
18688             case ECC_SECP256R1_OID:
18689                 return WOLFSSL_ECC_SECP256R1;
18690         #endif /* !NO_ECC_SECP */
18691         #ifdef HAVE_ECC_KOBLITZ
18692             case ECC_SECP256K1_OID:
18693                 return WOLFSSL_ECC_SECP256K1;
18694         #endif /* HAVE_ECC_KOBLITZ */
18695         #ifdef HAVE_ECC_BRAINPOOL
18696             case ECC_BRAINPOOLP256R1_OID:
18697                 return WOLFSSL_ECC_BRAINPOOLP256R1;
18698         #endif /* HAVE_ECC_BRAINPOOL */
18699     #endif
18700     #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
18701         #ifndef NO_ECC_SECP
18702             case ECC_SECP384R1_OID:
18703                 return WOLFSSL_ECC_SECP384R1;
18704         #endif /* !NO_ECC_SECP */
18705         #ifdef HAVE_ECC_BRAINPOOL
18706             case ECC_BRAINPOOLP384R1_OID:
18707                 return WOLFSSL_ECC_BRAINPOOLP384R1;
18708         #endif /* HAVE_ECC_BRAINPOOL */
18709     #endif
18710     #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
18711         #ifdef HAVE_ECC_BRAINPOOL
18712             case ECC_BRAINPOOLP512R1_OID:
18713                 return WOLFSSL_ECC_BRAINPOOLP512R1;
18714         #endif /* HAVE_ECC_BRAINPOOL */
18715     #endif
18716     #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
18717         #ifndef NO_ECC_SECP
18718             case ECC_SECP521R1_OID:
18719                 return WOLFSSL_ECC_SECP521R1;
18720         #endif /* !NO_ECC_SECP */
18721     #endif
18722             default:
18723                 return 0;
18724         }
18725     }
18726 
18727 #endif /* HAVE_ECC */
18728 
18729     typedef struct SskeArgs {
18730         byte*  output; /* not allocated */
18731     #if defined(HAVE_ECC) || (!defined(NO_DH) && !defined(NO_RSA))
18732         byte*  sigDataBuf;
18733     #endif
18734     #if defined(HAVE_ECC)
18735         byte*  exportBuf;
18736     #endif
18737     #ifndef NO_RSA
18738         byte*  verifySig;
18739     #endif
18740         word32 idx;
18741         word32 tmpSigSz;
18742         word32 length;
18743         word32 sigSz;
18744     #if defined(HAVE_ECC) || (!defined(NO_DH) && !defined(NO_RSA))
18745         word32 sigDataSz;
18746     #endif
18747     #if defined(HAVE_ECC)
18748         word32 exportSz;
18749     #endif
18750     #ifdef HAVE_QSH
18751         word32 qshSz;
18752     #endif
18753         int    sendSz;
18754     } SskeArgs;
18755 
18756     static void FreeSskeArgs(WOLFSSL* ssl, void* pArgs)
18757     {
18758         SskeArgs* args = (SskeArgs*)pArgs;
18759 
18760         (void)ssl;
18761 
18762     #if defined(HAVE_ECC)
18763         if (args->exportBuf) {
18764             XFREE(args->exportBuf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
18765             args->exportBuf = NULL;
18766         }
18767     #endif
18768     #if defined(HAVE_ECC) || (!defined(NO_DH) && !defined(NO_RSA))
18769         if (args->sigDataBuf) {
18770             XFREE(args->sigDataBuf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
18771             args->sigDataBuf = NULL;
18772         }
18773     #endif
18774     #ifndef NO_RSA
18775         if (args->verifySig) {
18776             XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
18777             args->verifySig = NULL;
18778         }
18779     #endif
18780         (void)args;
18781     }
18782 
18783     int SendServerKeyExchange(WOLFSSL* ssl)
18784     {
18785         int ret;
18786     #ifdef WOLFSSL_ASYNC_CRYPT
18787         SskeArgs* args = (SskeArgs*)ssl->async.args;
18788         typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
18789         (void)sizeof(args_test);
18790     #else
18791         SskeArgs  args[1];
18792     #endif
18793 
18794         WOLFSSL_ENTER("SendServerKeyExchange");
18795 
18796     #ifdef WOLFSSL_ASYNC_CRYPT
18797         ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
18798         if (ret != WC_NOT_PENDING_E) {
18799             /* Check for error */
18800             if (ret < 0)
18801                 goto exit_sske;
18802         }
18803         else
18804     #endif
18805         {
18806             /* Reset state */
18807             ret = 0;
18808             ssl->options.asyncState = TLS_ASYNC_BEGIN;
18809             XMEMSET(args, 0, sizeof(SskeArgs));
18810         #ifdef WOLFSSL_ASYNC_CRYPT
18811             ssl->async.freeArgs = FreeSskeArgs;
18812         #endif
18813         }
18814 
18815         switch(ssl->options.asyncState)
18816         {
18817             case TLS_ASYNC_BEGIN:
18818             {
18819             #ifdef HAVE_QSH
18820                 if (ssl->peerQSHKeyPresent) {
18821                     args->qshSz = QSH_KeyGetSize(ssl);
18822                 }
18823             #endif
18824 
18825                 /* Do some checks / debug msgs */
18826                 switch(ssl->specs.kea)
18827                 {
18828                 #if defined(HAVE_ECC) && !defined(NO_PSK)
18829                     case ecdhe_psk_kea:
18830                     {
18831                         WOLFSSL_MSG("Using ephemeral ECDH PSK");
18832                         break;
18833                     }
18834                 #endif /* HAVE_ECC && !NO_PSK */
18835                 #ifdef HAVE_ECC
18836                     case ecc_diffie_hellman_kea:
18837                     {
18838                         if (ssl->specs.static_ecdh) {
18839                             WOLFSSL_MSG("Using Static ECDH, not sending ServerKeyExchange");
18840                             ERROR_OUT(0, exit_sske);
18841                         }
18842 
18843                         /* make sure private key exists */
18844                         if (ssl->buffers.key == NULL ||
18845                                             ssl->buffers.key->buffer == NULL) {
18846                             ERROR_OUT(NO_PRIVATE_KEY, exit_sske);
18847                         }
18848 
18849                         WOLFSSL_MSG("Using ephemeral ECDH");
18850                         break;
18851                     }
18852                 #endif /* HAVE_ECC */
18853                 }
18854 
18855                 /* Preparing keys */
18856                 switch(ssl->specs.kea)
18857                 {
18858                 #ifndef NO_PSK
18859                     case psk_kea:
18860                     {
18861                         /* Nothing to do in this sub-state */
18862                         break;
18863                     }
18864                 #endif /* !NO_PSK */
18865                 #if !defined(NO_DH) && (!defined(NO_PSK) || !defined(NO_RSA))
18866                 #if !defined(NO_PSK)
18867                     case dhe_psk_kea:
18868                 #endif
18869                 #if !defined(NO_RSA)
18870                     case diffie_hellman_kea:
18871                 #endif
18872                     {
18873                         /* Allocate DH key buffers and generate key */
18874                         if (ssl->buffers.serverDH_P.buffer == NULL ||
18875                             ssl->buffers.serverDH_G.buffer == NULL) {
18876                             ERROR_OUT(NO_DH_PARAMS, exit_sske);
18877                         }
18878 
18879                         if (ssl->buffers.serverDH_Pub.buffer == NULL) {
18880                             /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
18881                             ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
18882                                     ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
18883                                     ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
18884                             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
18885                                 ERROR_OUT(MEMORY_E, exit_sske);
18886                             }
18887                         }
18888 
18889                         if (ssl->buffers.serverDH_Priv.buffer == NULL) {
18890                             /* Free'd in SSL_ResourceFree and FreeHandshakeResources */
18891                             ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
18892                                     ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
18893                                     ssl->heap, DYNAMIC_TYPE_DH_BUFFER);
18894                             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
18895                                 ERROR_OUT(MEMORY_E, exit_sske);
18896                             }
18897                         }
18898 
18899                         ssl->options.dhKeySz =
18900                                 (word16)ssl->buffers.serverDH_P.length;
18901 
18902                         ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
18903                                             (void**)&ssl->buffers.serverDH_Key);
18904                         if (ret != 0) {
18905                             goto exit_sske;
18906                         }
18907 
18908                         ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
18909                             ssl->buffers.serverDH_P.buffer,
18910                             ssl->buffers.serverDH_P.length,
18911                             ssl->buffers.serverDH_G.buffer,
18912                             ssl->buffers.serverDH_G.length);
18913                         if (ret != 0) {
18914                             goto exit_sske;
18915                         }
18916 
18917                         ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
18918                             ssl->buffers.serverDH_Priv.buffer,
18919                             &ssl->buffers.serverDH_Priv.length,
18920                             ssl->buffers.serverDH_Pub.buffer,
18921                             &ssl->buffers.serverDH_Pub.length);
18922                         break;
18923                     }
18924                 #endif /* !NO_DH && (!NO_PSK || !NO_RSA) */
18925                 #if defined(HAVE_ECC) && !defined(NO_PSK)
18926                     case ecdhe_psk_kea:
18927                         /* Fall through to create temp ECC key */
18928                 #endif /* HAVE_ECC && !NO_PSK */
18929                 #ifdef HAVE_ECC
18930                     case ecc_diffie_hellman_kea:
18931                     {
18932                         /* need ephemeral key now, create it if missing */
18933                         if (ssl->eccTempKey == NULL) {
18934                             /* alloc/init on demand */
18935                             ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
18936                                 (void**)&ssl->eccTempKey);
18937                             if (ret != 0) {
18938                                 goto exit_sske;
18939                             }
18940                         }
18941 
18942                         if (ssl->eccTempKeyPresent == 0) {
18943                             /* TODO: Need to first do wc_EccPrivateKeyDecode,
18944                                 then we know curve dp */
18945                             ret = EccMakeKey(ssl, ssl->eccTempKey, NULL);
18946                             if (ret == 0 || ret == WC_PENDING_E) {
18947                                 ssl->eccTempKeyPresent = 1;
18948                             }
18949                         }
18950                         break;
18951                     }
18952                 #endif /* HAVE_ECC */
18953                     default:
18954                         /* Skip ServerKeyExchange */
18955                         goto exit_sske;
18956                 } /* switch(ssl->specs.kea) */
18957 
18958                 /* Check for error */
18959                 if (ret != 0) {
18960                     goto exit_sske;
18961                 }
18962 
18963                 /* Advance state and proceed */
18964                 ssl->options.asyncState = TLS_ASYNC_BUILD;
18965             } /* case TLS_ASYNC_BEGIN */
18966 
18967             case TLS_ASYNC_BUILD:
18968             {
18969             #if (!defined(NO_DH) && !defined(NO_RSA)) || defined(HAVE_ECC)
18970                 word32 preSigSz, preSigIdx;
18971             #endif
18972 
18973                 switch(ssl->specs.kea)
18974                 {
18975                 #ifndef NO_PSK
18976                     case psk_kea:
18977                     {
18978                         args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
18979 
18980                         if (ssl->arrays->server_hint[0] == 0) {
18981                             ERROR_OUT(0, exit_sske); /* don't send */
18982                         }
18983 
18984                         /* include size part */
18985                         args->length = (word32)XSTRLEN(ssl->arrays->server_hint);
18986                         if (args->length > MAX_PSK_ID_LEN) {
18987                             ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
18988                         }
18989 
18990                         args->length += HINT_LEN_SZ;
18991                         args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
18992                                                             RECORD_HEADER_SZ;
18993 
18994                     #ifdef HAVE_QSH
18995                         args->length += args->qshSz;
18996                         args->sendSz += args->qshSz;
18997                     #endif
18998 
18999                     #ifdef WOLFSSL_DTLS
19000                         if (ssl->options.dtls) {
19001                             args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19002                             args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19003                         }
19004                     #endif
19005                         /* check for available size */
19006                         if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
19007                             goto exit_sske;
19008                         }
19009 
19010                         /* get ouput buffer */
19011                         args->output = ssl->buffers.outputBuffer.buffer +
19012                                        ssl->buffers.outputBuffer.length;
19013 
19014                         AddHeaders(args->output, args->length,
19015                                                     server_key_exchange, ssl);
19016 
19017                         /* key data */
19018                     #ifdef HAVE_QSH
19019                         c16toa((word16)(args->length - args->qshSz -
19020                                         HINT_LEN_SZ), args->output + args->idx);
19021                     #else
19022                         c16toa((word16)(args->length - HINT_LEN_SZ),
19023                                                       args->output + args->idx);
19024                     #endif
19025 
19026                         args->idx += HINT_LEN_SZ;
19027                         XMEMCPY(args->output + args->idx,
19028                                 ssl->arrays->server_hint,
19029                                 args->length - HINT_LEN_SZ);
19030                         break;
19031                     }
19032                 #endif /* !NO_PSK */
19033                 #if !defined(NO_DH) && !defined(NO_PSK)
19034                     case dhe_psk_kea:
19035                     {
19036                         word32 hintLen;
19037 
19038                         args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
19039                         args->length = LENGTH_SZ * 3 + /* p, g, pub */
19040                                  ssl->buffers.serverDH_P.length +
19041                                  ssl->buffers.serverDH_G.length +
19042                                  ssl->buffers.serverDH_Pub.length;
19043 
19044                         /* include size part */
19045                         hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
19046                         if (hintLen > MAX_PSK_ID_LEN) {
19047                             ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
19048                         }
19049                         args->length += hintLen + HINT_LEN_SZ;
19050                         args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
19051                                                             RECORD_HEADER_SZ;
19052 
19053                     #ifdef HAVE_QSH
19054                         args->length += args->qshSz;
19055                         args->sendSz += args->qshSz;
19056                     #endif
19057                     #ifdef WOLFSSL_DTLS
19058                         if (ssl->options.dtls) {
19059                             args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19060                             args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19061                         }
19062                     #endif
19063 
19064                         /* check for available size */
19065                         if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
19066                             goto exit_sske;
19067                         }
19068 
19069                         /* get ouput buffer */
19070                         args->output = ssl->buffers.outputBuffer.buffer +
19071                                        ssl->buffers.outputBuffer.length;
19072 
19073                         AddHeaders(args->output, args->length,
19074                                                     server_key_exchange, ssl);
19075 
19076                         /* key data */
19077                         c16toa((word16)hintLen, args->output + args->idx);
19078                         args->idx += HINT_LEN_SZ;
19079                         XMEMCPY(args->output + args->idx,
19080                                             ssl->arrays->server_hint, hintLen);
19081                         args->idx += hintLen;
19082 
19083                         /* add p, g, pub */
19084                         c16toa((word16)ssl->buffers.serverDH_P.length,
19085                             args->output + args->idx);
19086                         args->idx += LENGTH_SZ;
19087                         XMEMCPY(args->output + args->idx,
19088                                 ssl->buffers.serverDH_P.buffer,
19089                                 ssl->buffers.serverDH_P.length);
19090                         args->idx += ssl->buffers.serverDH_P.length;
19091 
19092                         /*  g */
19093                         c16toa((word16)ssl->buffers.serverDH_G.length,
19094                             args->output + args->idx);
19095                         args->idx += LENGTH_SZ;
19096                         XMEMCPY(args->output + args->idx,
19097                                 ssl->buffers.serverDH_G.buffer,
19098                                 ssl->buffers.serverDH_G.length);
19099                         args->idx += ssl->buffers.serverDH_G.length;
19100 
19101                         /*  pub */
19102                         c16toa((word16)ssl->buffers.serverDH_Pub.length,
19103                             args->output + args->idx);
19104                         args->idx += LENGTH_SZ;
19105                         XMEMCPY(args->output + args->idx,
19106                                 ssl->buffers.serverDH_Pub.buffer,
19107                                 ssl->buffers.serverDH_Pub.length);
19108                         /* No need to update idx, since sizes are already set */
19109                         /* args->idx += ssl->buffers.serverDH_Pub.length; */
19110                         break;
19111                     }
19112                 #endif /* !defined(NO_DH) && !defined(NO_PSK) */
19113                 #if defined(HAVE_ECC) && !defined(NO_PSK)
19114                     case ecdhe_psk_kea:
19115                     {
19116                         word32 hintLen;
19117 
19118                         /* curve type, named curve, length(1) */
19119                         args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
19120                         args->length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
19121 
19122                         args->exportSz = MAX_EXPORT_ECC_SZ;
19123                         args->exportBuf = (byte*)XMALLOC(args->exportSz,
19124                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
19125                         if (args->exportBuf == NULL) {
19126                             ERROR_OUT(MEMORY_E, exit_sske);
19127                         }
19128                         if (wc_ecc_export_x963(ssl->eccTempKey, args->exportBuf,
19129                                                       &args->exportSz) != 0) {
19130                             ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
19131                         }
19132                         args->length += args->exportSz;
19133 
19134                         /* include size part */
19135                         hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
19136                         if (hintLen > MAX_PSK_ID_LEN) {
19137                             ERROR_OUT(SERVER_HINT_ERROR, exit_sske);
19138                         }
19139                         args->length += hintLen + HINT_LEN_SZ;
19140                         args->sendSz = args->length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
19141 
19142                     #ifdef HAVE_QSH
19143                         args->length += args->qshSz;
19144                         args->sendSz += args->qshSz;
19145                     #endif
19146                     #ifdef WOLFSSL_DTLS
19147                         if (ssl->options.dtls) {
19148                             args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19149                             args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19150                         }
19151                     #endif
19152                         /* check for available size */
19153                         if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
19154                             goto exit_sske;
19155                         }
19156 
19157                         /* get output buffer */
19158                         args->output = ssl->buffers.outputBuffer.buffer +
19159                                        ssl->buffers.outputBuffer.length;
19160 
19161                         /* key data */
19162                         c16toa((word16)hintLen, args->output + args->idx);
19163                         args->idx += HINT_LEN_SZ;
19164                         XMEMCPY(args->output + args->idx,
19165                                             ssl->arrays->server_hint, hintLen);
19166                         args->idx += hintLen;
19167 
19168                         /* ECC key exchange data */
19169                         args->output[args->idx++] = named_curve;
19170                         args->output[args->idx++] = 0x00;          /* leading zero */
19171                         args->output[args->idx++] = SetCurveId(ssl->eccTempKey);
19172                         args->output[args->idx++] = (byte)args->exportSz;
19173                         XMEMCPY(args->output + args->idx, args->exportBuf,
19174                                                                 args->exportSz);
19175                         break;
19176                     }
19177                 #endif /* HAVE_ECC && !NO_PSK */
19178                 #ifdef HAVE_ECC
19179                     case ecc_diffie_hellman_kea:
19180                     {
19181                         enum wc_HashType hashType = WC_HASH_TYPE_NONE;
19182 
19183                         /* curve type, named curve, length(1) */
19184                         args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
19185                         args->length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
19186 
19187                         /* Export temp ECC key and add to length */
19188                         args->exportSz = MAX_EXPORT_ECC_SZ;
19189                         args->exportBuf = (byte*)XMALLOC(args->exportSz,
19190                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
19191                         if (args->exportBuf == NULL) {
19192                             ERROR_OUT(MEMORY_E, exit_sske);
19193                         }
19194                         if (wc_ecc_export_x963(ssl->eccTempKey, args->exportBuf,
19195                                                         &args->exportSz) != 0) {
19196                             ERROR_OUT(ECC_EXPORT_ERROR, exit_sske);
19197                         }
19198                         args->length += args->exportSz;
19199 
19200                         preSigSz  = args->length;
19201                         preSigIdx = args->idx;
19202 
19203                         switch(ssl->specs.sig_algo)
19204                         {
19205                         #ifndef NO_RSA
19206                             case rsa_sa_algo:
19207                             {
19208                                 word32 i = 0;
19209                                 int    keySz;
19210 
19211                                 ssl->hsType = DYNAMIC_TYPE_RSA;
19212                                 ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
19213                                 if (ret != 0) {
19214                                     goto exit_sske;
19215                                 }
19216 
19217                                 ret = wc_RsaPrivateKeyDecode(
19218                                     ssl->buffers.key->buffer,
19219                                     &i,
19220                                     (RsaKey*)ssl->hsKey,
19221                                     ssl->buffers.key->length);
19222                                 if (ret != 0) {
19223                                     goto exit_sske;
19224                                 }
19225                                 keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
19226                                 if (keySz < 0) { /* test if keySz has error */
19227                                     ERROR_OUT(keySz, exit_sske);
19228                                 }
19229 
19230                                 args->tmpSigSz = (word32)keySz;
19231                                 if (keySz < ssl->options.minRsaKeySz) {
19232                                     WOLFSSL_MSG("RSA signature key size too small");
19233                                     ERROR_OUT(RSA_KEY_SIZE_E, exit_sske);
19234                                 }
19235                                 break;
19236                             }
19237                         #endif /* !NO_RSA */
19238                             case ecc_dsa_sa_algo:
19239                             {
19240                                 word32 i = 0;
19241 
19242                                 ssl->hsType = DYNAMIC_TYPE_ECC;
19243                                 ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
19244                                 if (ret != 0) {
19245                                     goto exit_sske;
19246                                 }
19247 
19248                                 ret = wc_EccPrivateKeyDecode(
19249                                     ssl->buffers.key->buffer,
19250                                     &i,
19251                                     (ecc_key*)ssl->hsKey,
19252                                     ssl->buffers.key->length);
19253                                 if (ret != 0) {
19254                                     goto exit_sske;
19255                                 }
19256                                 /* worst case estimate */
19257                                 args->tmpSigSz = wc_ecc_sig_size(
19258                                     (ecc_key*)ssl->hsKey);
19259 
19260                                 /* check the minimum ECC key size */
19261                                 if (wc_ecc_size((ecc_key*)ssl->hsKey) <
19262                                         ssl->options.minEccKeySz) {
19263                                     WOLFSSL_MSG("ECC key size too small");
19264                                     ret = ECC_KEY_SIZE_E;
19265                                     goto exit_sske;
19266                                 }
19267                                 break;
19268                             }
19269                             default:
19270                                 ERROR_OUT(ALGO_ID_E, exit_sske);  /* unsupported type */
19271                         } /* switch(ssl->specs.sig_algo) */
19272 
19273                         /* sig length */
19274                         args->length += LENGTH_SZ;
19275                         args->length += args->tmpSigSz;
19276 
19277                         if (IsAtLeastTLSv1_2(ssl)) {
19278                             args->length += HASH_SIG_SIZE;
19279                         }
19280 
19281                         args->sendSz = args->length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
19282 
19283                     #ifdef HAVE_QSH
19284                         args->length += args->qshSz;
19285                         args->sendSz += args->qshSz;
19286                     #endif
19287                     #ifdef WOLFSSL_DTLS
19288                         if (ssl->options.dtls) {
19289                             args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19290                             args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19291                             preSigIdx = args->idx;
19292                         }
19293                     #endif
19294                         /* check for available size */
19295                         if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
19296                             goto exit_sske;
19297                         }
19298 
19299                         /* get ouput buffer */
19300                         args->output = ssl->buffers.outputBuffer.buffer +
19301                                        ssl->buffers.outputBuffer.length;
19302 
19303                         /* record and message headers will be added below, when we're sure
19304                            of the sig length */
19305 
19306                         /* key exchange data */
19307                         args->output[args->idx++] = named_curve;
19308                         args->output[args->idx++] = 0x00;          /* leading zero */
19309                         args->output[args->idx++] = SetCurveId(ssl->eccTempKey);
19310                         args->output[args->idx++] = (byte)args->exportSz;
19311                         XMEMCPY(args->output + args->idx, args->exportBuf, args->exportSz);
19312                         args->idx += args->exportSz;
19313 
19314                         /* Determine hash type */
19315                         if (IsAtLeastTLSv1_2(ssl)) {
19316                             args->output[args->idx++] = ssl->suites->hashAlgo;
19317                             args->output[args->idx++] = ssl->suites->sigAlgo;
19318 
19319                             switch (ssl->suites->hashAlgo) {
19320                                 case sha512_mac:
19321                                 #ifdef WOLFSSL_SHA512
19322                                     hashType = WC_HASH_TYPE_SHA512;
19323                                 #endif
19324                                     break;
19325                                 case sha384_mac:
19326                                 #ifdef WOLFSSL_SHA384
19327                                     hashType = WC_HASH_TYPE_SHA384;
19328                                 #endif
19329                                     break;
19330                                 case sha256_mac:
19331                                 #ifndef NO_SHA256
19332                                     hashType = WC_HASH_TYPE_SHA256;
19333                                 #endif
19334                                     break;
19335                                 case sha_mac:
19336                                     #if !defined(NO_SHA) && \
19337                                             (!defined(NO_OLD_TLS) || \
19338                                               defined(WOLFSSL_ALLOW_TLS_SHA1))
19339                                         hashType = WC_HASH_TYPE_SHA;
19340                                     #endif
19341                                     break;
19342                                 default:
19343                                     WOLFSSL_MSG("Bad hash sig algo");
19344                                     break;
19345                             }
19346 
19347                             if (hashType == WC_HASH_TYPE_NONE) {
19348                                 ERROR_OUT(ALGO_ID_E, exit_sske);
19349                             }
19350 
19351                         } else {
19352                             /* only using sha and md5 for rsa */
19353                         #ifndef NO_OLD_TLS
19354                             hashType = WC_HASH_TYPE_SHA;
19355                             if (ssl->suites->sigAlgo == rsa_sa_algo) {
19356                                 hashType = WC_HASH_TYPE_MD5_SHA;
19357                             }
19358                         #else
19359                             ERROR_OUT(ALGO_ID_E, exit_sske);
19360                         #endif
19361                         }
19362 
19363                         /* Signtaure length will be written later, when we're sure what it is */
19364 
19365                     #ifdef HAVE_FUZZER
19366                         if (ssl->fuzzerCb) {
19367                             ssl->fuzzerCb(ssl, args->output + preSigIdx,
19368                                 preSigSz, FUZZ_SIGNATURE, ssl->fuzzerCtx);
19369                         }
19370                     #endif
19371 
19372                         /* Assemble buffer to hash for signature */
19373                         args->sigDataSz = RAN_LEN + RAN_LEN + preSigSz;
19374                         args->sigDataBuf = (byte*)XMALLOC(args->sigDataSz,
19375                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
19376                         if (args->sigDataBuf == NULL) {
19377                             ERROR_OUT(MEMORY_E, exit_sske);
19378                         }
19379                         XMEMCPY(args->sigDataBuf, ssl->arrays->clientRandom,
19380                                                                        RAN_LEN);
19381                         XMEMCPY(args->sigDataBuf+RAN_LEN,
19382                                             ssl->arrays->serverRandom, RAN_LEN);
19383                         XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
19384                                 args->output + preSigIdx, preSigSz);
19385 
19386                         ssl->buffers.sig.length = wc_HashGetDigestSize(hashType);
19387                         ssl->buffers.sig.buffer = (byte*)XMALLOC(
19388                                             ssl->buffers.sig.length,
19389                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
19390                         if (ssl->buffers.sig.buffer == NULL) {
19391                             ERROR_OUT(MEMORY_E, exit_sske);
19392                         }
19393 
19394                         /* Perform hash */
19395                         ret = wc_Hash(hashType,
19396                             args->sigDataBuf, args->sigDataSz,
19397                             ssl->buffers.sig.buffer, ssl->buffers.sig.length);
19398                         if (ret != 0) {
19399                             goto exit_sske;
19400                         }
19401 
19402                         args->sigSz = args->tmpSigSz;
19403 
19404                         /* Sign hash to create signature */
19405                         switch (ssl->specs.sig_algo)
19406                         {
19407                         #ifndef NO_RSA
19408                             case rsa_sa_algo:
19409                             {
19410                                 /* For TLS 1.2 re-encode signature */
19411                                 if (IsAtLeastTLSv1_2(ssl)) {
19412                                     int typeH = 0;
19413                                     byte* encodedSig = (byte*)XMALLOC(
19414                                                   MAX_ENCODED_SIG_SZ, ssl->heap,
19415                                                        DYNAMIC_TYPE_TMP_BUFFER);
19416                                     if (encodedSig == NULL) {
19417                                         ERROR_OUT(MEMORY_E, exit_sske);
19418                                     }
19419 
19420                                     switch (ssl->suites->hashAlgo) {
19421                                         case sha512_mac:
19422                                         #ifdef WOLFSSL_SHA512
19423                                             typeH    = SHA512h;
19424                                         #endif
19425                                             break;
19426                                         case sha384_mac:
19427                                         #ifdef WOLFSSL_SHA384
19428                                             typeH    = SHA384h;
19429                                         #endif
19430                                             break;
19431                                         case sha256_mac:
19432                                         #ifndef NO_SHA256
19433                                             typeH    = SHA256h;
19434                                         #endif
19435                                             break;
19436                                         case sha_mac:
19437                                             #if !defined(NO_SHA) && \
19438                                               (!defined(NO_OLD_TLS) || \
19439                                                 defined(WOLFSSL_ALLOW_TLS_SHA1))
19440                                                 typeH    = SHAh;
19441                                             #endif
19442                                             break;
19443                                         default:
19444                                             break;
19445                                     }
19446 
19447                                     ssl->buffers.sig.length =
19448                                         wc_EncodeSignature(encodedSig,
19449                                         ssl->buffers.sig.buffer,
19450                                         ssl->buffers.sig.length, typeH);
19451 
19452                                     /* Replace sig buffer with new one */
19453                                     XFREE(ssl->buffers.sig.buffer, ssl->heap,
19454                                                        DYNAMIC_TYPE_TMP_BUFFER);
19455                                     ssl->buffers.sig.buffer = encodedSig;
19456                                 }
19457 
19458                                 /* write sig size here */
19459                                 c16toa((word16)args->sigSz,
19460                                     args->output + args->idx);
19461                                 args->idx += LENGTH_SZ;
19462                                 break;
19463                             }
19464                         #endif /* !NO_RSA */
19465                             case ecc_dsa_sa_algo:
19466                             {
19467                                 break;
19468                             }
19469                         } /* switch(ssl->specs.sig_algo) */
19470                         break;
19471                     }
19472                 #endif /* HAVE_ECC */
19473                 #if !defined(NO_DH) && !defined(NO_RSA)
19474                     case diffie_hellman_kea:
19475                     {
19476                         enum wc_HashType hashType = WC_HASH_TYPE_NONE;
19477 
19478                         args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
19479                         args->length = LENGTH_SZ * 3;  /* p, g, pub */
19480                         args->length += ssl->buffers.serverDH_P.length +
19481                                         ssl->buffers.serverDH_G.length +
19482                                         ssl->buffers.serverDH_Pub.length;
19483 
19484                         preSigIdx = args->idx;
19485                         preSigSz  = args->length;
19486 
19487                         if (!ssl->options.usingAnon_cipher) {
19488                             word32   i = 0;
19489                             int      keySz;
19490 
19491                             /* make sure private key exists */
19492                             if (ssl->buffers.key == NULL ||
19493                                             ssl->buffers.key->buffer == NULL) {
19494                                 ERROR_OUT(NO_PRIVATE_KEY, exit_sske);
19495                             }
19496 
19497                             ssl->hsType = DYNAMIC_TYPE_RSA;
19498                             ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
19499                             if (ret != 0) {
19500                                 goto exit_sske;
19501                             }
19502 
19503                             /* sig length */
19504                             args->length += LENGTH_SZ;
19505 
19506                             ret = wc_RsaPrivateKeyDecode(
19507                                 ssl->buffers.key->buffer, &i,
19508                                 (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
19509                             if (ret != 0) {
19510                                 goto exit_sske;
19511                             }
19512                             keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
19513                             if (keySz < 0) { /* test if keySz has error */
19514                                 ERROR_OUT(keySz, exit_sske);
19515                             }
19516                             args->tmpSigSz = (word32)keySz;
19517                             args->length += args->tmpSigSz;
19518 
19519                             if (keySz < ssl->options.minRsaKeySz) {
19520                                 WOLFSSL_MSG("RSA key size too small");
19521                                 ERROR_OUT(RSA_KEY_SIZE_E, exit_sske);
19522                             }
19523 
19524                             if (IsAtLeastTLSv1_2(ssl)) {
19525                                 args->length += HASH_SIG_SIZE;
19526                             }
19527                         }
19528 
19529                         args->sendSz = args->length + HANDSHAKE_HEADER_SZ +
19530                                                             RECORD_HEADER_SZ;
19531 
19532                     #ifdef HAVE_QSH
19533                         args->length += args->qshSz;
19534                         args->sendSz += args->qshSz;
19535                     #endif
19536                     #ifdef WOLFSSL_DTLS
19537                         if (ssl->options.dtls) {
19538                             args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19539                             args->idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
19540                             preSigIdx = args->idx;
19541                         }
19542                     #endif
19543 
19544                         /* check for available size */
19545                         if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
19546                             goto exit_sske;
19547                         }
19548 
19549                         /* get ouput buffer */
19550                         args->output = ssl->buffers.outputBuffer.buffer +
19551                                        ssl->buffers.outputBuffer.length;
19552 
19553                         AddHeaders(args->output, args->length,
19554                                                     server_key_exchange, ssl);
19555 
19556                         /* add p, g, pub */
19557                         c16toa((word16)ssl->buffers.serverDH_P.length,
19558                                                     args->output + args->idx);
19559                         args->idx += LENGTH_SZ;
19560                         XMEMCPY(args->output + args->idx,
19561                                               ssl->buffers.serverDH_P.buffer,
19562                                               ssl->buffers.serverDH_P.length);
19563                         args->idx += ssl->buffers.serverDH_P.length;
19564 
19565                         /*  g */
19566                         c16toa((word16)ssl->buffers.serverDH_G.length,
19567                                                     args->output + args->idx);
19568                         args->idx += LENGTH_SZ;
19569                         XMEMCPY(args->output + args->idx,
19570                                               ssl->buffers.serverDH_G.buffer,
19571                                               ssl->buffers.serverDH_G.length);
19572                         args->idx += ssl->buffers.serverDH_G.length;
19573 
19574                         /*  pub */
19575                         c16toa((word16)ssl->buffers.serverDH_Pub.length,
19576                                                     args->output + args->idx);
19577                         args->idx += LENGTH_SZ;
19578                         XMEMCPY(args->output + args->idx,
19579                                               ssl->buffers.serverDH_Pub.buffer,
19580                                               ssl->buffers.serverDH_Pub.length);
19581                         args->idx += ssl->buffers.serverDH_Pub.length;
19582 
19583                     #ifdef HAVE_FUZZER
19584                         if (ssl->fuzzerCb) {
19585                             ssl->fuzzerCb(ssl, args->output + preSigIdx,
19586                                 preSigSz, FUZZ_SIGNATURE, ssl->fuzzerCtx);
19587                         }
19588                     #endif
19589 
19590                         if (ssl->options.usingAnon_cipher) {
19591                             break;
19592                         }
19593 
19594                         /* Determine hash type */
19595                         if (IsAtLeastTLSv1_2(ssl)) {
19596                             args->output[args->idx++] = ssl->suites->hashAlgo;
19597                             args->output[args->idx++] = ssl->suites->sigAlgo;
19598 
19599                             switch (ssl->suites->hashAlgo) {
19600                                 case sha512_mac:
19601                                 #ifdef WOLFSSL_SHA512
19602                                     hashType = WC_HASH_TYPE_SHA512;
19603                                 #endif
19604                                     break;
19605                                 case sha384_mac:
19606                                 #ifdef WOLFSSL_SHA384
19607                                     hashType = WC_HASH_TYPE_SHA384;
19608                                 #endif
19609                                     break;
19610                                 case sha256_mac:
19611                                 #ifndef NO_SHA256
19612                                     hashType = WC_HASH_TYPE_SHA256;
19613                                 #endif
19614                                     break;
19615                                 case sha_mac:
19616                                     #if !defined(NO_SHA) && \
19617                                             (!defined(NO_OLD_TLS) || \
19618                                               defined(WOLFSSL_ALLOW_TLS_SHA1))
19619                                         hashType = WC_HASH_TYPE_SHA;
19620                                     #endif
19621                                     break;
19622                                 default:
19623                                     WOLFSSL_MSG("Bad hash sig algo");
19624                                     break;
19625                             }
19626 
19627                             if (hashType == WC_HASH_TYPE_NONE) {
19628                                 ERROR_OUT(ALGO_ID_E, exit_sske);
19629                             }
19630                         } else {
19631                             /* only using sha and md5 for rsa */
19632                         #ifndef NO_OLD_TLS
19633                             hashType = WC_HASH_TYPE_SHA;
19634                             if (ssl->suites->sigAlgo == rsa_sa_algo) {
19635                                 hashType = WC_HASH_TYPE_MD5_SHA;
19636                             }
19637                         #else
19638                             ERROR_OUT(ALGO_ID_E, exit_sske);
19639                         #endif
19640                         }
19641 
19642                         /* signature size */
19643                         c16toa((word16)args->tmpSigSz, args->output + args->idx);
19644                         args->idx += LENGTH_SZ;
19645 
19646                         /* Assemble buffer to hash for signature */
19647                         args->sigDataSz = RAN_LEN + RAN_LEN + preSigSz;
19648                         args->sigDataBuf = (byte*)XMALLOC(args->sigDataSz,
19649                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
19650                         if (args->sigDataBuf == NULL) {
19651                             ERROR_OUT(MEMORY_E, exit_sske);
19652                         }
19653                         XMEMCPY(args->sigDataBuf, ssl->arrays->clientRandom,
19654                                                                     RAN_LEN);
19655                         XMEMCPY(args->sigDataBuf+RAN_LEN,
19656                                         ssl->arrays->serverRandom, RAN_LEN);
19657                         XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN,
19658                             args->output + preSigIdx, preSigSz);
19659 
19660                         ssl->buffers.sig.length = wc_HashGetDigestSize(hashType);
19661                         ssl->buffers.sig.buffer = (byte*)XMALLOC(
19662                                              ssl->buffers.sig.length, ssl->heap,
19663                                                        DYNAMIC_TYPE_TMP_BUFFER);
19664                         if (ssl->buffers.sig.buffer == NULL) {
19665                             ERROR_OUT(MEMORY_E, exit_sske);
19666                         }
19667 
19668                         /* Perform hash */
19669                         ret = wc_Hash(hashType,
19670                             args->sigDataBuf, args->sigDataSz,
19671                             ssl->buffers.sig.buffer, ssl->buffers.sig.length);
19672                         if (ret != 0) {
19673                             goto exit_sske;
19674                         }
19675 
19676                         args->sigSz = args->tmpSigSz;
19677 
19678                         /* Sign hash to create signature */
19679                         switch (ssl->suites->sigAlgo)
19680                         {
19681                         #ifndef NO_RSA
19682                             case rsa_sa_algo:
19683                             {
19684                                 /* For TLS 1.2 re-encode signature */
19685                                 if (IsAtLeastTLSv1_2(ssl)) {
19686                                     int typeH = 0;
19687                                     byte* encodedSig = (byte*)XMALLOC(
19688                                                   MAX_ENCODED_SIG_SZ, ssl->heap,
19689                                                        DYNAMIC_TYPE_TMP_BUFFER);
19690                                     if (encodedSig == NULL) {
19691                                         ERROR_OUT(MEMORY_E, exit_sske);
19692                                     }
19693 
19694                                     switch (ssl->suites->hashAlgo) {
19695                                         case sha512_mac:
19696                                         #ifdef WOLFSSL_SHA512
19697                                             typeH    = SHA512h;
19698                                         #endif
19699                                             break;
19700                                         case sha384_mac:
19701                                         #ifdef WOLFSSL_SHA384
19702                                             typeH    = SHA384h;
19703                                         #endif
19704                                             break;
19705                                         case sha256_mac:
19706                                         #ifndef NO_SHA256
19707                                             typeH    = SHA256h;
19708                                         #endif
19709                                             break;
19710                                         case sha_mac:
19711                                             #if !defined(NO_SHA) && \
19712                                               (!defined(NO_OLD_TLS) || \
19713                                                 defined(WOLFSSL_ALLOW_TLS_SHA1))
19714                                                 typeH    = SHAh;
19715                                             #endif
19716                                             break;
19717                                         default:
19718                                             break;
19719                                     }
19720 
19721                                     ssl->buffers.sig.length =
19722                                     wc_EncodeSignature(encodedSig,
19723                                         ssl->buffers.sig.buffer,
19724                                         ssl->buffers.sig.length, typeH);
19725 
19726                                     /* Replace sig buffer with new one */
19727                                     XFREE(ssl->buffers.sig.buffer, ssl->heap,
19728                                                        DYNAMIC_TYPE_TMP_BUFFER);
19729                                     ssl->buffers.sig.buffer = encodedSig;
19730                                 }
19731                                 break;
19732                             }
19733                         #endif /* NO_RSA */
19734                         } /* switch (ssl->suites->sigAlgo) */
19735                         break;
19736                     }
19737                 #endif /* !defined(NO_DH) && !defined(NO_RSA) */
19738                 } /* switch(ssl->specs.kea) */
19739 
19740                 /* Check for error */
19741                 if (ret != 0) {
19742                     goto exit_sske;
19743                 }
19744 
19745                 /* Advance state and proceed */
19746                 ssl->options.asyncState = TLS_ASYNC_DO;
19747             } /* case TLS_ASYNC_BUILD */
19748 
19749             case TLS_ASYNC_DO:
19750             {
19751                 switch(ssl->specs.kea)
19752                 {
19753                 #ifndef NO_PSK
19754                     case psk_kea:
19755                     {
19756                         break;
19757                     }
19758                 #endif /* !NO_PSK */
19759                 #if !defined(NO_DH) && !defined(NO_PSK)
19760                     case dhe_psk_kea:
19761                     {
19762                         break;
19763                     }
19764                 #endif /* !defined(NO_DH) && !defined(NO_PSK) */
19765                 #if defined(HAVE_ECC) && !defined(NO_PSK)
19766                     case ecdhe_psk_kea:
19767                     {
19768                         break;
19769                     }
19770                 #endif /* HAVE_ECC && !NO_PSK */
19771                 #ifdef HAVE_ECC
19772                     case ecc_diffie_hellman_kea:
19773                     {
19774                         /* Sign hash to create signature */
19775                         switch (ssl->specs.sig_algo)
19776                         {
19777                         #ifndef NO_RSA
19778                             case rsa_sa_algo:
19779                             {
19780                                 RsaKey* key = (RsaKey*)ssl->hsKey;
19781 
19782                                 ret = RsaSign(ssl,
19783                                     ssl->buffers.sig.buffer,
19784                                     ssl->buffers.sig.length,
19785                                     args->output + args->idx,
19786                                     &args->sigSz,
19787                                     key,
19788                                     ssl->buffers.key->buffer,
19789                                     ssl->buffers.key->length,
19790                             #ifdef HAVE_PK_CALLBACKS
19791                                     ssl->RsaSignCtx
19792                             #else
19793                                     NULL
19794                             #endif
19795                                 );
19796                                 break;
19797                             }
19798                         #endif /* !NO_RSA */
19799                             case ecc_dsa_sa_algo:
19800                             {
19801                                 ecc_key* key = (ecc_key*)ssl->hsKey;
19802 
19803                                 ret = EccSign(ssl,
19804                                     ssl->buffers.sig.buffer,
19805                                     ssl->buffers.sig.length,
19806                                     args->output + LENGTH_SZ + args->idx,
19807                                     &args->sigSz,
19808                                     key,
19809                             #if defined(HAVE_PK_CALLBACKS)
19810                                     ssl->buffers.key->buffer,
19811                                     ssl->buffers.key->length,
19812                                     ssl->EccSignCtx
19813                             #else
19814                                     NULL, 0, NULL
19815                             #endif
19816                                 );
19817                                 break;
19818                             }
19819                         } /* switch(ssl->specs.sig_algo) */
19820                         break;
19821                     }
19822                 #endif /* HAVE_ECC */
19823                 #if !defined(NO_DH) && !defined(NO_RSA)
19824                     case diffie_hellman_kea:
19825                     {
19826                         /* Sign hash to create signature */
19827                         switch (ssl->suites->sigAlgo)
19828                         {
19829                         #ifndef NO_RSA
19830                             case rsa_sa_algo:
19831                             {
19832                                 RsaKey* key = (RsaKey*)ssl->hsKey;
19833 
19834                                 if (ssl->options.usingAnon_cipher) {
19835                                     break;
19836                                 }
19837 
19838                                 ret = RsaSign(ssl,
19839                                     ssl->buffers.sig.buffer,
19840                                     ssl->buffers.sig.length,
19841                                     args->output + args->idx,
19842                                     &args->sigSz,
19843                                     key,
19844                                     ssl->buffers.key->buffer,
19845                                     ssl->buffers.key->length,
19846                                 #ifdef HAVE_PK_CALLBACKS
19847                                     ssl->RsaSignCtx
19848                                 #else
19849                                     NULL
19850                                 #endif
19851                                 );
19852                                 break;
19853                             }
19854                         #endif /* NO_RSA */
19855                         } /* switch (ssl->suites->sigAlgo) */
19856 
19857                         break;
19858                     }
19859                 #endif /* !defined(NO_DH) && !defined(NO_RSA) */
19860                 } /* switch(ssl->specs.kea) */
19861 
19862                 /* Check for error */
19863                 if (ret != 0) {
19864                     goto exit_sske;
19865                 }
19866 
19867                 /* Advance state and proceed */
19868                 ssl->options.asyncState = TLS_ASYNC_VERIFY;
19869             } /* case TLS_ASYNC_DO */
19870 
19871             case TLS_ASYNC_VERIFY:
19872             {
19873                 switch(ssl->specs.kea)
19874                 {
19875                 #ifndef NO_PSK
19876                     case psk_kea:
19877                     {
19878                         /* Nothing to do in this sub-state */
19879                         break;
19880                     }
19881                 #endif /* !NO_PSK */
19882                 #if !defined(NO_DH) && !defined(NO_PSK)
19883                     case dhe_psk_kea:
19884                     {
19885                         /* Nothing to do in this sub-state */
19886                         break;
19887                     }
19888                 #endif /* !defined(NO_DH) && !defined(NO_PSK) */
19889                 #if defined(HAVE_ECC) && !defined(NO_PSK)
19890                     case ecdhe_psk_kea:
19891                     {
19892                         /* Nothing to do in this sub-state */
19893                         break;
19894                     }
19895                 #endif /* HAVE_ECC && !NO_PSK */
19896                 #ifdef HAVE_ECC
19897                     case ecc_diffie_hellman_kea:
19898                     {
19899                         switch(ssl->specs.sig_algo)
19900                         {
19901                         #ifndef NO_RSA
19902                             case rsa_sa_algo:
19903                             {
19904                                 RsaKey* key = (RsaKey*)ssl->hsKey;
19905 
19906                                 if (args->verifySig == NULL) {
19907                                     if (args->sigSz == 0) {
19908                                         ERROR_OUT(BAD_COND_E, exit_sske);
19909                                     }
19910                                     args->verifySig = (byte*)XMALLOC(
19911                                                     args->sigSz, ssl->heap,
19912                                                     DYNAMIC_TYPE_TMP_BUFFER);
19913                                     if (!args->verifySig) {
19914                                         ERROR_OUT(MEMORY_E, exit_sske);
19915                                     }
19916                                     XMEMCPY(args->verifySig,
19917                                         args->output + args->idx, args->sigSz);
19918                                 }
19919 
19920                                 /* check for signature faults */
19921                                 ret = VerifyRsaSign(ssl,
19922                                     args->verifySig, args->sigSz,
19923                                     ssl->buffers.sig.buffer,
19924                                     ssl->buffers.sig.length,
19925                                     key
19926                                 );
19927                                 break;
19928                             }
19929                         #endif
19930                             case ecc_dsa_sa_algo:
19931                             {
19932                                 /* Now that we know the real sig size, write it. */
19933                                 c16toa((word16)args->sigSz,
19934                                                     args->output + args->idx);
19935 
19936                                 /* And adjust length and sendSz from estimates */
19937                                 args->length += args->sigSz - args->tmpSigSz;
19938                                 args->sendSz += args->sigSz - args->tmpSigSz;
19939                                 break;
19940                             }
19941                             default:
19942                                 ERROR_OUT(ALGO_ID_E, exit_sske);  /* unsupported type */
19943                         } /* switch(ssl->specs.sig_algo) */
19944                         break;
19945                     }
19946                 #endif /* HAVE_ECC */
19947                 #if !defined(NO_DH) && !defined(NO_RSA)
19948                     case diffie_hellman_kea:
19949                     {
19950                         switch (ssl->suites->sigAlgo)
19951                         {
19952                         #ifndef NO_RSA
19953                             case rsa_sa_algo:
19954                             {
19955                                 RsaKey* key = (RsaKey*)ssl->hsKey;
19956 
19957                                 if (ssl->options.usingAnon_cipher) {
19958                                     break;
19959                                 }
19960 
19961                                 if (args->verifySig == NULL) {
19962                                     if (args->sigSz == 0) {
19963                                         ERROR_OUT(BAD_COND_E, exit_sske);
19964                                     }
19965                                     args->verifySig = (byte*)XMALLOC(
19966                                                       args->sigSz, ssl->heap,
19967                                                       DYNAMIC_TYPE_TMP_BUFFER);
19968                                     if (!args->verifySig) {
19969                                         ERROR_OUT(MEMORY_E, exit_sske);
19970                                     }
19971                                     XMEMCPY(args->verifySig,
19972                                         args->output + args->idx, args->sigSz);
19973                                 }
19974 
19975                                 /* check for signature faults */
19976                                 ret = VerifyRsaSign(ssl,
19977                                     args->verifySig, args->sigSz,
19978                                     ssl->buffers.sig.buffer,
19979                                     ssl->buffers.sig.length,
19980                                     key
19981                                 );
19982                                 break;
19983                             }
19984                         #endif
19985                         } /* switch (ssl->suites->sigAlgo) */
19986                         break;
19987                     }
19988                 #endif /* !defined(NO_DH) && !defined(NO_RSA) */
19989                 } /* switch(ssl->specs.kea) */
19990 
19991                 /* Check for error */
19992                 if (ret != 0) {
19993                     goto exit_sske;
19994                 }
19995 
19996                 /* Advance state and proceed */
19997                 ssl->options.asyncState = TLS_ASYNC_FINALIZE;
19998             } /* case TLS_ASYNC_VERIFY */
19999 
20000             case TLS_ASYNC_FINALIZE:
20001             {
20002             #ifdef HAVE_QSH
20003                 if (ssl->peerQSHKeyPresent) {
20004                     if (args->qshSz > 0) {
20005                         args->idx = args->sendSz - args->qshSz;
20006                         if (QSH_KeyExchangeWrite(ssl, 1) != 0) {
20007                             ERROR_OUT(MEMORY_E, exit_sske);
20008                         }
20009 
20010                         /* extension type */
20011                         c16toa(TLSX_QUANTUM_SAFE_HYBRID,
20012                                                     args->output + args->idx);
20013                         args->idx += OPAQUE16_LEN;
20014 
20015                         /* write to output and check amount written */
20016                         if (TLSX_QSHPK_Write(ssl->QSH_secret->list,
20017                             args->output + args->idx) >
20018                                                 args->qshSz - OPAQUE16_LEN) {
20019                             ERROR_OUT(MEMORY_E, exit_sske);
20020                         }
20021                     }
20022                 }
20023             #endif
20024 
20025             #if defined(HAVE_ECC)
20026                 if (ssl->specs.kea == ecdhe_psk_kea ||
20027                     ssl->specs.kea == ecc_diffie_hellman_kea) {
20028                     /* Check output to make sure it was set */
20029                     if (args->output) {
20030                         AddHeaders(args->output, args->length,
20031                                                     server_key_exchange, ssl);
20032                     }
20033                     else {
20034                         ERROR_OUT(BUFFER_ERROR, exit_sske);
20035                     }
20036                 }
20037             #endif /* HAVE_ECC */
20038 
20039             #ifdef WOLFSSL_DTLS
20040                 if (IsDtlsNotSctpMode(ssl)) {
20041                     if ((ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz)) != 0) {
20042                         goto exit_sske;
20043                     }
20044                 }
20045 
20046                 if (ssl->options.dtls)
20047                     DtlsSEQIncrement(ssl, CUR_ORDER);
20048             #endif
20049 
20050                 ret = HashOutput(ssl, args->output, args->sendSz, 0);
20051                 if (ret != 0) {
20052                     goto exit_sske;
20053                 }
20054 
20055             #ifdef WOLFSSL_CALLBACKS
20056                 if (ssl->hsInfoOn) {
20057                     AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
20058                 }
20059                 if (ssl->toInfoOn) {
20060                     AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
20061                         args->output, args->sendSz, ssl->heap);
20062                 }
20063             #endif
20064 
20065                 /* Advance state and proceed */
20066                 ssl->options.asyncState = TLS_ASYNC_END;
20067             } /* case TLS_ASYNC_FINALIZE */
20068 
20069             case TLS_ASYNC_END:
20070             {
20071                 ssl->buffers.outputBuffer.length += args->sendSz;
20072                 if (!ssl->options.groupMessages) {
20073                     ret = SendBuffered(ssl);
20074                 }
20075 
20076                 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
20077                 break;
20078             }
20079             default:
20080                 ret = INPUT_CASE_ERROR;
20081         } /* switch(ssl->options.asyncState) */
20082 
20083     exit_sske:
20084 
20085         WOLFSSL_LEAVE("SendServerKeyExchange", ret);
20086 
20087     #ifdef WOLFSSL_ASYNC_CRYPT
20088         /* Handle async operation */
20089         if (ret == WC_PENDING_E)
20090             return ret;
20091     #endif /* WOLFSSL_ASYNC_CRYPT */
20092 
20093         /* Final cleanup */
20094         FreeSskeArgs(ssl, args);
20095         FreeKeyExchange(ssl);
20096 
20097         return ret;
20098     }
20099 
20100 #ifdef HAVE_SERVER_RENEGOTIATION_INFO
20101 
20102     /* search suites for specific one, idx on success, negative on error */
20103     static int FindSuite(Suites* suites, byte first, byte second)
20104     {
20105         int i;
20106 
20107         if (suites == NULL || suites->suiteSz == 0) {
20108             WOLFSSL_MSG("Suites pointer error or suiteSz 0");
20109             return SUITES_ERROR;
20110         }
20111 
20112         for (i = 0; i < suites->suiteSz-1; i += SUITE_LEN) {
20113             if (suites->suites[i]   == first &&
20114                 suites->suites[i+1] == second )
20115                 return i;
20116         }
20117 
20118         return MATCH_SUITE_ERROR;
20119     }
20120 
20121 #endif
20122 
20123     /* Make sure server cert/key are valid for this suite, true on success */
20124     static int VerifyServerSuite(WOLFSSL* ssl, word16 idx)
20125     {
20126         int  haveRSA = !ssl->options.haveStaticECC;
20127         int  havePSK = 0;
20128         byte first;
20129         byte second;
20130 
20131         WOLFSSL_ENTER("VerifyServerSuite");
20132 
20133         if (ssl->suites == NULL) {
20134             WOLFSSL_MSG("Suites pointer error");
20135             return 0;
20136         }
20137 
20138         first   = ssl->suites->suites[idx];
20139         second  = ssl->suites->suites[idx+1];
20140 
20141         #ifndef NO_PSK
20142             havePSK = ssl->options.havePSK;
20143         #endif
20144 
20145         if (ssl->options.haveNTRU)
20146             haveRSA = 0;
20147 
20148         if (CipherRequires(first, second, REQUIRES_RSA)) {
20149             WOLFSSL_MSG("Requires RSA");
20150             if (haveRSA == 0) {
20151                 WOLFSSL_MSG("Don't have RSA");
20152                 return 0;
20153             }
20154         }
20155 
20156         if (CipherRequires(first, second, REQUIRES_DHE)) {
20157             WOLFSSL_MSG("Requires DHE");
20158             if (ssl->options.haveDH == 0) {
20159                 WOLFSSL_MSG("Don't have DHE");
20160                 return 0;
20161             }
20162         }
20163 
20164         if (CipherRequires(first, second, REQUIRES_ECC)) {
20165             WOLFSSL_MSG("Requires ECC");
20166             if (ssl->options.haveECC == 0) {
20167                 WOLFSSL_MSG("Don't have ECC");
20168                 return 0;
20169             }
20170         }
20171 
20172         if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
20173             WOLFSSL_MSG("Requires static ECC");
20174             if (ssl->options.haveStaticECC == 0) {
20175                 WOLFSSL_MSG("Don't have static ECC");
20176                 return 0;
20177             }
20178         }
20179 
20180         if (CipherRequires(first, second, REQUIRES_PSK)) {
20181             WOLFSSL_MSG("Requires PSK");
20182             if (havePSK == 0) {
20183                 WOLFSSL_MSG("Don't have PSK");
20184                 return 0;
20185             }
20186         }
20187 
20188         if (CipherRequires(first, second, REQUIRES_NTRU)) {
20189             WOLFSSL_MSG("Requires NTRU");
20190             if (ssl->options.haveNTRU == 0) {
20191                 WOLFSSL_MSG("Don't have NTRU");
20192                 return 0;
20193             }
20194         }
20195 
20196         if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
20197             WOLFSSL_MSG("Requires RSA Signature");
20198             if (ssl->options.side == WOLFSSL_SERVER_END &&
20199                                            ssl->options.haveECDSAsig == 1) {
20200                 WOLFSSL_MSG("Don't have RSA Signature");
20201                 return 0;
20202             }
20203         }
20204 
20205 #ifdef HAVE_SUPPORTED_CURVES
20206         if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
20207             WOLFSSL_MSG("Don't have matching curves");
20208                 return 0;
20209         }
20210 #endif
20211 
20212         /* ECCDHE is always supported if ECC on */
20213 
20214 #ifdef HAVE_QSH
20215         /* need to negotiate a classic suite in addition to TLS_QSH */
20216         if (first == QSH_BYTE && second == TLS_QSH) {
20217             if (TLSX_SupportExtensions(ssl)) {
20218                 ssl->options.haveQSH = 1; /* matched TLS_QSH */
20219             }
20220             else {
20221                 WOLFSSL_MSG("Version of SSL connection does not support TLS_QSH");
20222             }
20223             return 0;
20224         }
20225 #endif
20226 
20227 #ifdef WOLFSSL_TLS13
20228         if (IsAtLeastTLSv1_3(ssl->version) &&
20229             ssl->options.side == WOLFSSL_SERVER_END) {
20230             /* Try to establish a key share. */
20231             int ret = TLSX_KeyShare_Establish(ssl);
20232             if (ret == KEY_SHARE_ERROR)
20233                 ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
20234             else if (ret != 0)
20235                 return 0;
20236         }
20237 #endif
20238 
20239         return 1;
20240     }
20241 
20242 #ifndef NO_WOLFSSL_SERVER
20243     static int CompareSuites(WOLFSSL* ssl, Suites* peerSuites, word16 i,
20244                              word16 j)
20245     {
20246         if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
20247             ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
20248 
20249             if (VerifyServerSuite(ssl, i)) {
20250                 int result;
20251                 WOLFSSL_MSG("Verified suite validity");
20252                 ssl->options.cipherSuite0 = ssl->suites->suites[i];
20253                 ssl->options.cipherSuite  = ssl->suites->suites[i+1];
20254                 result = SetCipherSpecs(ssl);
20255                 if (result == 0)
20256                     PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
20257                                          peerSuites->hashSigAlgoSz);
20258                 return result;
20259             }
20260             else {
20261                 WOLFSSL_MSG("Could not verify suite validity, continue");
20262             }
20263         }
20264 
20265         return MATCH_SUITE_ERROR;
20266     }
20267 
20268     int MatchSuite(WOLFSSL* ssl, Suites* peerSuites)
20269     {
20270         int ret;
20271         word16 i, j;
20272 
20273         WOLFSSL_ENTER("MatchSuite");
20274 
20275         /* & 0x1 equivalent % 2 */
20276         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
20277             return MATCH_SUITE_ERROR;
20278 
20279         if (ssl->suites == NULL)
20280             return SUITES_ERROR;
20281 
20282         if (!ssl->options.useClientOrder) {
20283             /* Server order */
20284             for (i = 0; i < ssl->suites->suiteSz; i += 2) {
20285                 for (j = 0; j < peerSuites->suiteSz; j += 2) {
20286                     ret = CompareSuites(ssl, peerSuites, i, j);
20287                     if (ret != MATCH_SUITE_ERROR)
20288                         return ret;
20289                 }
20290             }
20291         }
20292         else {
20293             /* Client order */
20294             for (j = 0; j < peerSuites->suiteSz; j += 2) {
20295                 for (i = 0; i < ssl->suites->suiteSz; i += 2) {
20296                     ret = CompareSuites(ssl, peerSuites, i, j);
20297                     if (ret != MATCH_SUITE_ERROR)
20298                         return ret;
20299                 }
20300             }
20301         }
20302 
20303         return MATCH_SUITE_ERROR;
20304     }
20305 #endif
20306 
20307 #ifdef OLD_HELLO_ALLOWED
20308 
20309     /* process old style client hello, deprecate? */
20310     int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
20311                               word32 inSz, word16 sz)
20312     {
20313         word32          idx = *inOutIdx;
20314         word16          sessionSz;
20315         word16          randomSz;
20316         word16          i, j;
20317         ProtocolVersion pv;
20318         Suites          clSuites;
20319 
20320         (void)inSz;
20321         WOLFSSL_MSG("Got old format client hello");
20322 #ifdef WOLFSSL_CALLBACKS
20323         if (ssl->hsInfoOn)
20324             AddPacketName("ClientHello", &ssl->handShakeInfo);
20325         if (ssl->toInfoOn)
20326             AddLateName("ClientHello", &ssl->timeoutInfo);
20327 #endif
20328 
20329         /* manually hash input since different format */
20330 #ifndef NO_OLD_TLS
20331 #ifndef NO_MD5
20332         wc_Md5Update(&ssl->hsHashes->hashMd5, input + idx, sz);
20333 #endif
20334 #ifndef NO_SHA
20335         wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz);
20336 #endif
20337 #endif
20338 #ifndef NO_SHA256
20339         if (IsAtLeastTLSv1_2(ssl)) {
20340             int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256,
20341                                          input + idx, sz);
20342             if (shaRet != 0)
20343                 return shaRet;
20344         }
20345 #endif
20346 
20347         /* does this value mean client_hello? */
20348         idx++;
20349 
20350         /* version */
20351         pv.major = input[idx++];
20352         pv.minor = input[idx++];
20353         ssl->chVersion = pv;  /* store */
20354 
20355         if (ssl->version.minor > pv.minor) {
20356             byte haveRSA = 0;
20357             byte havePSK = 0;
20358             if (!ssl->options.downgrade) {
20359                 WOLFSSL_MSG("Client trying to connect with lesser version");
20360                 return VERSION_ERROR;
20361             }
20362             if (pv.minor < ssl->options.minDowngrade) {
20363                 WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
20364                 return VERSION_ERROR;
20365             }
20366             if (pv.minor == SSLv3_MINOR) {
20367                 /* turn off tls */
20368                 WOLFSSL_MSG("\tdowngrading to SSLv3");
20369                 ssl->options.tls    = 0;
20370                 ssl->options.tls1_1 = 0;
20371                 ssl->version.minor  = SSLv3_MINOR;
20372             }
20373             else if (pv.minor == TLSv1_MINOR) {
20374                 WOLFSSL_MSG("\tdowngrading to TLSv1");
20375                 /* turn off tls 1.1+ */
20376                 ssl->options.tls1_1 = 0;
20377                 ssl->version.minor  = TLSv1_MINOR;
20378             }
20379             else if (pv.minor == TLSv1_1_MINOR) {
20380                 WOLFSSL_MSG("\tdowngrading to TLSv1.1");
20381                 ssl->version.minor  = TLSv1_1_MINOR;
20382             }
20383             else if (pv.minor == TLSv1_2_MINOR) {
20384                 WOLFSSL_MSG("    downgrading to TLSv1.2");
20385                 ssl->version.minor  = TLSv1_2_MINOR;
20386             }
20387 #ifndef NO_RSA
20388             haveRSA = 1;
20389 #endif
20390 #ifndef NO_PSK
20391             havePSK = ssl->options.havePSK;
20392 #endif
20393 
20394             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
20395                        ssl->options.haveDH, ssl->options.haveNTRU,
20396                        ssl->options.haveECDSAsig, ssl->options.haveECC,
20397                        ssl->options.haveStaticECC, ssl->options.side);
20398         }
20399 
20400         /* suite size */
20401         ato16(&input[idx], &clSuites.suiteSz);
20402         idx += OPAQUE16_LEN;
20403 
20404         if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
20405             return BUFFER_ERROR;
20406         clSuites.hashSigAlgoSz = 0;
20407 
20408         /* session size */
20409         ato16(&input[idx], &sessionSz);
20410         idx += OPAQUE16_LEN;
20411 
20412         if (sessionSz > ID_LEN)
20413             return BUFFER_ERROR;
20414 
20415         /* random size */
20416         ato16(&input[idx], &randomSz);
20417         idx += OPAQUE16_LEN;
20418 
20419         if (randomSz > RAN_LEN)
20420             return BUFFER_ERROR;
20421 
20422         /* suites */
20423         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
20424             byte first = input[idx++];
20425             if (!first) { /* implicit: skip sslv2 type */
20426                 XMEMCPY(&clSuites.suites[j], &input[idx], SUITE_LEN);
20427                 j += SUITE_LEN;
20428             }
20429             idx += SUITE_LEN;
20430         }
20431         clSuites.suiteSz = j;
20432 
20433         /* session id */
20434         if (sessionSz) {
20435             XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
20436             ssl->arrays->sessionIDSz = (byte)sessionSz;
20437             idx += sessionSz;
20438             ssl->options.resuming = 1;
20439         }
20440 
20441         /* random */
20442         if (randomSz < RAN_LEN)
20443             XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
20444         XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
20445                randomSz);
20446         idx += randomSz;
20447 
20448         if (ssl->options.usingCompression)
20449             ssl->options.usingCompression = 0;  /* turn off */
20450 
20451         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
20452         *inOutIdx = idx;
20453 
20454         ssl->options.haveSessionId = 1;
20455         /* DoClientHello uses same resume code */
20456         if (ssl->options.resuming) {  /* let's try */
20457             int ret = -1;
20458             WOLFSSL_SESSION* session = GetSession(ssl,
20459                                                   ssl->arrays->masterSecret, 1);
20460             #ifdef HAVE_SESSION_TICKET
20461                 if (ssl->options.useTicket == 1) {
20462                     session = &ssl->session;
20463                 }
20464             #endif
20465 
20466             if (!session) {
20467                 WOLFSSL_MSG("Session lookup for resume failed");
20468                 ssl->options.resuming = 0;
20469             } else {
20470             #ifdef HAVE_EXT_CACHE
20471                 wolfSSL_SESSION_free(session);
20472             #endif
20473                 if (MatchSuite(ssl, &clSuites) < 0) {
20474                     WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
20475                     return UNSUPPORTED_SUITE;
20476                 }
20477 
20478                 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
20479                                                                        RAN_LEN);
20480                 if (ret != 0)
20481                     return ret;
20482 
20483                 #ifdef NO_OLD_TLS
20484                     ret = DeriveTlsKeys(ssl);
20485                 #else
20486                     #ifndef NO_TLS
20487                         if (ssl->options.tls)
20488                             ret = DeriveTlsKeys(ssl);
20489                     #endif
20490                         if (!ssl->options.tls)
20491                             ret = DeriveKeys(ssl);
20492                 #endif
20493                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
20494 
20495                 return ret;
20496             }
20497         }
20498 
20499         return MatchSuite(ssl, &clSuites);
20500     }
20501 
20502 #endif /* OLD_HELLO_ALLOWED */
20503 
20504 
20505     int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
20506                              word32 helloSz)
20507     {
20508         byte            b;
20509         byte            bogusID = 0;   /* flag for a bogus session id */
20510         ProtocolVersion pv;
20511         Suites          clSuites;
20512         word32          i = *inOutIdx;
20513         word32          begin = i;
20514 #ifdef WOLFSSL_DTLS
20515         Hmac            cookieHmac;
20516         byte            peerCookie[MAX_COOKIE_LEN];
20517         byte            peerCookieSz = 0;
20518         byte            cookieType;
20519         byte            cookieSz = 0;
20520 
20521         XMEMSET(&cookieHmac, 0, sizeof(Hmac));
20522 #endif /* WOLFSSL_DTLS */
20523 
20524 #ifdef WOLFSSL_CALLBACKS
20525         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
20526         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
20527 #endif
20528 
20529         /* protocol version, random and session id length check */
20530         if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
20531             return BUFFER_ERROR;
20532 
20533         /* protocol version */
20534         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
20535         ssl->chVersion = pv;   /* store */
20536 #ifdef WOLFSSL_DTLS
20537         if (IsDtlsNotSctpMode(ssl)) {
20538             int ret;
20539             #if defined(NO_SHA) && defined(NO_SHA256)
20540                 #error "DTLS needs either SHA or SHA-256"
20541             #endif /* NO_SHA && NO_SHA256 */
20542 
20543             #if !defined(NO_SHA) && defined(NO_SHA256)
20544                 cookieType = SHA;
20545                 cookieSz = SHA_DIGEST_SIZE;
20546             #endif /* NO_SHA */
20547             #ifndef NO_SHA256
20548                 cookieType = SHA256;
20549                 cookieSz = SHA256_DIGEST_SIZE;
20550             #endif /* NO_SHA256 */
20551             ret = wc_HmacSetKey(&cookieHmac, cookieType,
20552                                 ssl->buffers.dtlsCookieSecret.buffer,
20553                                 ssl->buffers.dtlsCookieSecret.length);
20554             if (ret != 0) return ret;
20555             ret = wc_HmacUpdate(&cookieHmac,
20556                                 (const byte*)ssl->buffers.dtlsCtx.peer.sa,
20557                                 ssl->buffers.dtlsCtx.peer.sz);
20558             if (ret != 0) return ret;
20559             ret = wc_HmacUpdate(&cookieHmac, input + i, OPAQUE16_LEN);
20560             if (ret != 0) return ret;
20561         }
20562 #endif /* WOLFSSL_DTLS */
20563         i += OPAQUE16_LEN;
20564 
20565         if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
20566             (ssl->options.dtls && ssl->version.minor != DTLS_MINOR
20567              && ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
20568              && pv.minor != DTLSv1_2_MINOR)) {
20569 
20570             word16 haveRSA = 0;
20571             word16 havePSK = 0;
20572 
20573             if (!ssl->options.downgrade) {
20574                 WOLFSSL_MSG("Client trying to connect with lesser version");
20575                 return VERSION_ERROR;
20576             }
20577             if (pv.minor < ssl->options.minDowngrade) {
20578                 WOLFSSL_MSG("\tversion below minimum allowed, fatal error");
20579                 return VERSION_ERROR;
20580             }
20581 
20582             if (pv.minor == SSLv3_MINOR) {
20583                 /* turn off tls */
20584                 WOLFSSL_MSG("\tdowngrading to SSLv3");
20585                 ssl->options.tls    = 0;
20586                 ssl->options.tls1_1 = 0;
20587                 ssl->version.minor  = SSLv3_MINOR;
20588             }
20589             else if (pv.minor == TLSv1_MINOR) {
20590                 /* turn off tls 1.1+ */
20591                 WOLFSSL_MSG("\tdowngrading to TLSv1");
20592                 ssl->options.tls1_1 = 0;
20593                 ssl->version.minor  = TLSv1_MINOR;
20594             }
20595             else if (pv.minor == TLSv1_1_MINOR) {
20596                 WOLFSSL_MSG("\tdowngrading to TLSv1.1");
20597                 ssl->version.minor  = TLSv1_1_MINOR;
20598             }
20599             else if (pv.minor == TLSv1_2_MINOR) {
20600                 WOLFSSL_MSG("    downgrading to TLSv1.2");
20601                 ssl->version.minor  = TLSv1_2_MINOR;
20602             }
20603 #ifndef NO_RSA
20604             haveRSA = 1;
20605 #endif
20606 #ifndef NO_PSK
20607             havePSK = ssl->options.havePSK;
20608 #endif
20609             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
20610                        ssl->options.haveDH, ssl->options.haveNTRU,
20611                        ssl->options.haveECDSAsig, ssl->options.haveECC,
20612                        ssl->options.haveStaticECC, ssl->options.side);
20613         }
20614 
20615         /* random */
20616         XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
20617 #ifdef WOLFSSL_DTLS
20618         if (IsDtlsNotSctpMode(ssl)) {
20619             int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
20620             if (ret != 0) return ret;
20621         }
20622 #endif /* WOLFSSL_DTLS */
20623         i += RAN_LEN;
20624 
20625 #ifdef SHOW_SECRETS
20626         {
20627             int j;
20628             printf("client random: ");
20629             for (j = 0; j < RAN_LEN; j++)
20630                 printf("%02x", ssl->arrays->clientRandom[j]);
20631             printf("\n");
20632         }
20633 #endif
20634 
20635         /* session id */
20636         b = input[i++];
20637 
20638 #ifdef HAVE_SESSION_TICKET
20639         if (b > 0 && b < ID_LEN) {
20640             bogusID = 1;
20641             WOLFSSL_MSG("Client sent bogus session id, let's allow for echo");
20642         }
20643 #endif
20644 
20645         if (b == ID_LEN || bogusID) {
20646             if ((i - begin) + b > helloSz)
20647                 return BUFFER_ERROR;
20648 
20649             XMEMCPY(ssl->arrays->sessionID, input + i, b);
20650 #ifdef WOLFSSL_DTLS
20651             if (IsDtlsNotSctpMode(ssl)) {
20652                 int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
20653                 if (ret != 0) return ret;
20654             }
20655 #endif /* WOLFSSL_DTLS */
20656             ssl->arrays->sessionIDSz = b;
20657             i += b;
20658             ssl->options.resuming = 1; /* client wants to resume */
20659             WOLFSSL_MSG("Client wants to resume session");
20660         }
20661         else if (b) {
20662             WOLFSSL_MSG("Invalid session ID size");
20663             return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
20664         }
20665 
20666         #ifdef WOLFSSL_DTLS
20667             /* cookie */
20668             if (ssl->options.dtls) {
20669 
20670                 if ((i - begin) + OPAQUE8_LEN > helloSz)
20671                     return BUFFER_ERROR;
20672 
20673                 peerCookieSz = input[i++];
20674 
20675                 if (peerCookieSz) {
20676                     if (peerCookieSz > MAX_COOKIE_LEN)
20677                         return BUFFER_ERROR;
20678 
20679                     if ((i - begin) + peerCookieSz > helloSz)
20680                         return BUFFER_ERROR;
20681 
20682                     XMEMCPY(peerCookie, input + i, peerCookieSz);
20683 
20684                     i += peerCookieSz;
20685                 }
20686             }
20687         #endif
20688 
20689         /* suites */
20690         if ((i - begin) + OPAQUE16_LEN > helloSz)
20691             return BUFFER_ERROR;
20692 
20693         ato16(&input[i], &clSuites.suiteSz);
20694         i += OPAQUE16_LEN;
20695 
20696         /* suites and compression length check */
20697         if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
20698             return BUFFER_ERROR;
20699 
20700         if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
20701             return BUFFER_ERROR;
20702 
20703         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
20704 
20705 #ifdef HAVE_SERVER_RENEGOTIATION_INFO
20706         /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */
20707         if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) {
20708             int ret = 0;
20709 
20710             ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap);
20711             if (ret != SSL_SUCCESS)
20712                 return ret;
20713         }
20714 #endif /* HAVE_SERVER_RENEGOTIATION_INFO */
20715 
20716 #ifdef WOLFSSL_DTLS
20717         if (IsDtlsNotSctpMode(ssl)) {
20718             int ret = wc_HmacUpdate(&cookieHmac,
20719                                     input + i - OPAQUE16_LEN,
20720                                     clSuites.suiteSz + OPAQUE16_LEN);
20721             if (ret != 0) return ret;
20722         }
20723 #endif /* WOLFSSL_DTLS */
20724         i += clSuites.suiteSz;
20725         clSuites.hashSigAlgoSz = 0;
20726 
20727         /* compression length */
20728         b = input[i++];
20729 
20730         if ((i - begin) + b > helloSz)
20731             return BUFFER_ERROR;
20732 
20733         if (b == 0) {
20734             WOLFSSL_MSG("No compression types in list");
20735             return COMPRESSION_ERROR;
20736         }
20737 
20738 #ifdef WOLFSSL_DTLS
20739         if (IsDtlsNotSctpMode(ssl)) {
20740             byte newCookie[MAX_COOKIE_LEN];
20741             int ret;
20742 
20743             ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
20744             if (ret != 0) return ret;
20745             ret = wc_HmacFinal(&cookieHmac, newCookie);
20746             if (ret != 0) return ret;
20747 
20748             /* If a cookie callback is set, call it to overwrite the cookie.
20749              * This should be deprecated. The code now calculates the cookie
20750              * using an HMAC as expected. */
20751             if (ssl->ctx->CBIOCookie != NULL &&
20752                 ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz,
20753                                              ssl->IOCB_CookieCtx) != cookieSz) {
20754                 return COOKIE_ERROR;
20755             }
20756 
20757             /* Check the cookie, see if we progress the state machine. */
20758             if (peerCookieSz != cookieSz ||
20759                 XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
20760 
20761                 /* Send newCookie to client in a HelloVerifyRequest message
20762                  * and let the state machine alone. */
20763                 ssl->msgsReceived.got_client_hello = 0;
20764                 ssl->keys.dtls_handshake_number = 0;
20765                 ssl->keys.dtls_expected_peer_handshake_number = 0;
20766                 *inOutIdx += helloSz;
20767                 return SendHelloVerifyRequest(ssl, newCookie, cookieSz);
20768             }
20769 
20770             /* This was skipped in the DTLS case so we could handle the hello
20771              * verify request. */
20772             ret = HashInput(ssl, input + *inOutIdx, helloSz);
20773             if (ret != 0) return ret;
20774         }
20775 #endif /* WOLFSSL_DTLS */
20776 
20777         {
20778             /* copmression match types */
20779             int matchNo = 0;
20780             int matchZlib = 0;
20781 
20782             while (b--) {
20783                 byte comp = input[i++];
20784 
20785                 if (comp == NO_COMPRESSION) {
20786                     matchNo = 1;
20787                 }
20788                 if (comp == ZLIB_COMPRESSION) {
20789                     matchZlib = 1;
20790                 }
20791             }
20792 
20793             if (ssl->options.usingCompression == 0 && matchNo) {
20794                 WOLFSSL_MSG("Matched No Compression");
20795             } else if (ssl->options.usingCompression && matchZlib) {
20796                 WOLFSSL_MSG("Matched zlib Compression");
20797             } else if (ssl->options.usingCompression && matchNo) {
20798                 WOLFSSL_MSG("Could only match no compression, turning off");
20799                 ssl->options.usingCompression = 0;  /* turn off */
20800             } else {
20801                 WOLFSSL_MSG("Could not match compression");
20802                 return COMPRESSION_ERROR;
20803             }
20804         }
20805 
20806         *inOutIdx = i;
20807 
20808         /* tls extensions */
20809         if ((i - begin) < helloSz) {
20810 #ifdef HAVE_TLS_EXTENSIONS
20811         #ifdef HAVE_QSH
20812             QSH_Init(ssl);
20813         #endif
20814             if (TLSX_SupportExtensions(ssl)) {
20815                 int ret = 0;
20816 #else
20817             if (IsAtLeastTLSv1_2(ssl)) {
20818 #endif
20819                 /* Process the hello extension. Skip unsupported. */
20820                 word16 totalExtSz;
20821 
20822 #ifdef HAVE_TLS_EXTENSIONS
20823                 /* auto populate extensions supported unless user defined */
20824                 if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
20825                     return ret;
20826 #endif
20827 
20828                 if ((i - begin) + OPAQUE16_LEN > helloSz)
20829                     return BUFFER_ERROR;
20830 
20831                 ato16(&input[i], &totalExtSz);
20832                 i += OPAQUE16_LEN;
20833 
20834                 if ((i - begin) + totalExtSz > helloSz)
20835                     return BUFFER_ERROR;
20836 
20837 #ifdef HAVE_TLS_EXTENSIONS
20838                 /* tls extensions */
20839                 if ((ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz,
20840                                       client_hello, &clSuites)))
20841                     return ret;
20842 #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
20843                 if((ret=SNI_Callback(ssl)))
20844                     return ret;
20845                 ssl->options.side = WOLFSSL_SERVER_END;
20846 #endif /*HAVE_STUNNEL*/
20847 
20848                 i += totalExtSz;
20849 #else
20850                 while (totalExtSz) {
20851                     word16 extId, extSz;
20852 
20853                     if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
20854                         return BUFFER_ERROR;
20855 
20856                     ato16(&input[i], &extId);
20857                     i += OPAQUE16_LEN;
20858                     ato16(&input[i], &extSz);
20859                     i += OPAQUE16_LEN;
20860 
20861                     if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
20862                         return BUFFER_ERROR;
20863 
20864                     if (extId == HELLO_EXT_SIG_ALGO) {
20865                         ato16(&input[i], &clSuites.hashSigAlgoSz);
20866                         i += OPAQUE16_LEN;
20867 
20868                         if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
20869                             return BUFFER_ERROR;
20870 
20871                         XMEMCPY(clSuites.hashSigAlgo, &input[i],
20872                             min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
20873                         i += clSuites.hashSigAlgoSz;
20874 
20875                         if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
20876                             clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
20877                     }
20878 #ifdef HAVE_EXTENDED_MASTER
20879                     else if (extId == HELLO_EXT_EXTMS)
20880                         ssl->options.haveEMS = 1;
20881 #endif
20882                     else
20883                         i += extSz;
20884 
20885                     totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
20886                 }
20887 #endif
20888                 *inOutIdx = i;
20889             }
20890             else
20891                 *inOutIdx = begin + helloSz; /* skip extensions */
20892         }
20893 
20894         ssl->options.clientState   = CLIENT_HELLO_COMPLETE;
20895         ssl->options.haveSessionId = 1;
20896 
20897         /* ProcessOld uses same resume code */
20898         if (ssl->options.resuming) {
20899             int ret = -1;
20900             WOLFSSL_SESSION* session = GetSession(ssl,
20901                                                   ssl->arrays->masterSecret, 1);
20902             #ifdef HAVE_SESSION_TICKET
20903                 if (ssl->options.useTicket == 1) {
20904                     session = &ssl->session;
20905                 } else if (bogusID == 1 && ssl->options.rejectTicket == 0) {
20906                     WOLFSSL_MSG("Bogus session ID without session ticket");
20907                     return BUFFER_ERROR;
20908                 }
20909             #endif
20910 
20911             if (!session) {
20912                 WOLFSSL_MSG("Session lookup for resume failed");
20913                 ssl->options.resuming = 0;
20914             }
20915             else if (session->haveEMS != ssl->options.haveEMS) {
20916                 /* RFC 7627, 5.3, server-side */
20917                 /* if old sess didn't have EMS, but new does, full handshake */
20918                 if (!session->haveEMS && ssl->options.haveEMS) {
20919                     WOLFSSL_MSG("Attempting to resume a session that didn't "
20920                                 "use EMS with a new session with EMS. Do full "
20921                                 "handshake.");
20922                     ssl->options.resuming = 0;
20923                 }
20924                 /* if old sess used EMS, but new doesn't, MUST abort */
20925                 else if (session->haveEMS && !ssl->options.haveEMS) {
20926                     WOLFSSL_MSG("Trying to resume a session with EMS without "
20927                                 "using EMS");
20928                     return EXT_MASTER_SECRET_NEEDED_E;
20929                 }
20930 #ifdef HAVE_EXT_CACHE
20931                 wolfSSL_SESSION_free(session);
20932 #endif
20933             }
20934             else {
20935 #ifdef HAVE_EXT_CACHE
20936                 wolfSSL_SESSION_free(session);
20937 #endif
20938                 if (MatchSuite(ssl, &clSuites) < 0) {
20939                     WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
20940                     return UNSUPPORTED_SUITE;
20941                 }
20942 
20943                 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
20944                                                                        RAN_LEN);
20945                 if (ret != 0)
20946                     return ret;
20947 
20948                 #ifdef NO_OLD_TLS
20949                     ret = DeriveTlsKeys(ssl);
20950                 #else
20951                     #ifndef NO_TLS
20952                         if (ssl->options.tls)
20953                             ret = DeriveTlsKeys(ssl);
20954                     #endif
20955                         if (!ssl->options.tls)
20956                             ret = DeriveKeys(ssl);
20957                 #endif
20958                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
20959 
20960                 return ret;
20961             }
20962         }
20963         return MatchSuite(ssl, &clSuites);
20964     }
20965 
20966 
20967 #if !defined(NO_RSA) || defined(HAVE_ECC)
20968 
20969     typedef struct DcvArgs {
20970         byte*  output; /* not allocated */
20971         word32 sendSz;
20972         word16 sz;
20973         word32 sigSz;
20974         word32 idx;
20975         word32 begin;
20976         byte   hashAlgo;
20977         byte   sigAlgo;
20978     } DcvArgs;
20979 
20980     static void FreeDcvArgs(WOLFSSL* ssl, void* pArgs)
20981     {
20982         DcvArgs* args = (DcvArgs*)pArgs;
20983 
20984         (void)ssl;
20985         (void)args;
20986     }
20987 
20988     static int DoCertificateVerify(WOLFSSL* ssl, byte* input,
20989                                 word32* inOutIdx, word32 size)
20990     {
20991         int ret = 0;
20992     #ifdef WOLFSSL_ASYNC_CRYPT
20993         DcvArgs* args = (DcvArgs*)ssl->async.args;
20994         typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
20995         (void)sizeof(args_test);
20996     #else
20997         DcvArgs  args[1];
20998     #endif
20999 
21000         WOLFSSL_ENTER("DoCertificateVerify");
21001 
21002     #ifdef WOLFSSL_ASYNC_CRYPT
21003         ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
21004         if (ret != WC_NOT_PENDING_E) {
21005             /* Check for error */
21006             if (ret < 0)
21007                 goto exit_dcv;
21008         }
21009         else
21010     #endif
21011         {
21012             /* Reset state */
21013             ret = 0;
21014             ssl->options.asyncState = TLS_ASYNC_BEGIN;
21015             XMEMSET(args, 0, sizeof(DcvArgs));
21016             args->hashAlgo = sha_mac;
21017             args->sigAlgo = anonymous_sa_algo;
21018             args->idx = *inOutIdx;
21019             args->begin = *inOutIdx;
21020         #ifdef WOLFSSL_ASYNC_CRYPT
21021             ssl->async.freeArgs = FreeDcvArgs;
21022         #endif
21023         }
21024 
21025         switch(ssl->options.asyncState)
21026         {
21027             case TLS_ASYNC_BEGIN:
21028             {
21029             #ifdef WOLFSSL_CALLBACKS
21030                 if (ssl->hsInfoOn)
21031                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
21032                 if (ssl->toInfoOn)
21033                     AddLateName("CertificateVerify", &ssl->timeoutInfo);
21034             #endif
21035 
21036                 /* Advance state and proceed */
21037                 ssl->options.asyncState = TLS_ASYNC_BUILD;
21038             } /* case TLS_ASYNC_BEGIN */
21039 
21040             case TLS_ASYNC_BUILD:
21041             {
21042                 if (IsAtLeastTLSv1_2(ssl)) {
21043                     if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > size) {
21044                         ERROR_OUT(BUFFER_ERROR, exit_dcv);
21045                     }
21046 
21047                     args->hashAlgo = input[args->idx++];
21048                     args->sigAlgo  = input[args->idx++];
21049                 }
21050 
21051                 if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
21052                     ERROR_OUT(BUFFER_ERROR, exit_dcv);
21053                 }
21054 
21055                 ato16(input + args->idx, &args->sz);
21056                 args->idx += OPAQUE16_LEN;
21057 
21058                 if ((args->idx - args->begin) + args->sz > size ||
21059                                                     args->sz > ENCRYPT_LEN) {
21060                     ERROR_OUT(BUFFER_ERROR, exit_dcv);
21061                 }
21062 
21063             #ifdef HAVE_ECC
21064                 if (ssl->peerEccDsaKeyPresent) {
21065 
21066                     WOLFSSL_MSG("Doing ECC peer cert verify");
21067 
21068                 /* make sure a default is defined */
21069                 #if !defined(NO_SHA)
21070                     ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha;
21071                     ssl->buffers.digest.length = SHA_DIGEST_SIZE;
21072                 #elif !defined(NO_SHA256)
21073                     ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
21074                     ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
21075                 #elif defined(WOLFSSL_SHA384)
21076                     ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384;
21077                     ssl->buffers.digest.length = SHA384_DIGEST_SIZE;
21078                 #elif defined(WOLFSSL_SHA512)
21079                     ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512;
21080                     ssl->buffers.digest.length = SHA512_DIGEST_SIZE;
21081                 #else
21082                     #error No digest enabled for ECC sig verify
21083                 #endif
21084 
21085                     if (IsAtLeastTLSv1_2(ssl)) {
21086                         if (args->sigAlgo != ecc_dsa_sa_algo) {
21087                             WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
21088                         }
21089 
21090                         switch (args->hashAlgo) {
21091                             case sha256_mac:
21092                             #ifndef NO_SHA256
21093                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
21094                                 ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
21095                             #endif
21096                                 break;
21097                             case sha384_mac:
21098                             #ifdef WOLFSSL_SHA384
21099                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384;
21100                                 ssl->buffers.digest.length = SHA384_DIGEST_SIZE;
21101                             #endif
21102                                 break;
21103                             case sha512_mac:
21104                             #ifdef WOLFSSL_SHA512
21105                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512;
21106                                 ssl->buffers.digest.length = SHA512_DIGEST_SIZE;
21107                             #endif
21108                                 break;
21109                         }
21110                     }
21111                 }
21112             #endif /* HAVE_ECC */
21113 
21114                 /* Advance state and proceed */
21115                 ssl->options.asyncState = TLS_ASYNC_DO;
21116             } /* case TLS_ASYNC_BUILD */
21117 
21118             case TLS_ASYNC_DO:
21119             {
21120             #ifndef NO_RSA
21121                 if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
21122                     WOLFSSL_MSG("Doing RSA peer cert verify");
21123 
21124                     ret = RsaVerify(ssl,
21125                         input + args->idx,
21126                         args->sz,
21127                         &args->output,
21128                         rsa_sa_algo, no_mac,
21129                         ssl->peerRsaKey,
21130                     #ifdef HAVE_PK_CALLBACKS
21131                         ssl->buffers.peerRsaKey.buffer,
21132                         ssl->buffers.peerRsaKey.length,
21133                         ssl->RsaVerifyCtx
21134                     #else
21135                         NULL, 0, NULL
21136                     #endif
21137                     );
21138                     if (ret >= 0) {
21139                         args->sendSz = ret;
21140                         ret = 0;
21141                     }
21142                 }
21143             #endif /* !NO_RSA */
21144             #ifdef HAVE_ECC
21145                 if (ssl->peerEccDsaKeyPresent) {
21146                     WOLFSSL_MSG("Doing ECC peer cert verify");
21147 
21148                     ret = EccVerify(ssl,
21149                         input + args->idx, args->sz,
21150                         ssl->buffers.digest.buffer, ssl->buffers.digest.length,
21151                         ssl->peerEccDsaKey,
21152                     #ifdef HAVE_PK_CALLBACKS
21153                         ssl->buffers.peerEccDsaKey.buffer,
21154                         ssl->buffers.peerEccDsaKey.length,
21155                         ssl->EccVerifyCtx
21156                     #else
21157                         NULL, 0, NULL
21158                     #endif
21159                     );
21160                 }
21161             #endif /* HAVE_ECC */
21162 
21163                 /* Check for error */
21164                 if (ret != 0) {
21165                     goto exit_dcv;
21166                 }
21167 
21168                 /* Advance state and proceed */
21169                 ssl->options.asyncState = TLS_ASYNC_VERIFY;
21170             } /* case TLS_ASYNC_DO */
21171 
21172             case TLS_ASYNC_VERIFY:
21173             {
21174             #ifndef NO_RSA
21175                 if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
21176                     if (IsAtLeastTLSv1_2(ssl)) {
21177                     #ifdef WOLFSSL_SMALL_STACK
21178                         byte* encodedSig = NULL;
21179                     #else
21180                         byte  encodedSig[MAX_ENCODED_SIG_SZ];
21181                     #endif
21182                         int   typeH = SHAh;
21183 
21184                     /* make sure a default is defined */
21185                     #if !defined(NO_SHA)
21186                         ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha;
21187                         ssl->buffers.digest.length = SHA_DIGEST_SIZE;
21188                     #elif !defined(NO_SHA256)
21189                         ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
21190                         ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
21191                     #elif defined(WOLFSSL_SHA384)
21192                         ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384;
21193                         ssl->buffers.digest.length = SHA384_DIGEST_SIZE;
21194                     #elif defined(WOLFSSL_SHA512)
21195                         ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512;
21196                         ssl->buffers.digest.length = SHA512_DIGEST_SIZE;
21197                     #else
21198                         #error No digest enabled for RSA sig verify
21199                     #endif
21200 
21201                     #ifdef WOLFSSL_SMALL_STACK
21202                         encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
21203                                             ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
21204                         if (encodedSig == NULL) {
21205                             ERROR_OUT(MEMORY_E, exit_dcv);
21206                         }
21207                     #endif
21208 
21209                         if (args->sigAlgo != rsa_sa_algo) {
21210                             WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
21211                         }
21212 
21213                         switch (args->hashAlgo) {
21214                             case sha256_mac:
21215                             #ifndef NO_SHA256
21216                                 typeH    = SHA256h;
21217                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256;
21218                                 ssl->buffers.digest.length = SHA256_DIGEST_SIZE;
21219                             #endif /* !NO_SHA256 */
21220                                 break;
21221                             case sha384_mac:
21222                             #ifdef WOLFSSL_SHA384
21223                                 typeH    = SHA384h;
21224                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384;
21225                                 ssl->buffers.digest.length = SHA384_DIGEST_SIZE;
21226                             #endif /* WOLFSSL_SHA384 */
21227                                 break;
21228                             case sha512_mac:
21229                             #ifdef WOLFSSL_SHA512
21230                                 typeH    = SHA512h;
21231                                 ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512;
21232                                 ssl->buffers.digest.length = SHA512_DIGEST_SIZE;
21233                             #endif /* WOLFSSL_SHA512 */
21234                                 break;
21235                         } /* switch */
21236 
21237                         args->sigSz = wc_EncodeSignature(encodedSig,
21238                             ssl->buffers.digest.buffer,
21239                             ssl->buffers.digest.length, typeH);
21240 
21241                         if (args->sendSz != args->sigSz || !args->output ||
21242                             XMEMCMP(args->output, encodedSig,
21243                                 min(args->sigSz, MAX_ENCODED_SIG_SZ)) != 0) {
21244                             ret = VERIFY_CERT_ERROR;
21245                         }
21246 
21247                     #ifdef WOLFSSL_SMALL_STACK
21248                         XFREE(encodedSig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
21249                     #endif
21250                     }
21251                     else {
21252                         if (args->sendSz != FINISHED_SZ || !args->output ||
21253                             XMEMCMP(args->output,
21254                                 &ssl->hsHashes->certHashes, FINISHED_SZ) != 0) {
21255                             ret = VERIFY_CERT_ERROR;
21256                         }
21257                     }
21258                 }
21259             #endif /* !NO_RSA */
21260 
21261                 /* Advance state and proceed */
21262                 ssl->options.asyncState = TLS_ASYNC_FINALIZE;
21263             } /* case TLS_ASYNC_VERIFY */
21264 
21265             case TLS_ASYNC_FINALIZE:
21266             {
21267                 ssl->options.havePeerVerify = 1;
21268 
21269                 /* Set final index */
21270                 args->idx += args->sz;
21271                 *inOutIdx = args->idx;
21272 
21273                 /* Advance state and proceed */
21274                 ssl->options.asyncState = TLS_ASYNC_END;
21275             } /* case TLS_ASYNC_FINALIZE */
21276 
21277             case TLS_ASYNC_END:
21278             {
21279                 break;
21280             }
21281             default:
21282                 ret = INPUT_CASE_ERROR;
21283         } /* switch(ssl->options.asyncState) */
21284 
21285     exit_dcv:
21286 
21287         WOLFSSL_LEAVE("DoCertificateVerify", ret);
21288 
21289     #ifdef WOLFSSL_ASYNC_CRYPT
21290         /* Handle async operation */
21291         if (ret == WC_PENDING_E) {
21292             /* Mark message as not recevied so it can process again */
21293             ssl->msgsReceived.got_certificate_verify = 0;
21294 
21295             return ret;
21296         }
21297     #endif /* WOLFSSL_ASYNC_CRYPT */
21298 
21299         /* Digest is not allocated, so do this to prevent free */
21300         ssl->buffers.digest.buffer = NULL;
21301         ssl->buffers.digest.length = 0;
21302 
21303         /* Final cleanup */
21304         FreeDcvArgs(ssl, args);
21305         FreeKeyExchange(ssl);
21306 
21307         return ret;
21308     }
21309 
21310 #endif /* !NO_RSA || HAVE_ECC */
21311 
21312     int SendServerHelloDone(WOLFSSL* ssl)
21313     {
21314         byte* output;
21315         int   sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
21316         int   ret;
21317 
21318     #ifdef WOLFSSL_DTLS
21319         if (ssl->options.dtls)
21320             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
21321     #endif
21322 
21323         /* check for available size */
21324         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
21325             return ret;
21326 
21327         /* get output buffer */
21328         output = ssl->buffers.outputBuffer.buffer +
21329                  ssl->buffers.outputBuffer.length;
21330 
21331         AddHeaders(output, 0, server_hello_done, ssl);
21332 
21333     #ifdef WOLFSSL_DTLS
21334         if (IsDtlsNotSctpMode(ssl)) {
21335             if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
21336                 return 0;
21337         }
21338 
21339         if (ssl->options.dtls)
21340             DtlsSEQIncrement(ssl, CUR_ORDER);
21341     #endif
21342 
21343         ret = HashOutput(ssl, output, sendSz, 0);
21344             if (ret != 0)
21345                 return ret;
21346 
21347     #ifdef WOLFSSL_CALLBACKS
21348         if (ssl->hsInfoOn)
21349             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
21350         if (ssl->toInfoOn)
21351             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
21352                           ssl->heap);
21353     #endif
21354         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
21355 
21356         ssl->buffers.outputBuffer.length += sendSz;
21357 
21358         return SendBuffered(ssl);
21359     }
21360 
21361 
21362 #ifdef HAVE_SESSION_TICKET
21363 
21364 #define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
21365                 WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
21366 #define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
21367 
21368     /* our ticket format */
21369     typedef struct InternalTicket {
21370         ProtocolVersion pv;                    /* version when ticket created */
21371         byte            suite[SUITE_LEN];      /* cipher suite when created */
21372         byte            msecret[SECRET_LEN];   /* master secret */
21373         word32          timestamp;             /* born on */
21374         word16          haveEMS;               /* have extended master secret */
21375 #ifdef WOLFSSL_TLS13
21376         word32          ageAdd;                /* Obfuscation of age */
21377         byte            namedGroup;            /* Named group used */
21378 #endif
21379     } InternalTicket;
21380 
21381     /* fit within SESSION_TICKET_LEN */
21382     typedef struct ExternalTicket {
21383         byte key_name[WOLFSSL_TICKET_NAME_SZ];  /* key context name */
21384         byte iv[WOLFSSL_TICKET_IV_SZ];          /* this ticket's iv */
21385         byte enc_len[LENGTH_SZ];                /* encrypted length */
21386         byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
21387         byte mac[WOLFSSL_TICKET_MAC_SZ];        /* total mac */
21388         /* !! if add to structure, add to TICKET_FIXED_SZ !! */
21389     } ExternalTicket;
21390 
21391     /* create a new session ticket, 0 on success */
21392     int CreateTicket(WOLFSSL* ssl)
21393     {
21394         InternalTicket  it;
21395         ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
21396         int encLen;
21397         int ret;
21398         byte zeros[WOLFSSL_TICKET_MAC_SZ];   /* biggest cmp size */
21399 
21400         XMEMSET(&it, 0, sizeof(it));
21401 
21402         /* build internal */
21403         it.pv.major = ssl->version.major;
21404         it.pv.minor = ssl->version.minor;
21405 
21406         it.suite[0] = ssl->options.cipherSuite0;
21407         it.suite[1] = ssl->options.cipherSuite;
21408 
21409         if (!ssl->options.tls1_3) {
21410             XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
21411             c32toa(LowResTimer(), (byte*)&it.timestamp);
21412             it.haveEMS = ssl->options.haveEMS;
21413         }
21414         else {
21415 #ifdef WOLFSSL_TLS13
21416             /* Client adds to ticket age to obfuscate. */
21417             ret = wc_RNG_GenerateBlock(ssl->rng, (void*)&it.ageAdd,
21418                                        sizeof(it.ageAdd));
21419             if (ret != 0)
21420                 return BAD_TICKET_ENCRYPT;
21421             ssl->session.ticketAdd = it.ageAdd;
21422             it.namedGroup = ssl->session.namedGroup;
21423             it.timestamp = TimeNowInMilliseconds();
21424             /* Resumption master secret. */
21425             XMEMCPY(it.msecret, ssl->session.masterSecret, SECRET_LEN);
21426 #endif
21427         }
21428 
21429         /* build external */
21430         XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
21431 
21432         /* encrypt */
21433         encLen = WOLFSSL_TICKET_ENC_SZ;  /* max size user can use */
21434         ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
21435                                     et->enc_ticket, sizeof(InternalTicket),
21436                                     &encLen, ssl->ctx->ticketEncCtx);
21437         if (ret == WOLFSSL_TICKET_RET_OK) {
21438             if (encLen < (int)sizeof(InternalTicket) ||
21439                 encLen > WOLFSSL_TICKET_ENC_SZ) {
21440                 WOLFSSL_MSG("Bad user ticket encrypt size");
21441                 return BAD_TICKET_KEY_CB_SZ;
21442             }
21443 
21444             /* sanity checks on encrypt callback */
21445 
21446             /* internal ticket can't be the same if encrypted */
21447             if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
21448                 WOLFSSL_MSG("User ticket encrypt didn't encrypt");
21449                 return BAD_TICKET_ENCRYPT;
21450             }
21451 
21452             XMEMSET(zeros, 0, sizeof(zeros));
21453 
21454             /* name */
21455             if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) {
21456                 WOLFSSL_MSG("User ticket encrypt didn't set name");
21457                 return BAD_TICKET_ENCRYPT;
21458             }
21459 
21460             /* iv */
21461             if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) {
21462                 WOLFSSL_MSG("User ticket encrypt didn't set iv");
21463                 return BAD_TICKET_ENCRYPT;
21464             }
21465 
21466             /* mac */
21467             if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
21468                 WOLFSSL_MSG("User ticket encrypt didn't set mac");
21469                 return BAD_TICKET_ENCRYPT;
21470             }
21471 
21472             /* set size */
21473             c16toa((word16)encLen, et->enc_len);
21474             ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
21475             if (encLen < WOLFSSL_TICKET_ENC_SZ) {
21476                 /* move mac up since whole enc buffer not used */
21477                 XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
21478             }
21479         }
21480 
21481         return ret;
21482     }
21483 
21484 
21485     /* Parse ticket sent by client, returns callback return value */
21486     int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
21487     {
21488         ExternalTicket* et;
21489         InternalTicket* it;
21490         int             ret;
21491         int             outLen;
21492         word16          inLen;
21493 
21494         if (len > SESSION_TICKET_LEN ||
21495              len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
21496             return BAD_TICKET_MSG_SZ;
21497         }
21498 
21499         et = (ExternalTicket*)input;
21500         it = (InternalTicket*)et->enc_ticket;
21501 
21502         /* decrypt */
21503         ato16(et->enc_len, &inLen);
21504         if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
21505             return BAD_TICKET_MSG_SZ;
21506         }
21507         outLen = inLen;   /* may be reduced by user padding */
21508         ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
21509                                     et->enc_ticket + inLen, 0,
21510                                     et->enc_ticket, inLen, &outLen,
21511                                     ssl->ctx->ticketEncCtx);
21512         if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) return ret;
21513         if (outLen > inLen || outLen < (int)sizeof(InternalTicket)) {
21514             WOLFSSL_MSG("Bad user ticket decrypt len");
21515             return BAD_TICKET_KEY_CB_SZ;
21516         }
21517 
21518         /* get master secret */
21519         if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE) {
21520             if (!IsAtLeastTLSv1_3(ssl->version)) {
21521                 XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
21522                 /* Copy the haveExtendedMasterSecret property from the ticket to
21523                  * the saved session, so the property may be checked later. */
21524                 ssl->session.haveEMS = it->haveEMS;
21525             }
21526             else {
21527 #ifdef WOLFSSL_TLS13
21528                 /* Restore information to renegotiate. */
21529                 ssl->session.ticketSeen = it->timestamp;
21530                 ssl->session.ticketAdd = it->ageAdd;
21531                 ssl->session.cipherSuite0 = it->suite[0];
21532                 ssl->session.cipherSuite = it->suite[1];
21533                 /* Resumption master secret. */
21534                 XMEMCPY(ssl->session.masterSecret, it->msecret, SECRET_LEN);
21535                 ssl->session.namedGroup = it->namedGroup;
21536 #endif
21537             }
21538         }
21539 
21540         return ret;
21541     }
21542 
21543 
21544     /* send Session Ticket */
21545     int SendTicket(WOLFSSL* ssl)
21546     {
21547         byte*              output;
21548         int                ret;
21549         int                sendSz;
21550         word32             length = SESSION_HINT_SZ + LENGTH_SZ;
21551         word32             idx    = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
21552 
21553         if (ssl->options.createTicket) {
21554             ret = CreateTicket(ssl);
21555             if (ret != 0) return ret;
21556         }
21557 
21558         length += ssl->session.ticketLen;
21559         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
21560 
21561         #ifdef WOLFSSL_DTLS
21562         if (ssl->options.dtls) {
21563             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
21564             idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
21565         }
21566         #endif
21567         /* check for available size */
21568         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
21569             return ret;
21570 
21571         /* get output buffer */
21572         output = ssl->buffers.outputBuffer.buffer +
21573                  ssl->buffers.outputBuffer.length;
21574 
21575         AddHeaders(output, length, session_ticket, ssl);
21576 
21577         /* hint */
21578         c32toa(ssl->ctx->ticketHint, output + idx);
21579         idx += SESSION_HINT_SZ;
21580 
21581         /* length */
21582         c16toa(ssl->session.ticketLen, output + idx);
21583         idx += LENGTH_SZ;
21584 
21585         /* ticket */
21586         XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
21587         /* idx += ssl->session.ticketLen; */
21588 
21589         #ifdef WOLFSSL_DTLS
21590         if (ssl->options.dtls) {
21591             if ((ret = DtlsMsgPoolSave(ssl, output, sendSz)) != 0)
21592                 return ret;
21593 
21594             DtlsSEQIncrement(ssl, CUR_ORDER);
21595         }
21596         #endif
21597 
21598         ret = HashOutput(ssl, output, sendSz, 0);
21599         if (ret != 0) return ret;
21600         ssl->buffers.outputBuffer.length += sendSz;
21601 
21602         return SendBuffered(ssl);
21603     }
21604 
21605 #endif /* HAVE_SESSION_TICKET */
21606 
21607 
21608 #ifdef WOLFSSL_DTLS
21609     static int SendHelloVerifyRequest(WOLFSSL* ssl,
21610                                       const byte* cookie, byte cookieSz)
21611     {
21612         byte* output;
21613         int   length = VERSION_SZ + ENUM_LEN + cookieSz;
21614         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
21615         int   sendSz = length + idx;
21616         int   ret;
21617 
21618         /* check for available size */
21619         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
21620             return ret;
21621 
21622         /* get output buffer */
21623         output = ssl->buffers.outputBuffer.buffer +
21624                  ssl->buffers.outputBuffer.length;
21625 
21626         /* Hello Verify Request should use the same sequence number as the
21627          * Client Hello. */
21628         ssl->keys.dtls_sequence_number_hi = ssl->keys.curSeq_hi;
21629         ssl->keys.dtls_sequence_number_lo = ssl->keys.curSeq_lo;
21630         AddHeaders(output, length, hello_verify_request, ssl);
21631 
21632 #ifdef OPENSSL_EXTRA
21633         output[idx++] = DTLS_MAJOR;
21634         output[idx++] = DTLS_MINOR;
21635 #else
21636         output[idx++] = ssl->version.major;
21637         output[idx++] = ssl->version.minor;
21638 #endif
21639 
21640         output[idx++] = cookieSz;
21641         if (cookie == NULL || cookieSz == 0)
21642             return COOKIE_ERROR;
21643 
21644         XMEMCPY(output + idx, cookie, cookieSz);
21645 
21646 #ifdef WOLFSSL_CALLBACKS
21647         if (ssl->hsInfoOn)
21648             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
21649         if (ssl->toInfoOn)
21650             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
21651                           sendSz, ssl->heap);
21652 #endif
21653 
21654         ssl->buffers.outputBuffer.length += sendSz;
21655 
21656         return SendBuffered(ssl);
21657     }
21658 #endif /* WOLFSSL_DTLS */
21659 
21660     typedef struct DckeArgs {
21661         byte*  output; /* not allocated */
21662         word32 length;
21663         word32 idx;
21664         word32 begin;
21665         word32 sigSz;
21666     } DckeArgs;
21667 
21668     static void FreeDckeArgs(WOLFSSL* ssl, void* pArgs)
21669     {
21670         DckeArgs* args = (DckeArgs*)pArgs;
21671 
21672         (void)ssl;
21673         (void)args;
21674     }
21675 
21676     static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx,
21677                                                                     word32 size)
21678     {
21679         int ret;
21680     #ifdef WOLFSSL_ASYNC_CRYPT
21681         DckeArgs* args = (DckeArgs*)ssl->async.args;
21682         typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
21683         (void)sizeof(args_test);
21684     #else
21685         DckeArgs  args[1];
21686     #endif
21687 
21688         WOLFSSL_ENTER("DoClientKeyExchange");
21689 
21690     #ifdef WOLFSSL_ASYNC_CRYPT
21691         ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
21692         if (ret != WC_NOT_PENDING_E) {
21693             /* Check for error */
21694             if (ret < 0)
21695                 goto exit_dcke;
21696         }
21697         else
21698     #endif /* WOLFSSL_ASYNC_CRYPT */
21699         {
21700             /* Reset state */
21701             ret = 0;
21702             ssl->options.asyncState = TLS_ASYNC_BEGIN;
21703             XMEMSET(args, 0, sizeof(DckeArgs));
21704             args->idx = *inOutIdx;
21705             args->begin = *inOutIdx;
21706         #ifdef WOLFSSL_ASYNC_CRYPT
21707             ssl->async.freeArgs = FreeDckeArgs;
21708         #endif
21709         }
21710 
21711         /* Do Client Key Exchange State Machine */
21712         switch(ssl->options.asyncState)
21713         {
21714             case TLS_ASYNC_BEGIN:
21715             {
21716                 /* Sanity checks */
21717                 if (ssl->options.side != WOLFSSL_SERVER_END) {
21718                     WOLFSSL_MSG("Client received client keyexchange, attack?");
21719                     WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
21720                     ERROR_OUT(SSL_FATAL_ERROR, exit_dcke);
21721                 }
21722 
21723                 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
21724                     WOLFSSL_MSG("Client sending keyexchange at wrong time");
21725                     SendAlert(ssl, alert_fatal, unexpected_message);
21726                     ERROR_OUT(OUT_OF_ORDER_E, exit_dcke);
21727                 }
21728 
21729             #ifndef NO_CERTS
21730                 if (ssl->options.verifyPeer && ssl->options.failNoCert) {
21731                     if (!ssl->options.havePeerCert) {
21732                         WOLFSSL_MSG("client didn't present peer cert");
21733                         ERROR_OUT(NO_PEER_CERT, exit_dcke);
21734                     }
21735                 }
21736 
21737                 if (ssl->options.verifyPeer && ssl->options.failNoCertxPSK) {
21738                     if (!ssl->options.havePeerCert &&
21739                                              !ssl->options.usingPSK_cipher) {
21740                         WOLFSSL_MSG("client didn't present peer cert");
21741                         return NO_PEER_CERT;
21742                     }
21743                 }
21744             #endif /* !NO_CERTS */
21745 
21746             #ifdef WOLFSSL_CALLBACKS
21747                 if (ssl->hsInfoOn) {
21748                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
21749                 }
21750                 if (ssl->toInfoOn) {
21751                     AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
21752                 }
21753             #endif
21754 
21755                 switch (ssl->specs.kea) {
21756                 #ifndef NO_RSA
21757                     case rsa_kea:
21758                     {
21759                         /* make sure private key exists */
21760                         if (ssl->buffers.key == NULL ||
21761                                             ssl->buffers.key->buffer == NULL) {
21762                             ERROR_OUT(NO_PRIVATE_KEY, exit_dcke);
21763                         }
21764                         break;
21765                     } /* rsa_kea */
21766                 #endif /* !NO_RSA */
21767                 #ifndef NO_PSK
21768                     case psk_kea:
21769                     {
21770                         /* sanity check that PSK server callback has been set */
21771                         if (ssl->options.server_psk_cb == NULL) {
21772                            WOLFSSL_MSG("No server PSK callback set");
21773                            ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
21774                         }
21775                         break;
21776                     }
21777                 #endif /* !NO_PSK */
21778                 #ifdef HAVE_NTRU
21779                     case ntru_kea:
21780                     {
21781                         /* make sure private key exists */
21782                         if (ssl->buffers.key == NULL ||
21783                                             ssl->buffers.key->buffer == NULL) {
21784                             ERROR_OUT(NO_PRIVATE_KEY, exit_dcke);
21785                         }
21786                         break;
21787                     }
21788                 #endif /* HAVE_NTRU */
21789                 #ifdef HAVE_ECC
21790                     case ecc_diffie_hellman_kea:
21791                     {
21792                         break;
21793                     }
21794                 #endif /* HAVE_ECC */
21795                 #ifndef NO_DH
21796                     case diffie_hellman_kea:
21797                     {
21798                         break;
21799                     }
21800                 #endif /* !NO_DH */
21801                 #if !defined(NO_DH) && !defined(NO_PSK)
21802                     case dhe_psk_kea:
21803                     {
21804                         /* sanity check that PSK server callback has been set */
21805                         if (ssl->options.server_psk_cb == NULL) {
21806                             WOLFSSL_MSG("No server PSK callback set");
21807                             ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
21808                         }
21809                         break;
21810                     }
21811                 #endif /* !NO_DH && !NO_PSK */
21812                 #if defined(HAVE_ECC) && !defined(NO_PSK)
21813                     case ecdhe_psk_kea:
21814                     {
21815                         /* sanity check that PSK server callback has been set */
21816                         if (ssl->options.server_psk_cb == NULL) {
21817                             WOLFSSL_MSG("No server PSK callback set");
21818                             ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
21819                         }
21820                         break;
21821                     }
21822                 #endif /* HAVE_ECC && !NO_PSK */
21823                     default:
21824                         WOLFSSL_MSG("Bad kea type");
21825                         ret = BAD_KEA_TYPE_E;
21826                 } /* switch (ssl->specs.kea) */
21827 
21828                 /* Check for error */
21829                 if (ret != 0) {
21830                     goto exit_dcke;
21831                 }
21832 
21833                 /* Advance state and proceed */
21834                 ssl->options.asyncState = TLS_ASYNC_BUILD;
21835             } /* TLS_ASYNC_BEGIN */
21836 
21837             case TLS_ASYNC_BUILD:
21838             {
21839                 switch (ssl->specs.kea) {
21840                 #ifndef NO_RSA
21841                     case rsa_kea:
21842                     {
21843                         word32 i = 0;
21844                         int    keySz;
21845 
21846                         ssl->hsType = DYNAMIC_TYPE_RSA;
21847                         ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
21848                         if (ret != 0) {
21849                             goto exit_dcke;
21850                         }
21851 
21852                         ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer,
21853                             &i, (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
21854                         if (ret != 0) {
21855                             goto exit_dcke;
21856                         }
21857                         keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
21858                         if (keySz < 0) { /* test if keySz has error */
21859                             ERROR_OUT(keySz, exit_dcke);
21860                         }
21861                         args->length = (word32)keySz;
21862 
21863                         if (keySz < ssl->options.minRsaKeySz) {
21864                             WOLFSSL_MSG("Peer RSA key is too small");
21865                             ERROR_OUT(RSA_KEY_SIZE_E, exit_dcke);
21866                         }
21867                         ssl->arrays->preMasterSz = SECRET_LEN;
21868 
21869                         if (ssl->options.tls) {
21870                             word16 check;
21871 
21872                             if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
21873                                 ERROR_OUT(BUFFER_ERROR, exit_dcke);
21874                             }
21875 
21876                             ato16(input + args->idx, &check);
21877                             args->idx += OPAQUE16_LEN;
21878 
21879                             if ((word32)check != args->length) {
21880                                 WOLFSSL_MSG("RSA explicit size doesn't match");
21881                                 ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
21882                             }
21883                         }
21884 
21885                         if ((args->idx - args->begin) + args->length > size) {
21886                             WOLFSSL_MSG("RSA message too big");
21887                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
21888                         }
21889 
21890                         args->output = NULL;
21891                         break;
21892                     } /* rsa_kea */
21893                 #endif /* !NO_RSA */
21894                 #ifndef NO_PSK
21895                     case psk_kea:
21896                     {
21897                         byte* pms = ssl->arrays->preMasterSecret;
21898                         word16 ci_sz;
21899 
21900                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
21901                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
21902                         }
21903 
21904                         ato16(input + args->idx, &ci_sz);
21905                         args->idx += OPAQUE16_LEN;
21906 
21907                         if (ci_sz > MAX_PSK_ID_LEN) {
21908                             ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
21909                         }
21910 
21911                         if ((args->idx - args->begin) + ci_sz > size) {
21912                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
21913                         }
21914 
21915                         XMEMCPY(ssl->arrays->client_identity,
21916                                                     input + args->idx, ci_sz);
21917                         args->idx += ci_sz;
21918 
21919                         ssl->arrays->client_identity[ci_sz] = '\0'; /* null term */
21920                         ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
21921                             ssl->arrays->client_identity, ssl->arrays->psk_key,
21922                             MAX_PSK_KEY_LEN);
21923 
21924                         if (ssl->arrays->psk_keySz == 0 ||
21925                                 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
21926                             ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
21927                         }
21928 
21929                         /* make psk pre master secret */
21930                         /* length of key + length 0s + length of key + key */
21931                         c16toa((word16) ssl->arrays->psk_keySz, pms);
21932                         pms += OPAQUE16_LEN;
21933 
21934                         XMEMSET(pms, 0, ssl->arrays->psk_keySz);
21935                         pms += ssl->arrays->psk_keySz;
21936 
21937                         c16toa((word16) ssl->arrays->psk_keySz, pms);
21938                         pms += OPAQUE16_LEN;
21939 
21940                         XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
21941                         ssl->arrays->preMasterSz =
21942                             (ssl->arrays->psk_keySz * 2) + (OPAQUE16_LEN * 2);
21943                         break;
21944                     }
21945                 #endif /* !NO_PSK */
21946                 #ifdef HAVE_NTRU
21947                     case ntru_kea:
21948                     {
21949                         word16 cipherLen;
21950                         word16 plainLen = ENCRYPT_LEN;
21951 
21952                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
21953                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
21954                         }
21955 
21956                         ato16(input + args->idx, &cipherLen);
21957                         args->idx += OPAQUE16_LEN;
21958 
21959                         if (cipherLen > MAX_NTRU_ENCRYPT_SZ) {
21960                             ERROR_OUT(NTRU_KEY_ERROR, exit_dcke);
21961                         }
21962 
21963                         if ((args->idx - args->begin) + cipherLen > size) {
21964                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
21965                         }
21966 
21967                         if (NTRU_OK != ntru_crypto_ntru_decrypt(
21968                                     (word16) ssl->buffers.key->length,
21969                                     ssl->buffers.key->buffer, cipherLen,
21970                                     input + args->idx, &plainLen,
21971                                     ssl->arrays->preMasterSecret)) {
21972                             ERROR_OUT(NTRU_DECRYPT_ERROR, exit_dcke);
21973                         }
21974 
21975                         if (plainLen != SECRET_LEN) {
21976                             ERROR_OUT(NTRU_DECRYPT_ERROR, exit_dcke);
21977                         }
21978 
21979                         args->idx += cipherLen;
21980                         ssl->arrays->preMasterSz = plainLen;
21981                         break;
21982                     }
21983                 #endif /* HAVE_NTRU */
21984                 #ifdef HAVE_ECC
21985                     case ecc_diffie_hellman_kea:
21986                     {
21987                         ecc_key* private_key = ssl->eccTempKey;
21988 
21989                         /* handle static private key */
21990                         if (ssl->specs.static_ecdh) {
21991                             word32 i = 0;
21992 
21993                             ssl->hsType = DYNAMIC_TYPE_ECC;
21994                             ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
21995                             if (ret != 0) {
21996                                 goto exit_dcke;
21997                             }
21998 
21999                             ret = wc_EccPrivateKeyDecode(
22000                                 ssl->buffers.key->buffer,
22001                                 &i,
22002                                 (ecc_key*)ssl->hsKey,
22003                                 ssl->buffers.key->length);
22004                             if (ret == 0) {
22005                                 private_key = (ecc_key*)ssl->hsKey;
22006                                 if (wc_ecc_size(private_key) <
22007                                                 ssl->options.minEccKeySz) {
22008                                     WOLFSSL_MSG("ECC key too small");
22009                                     ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke);
22010                                 }
22011                             }
22012                         }
22013 
22014                         /* import peer ECC key */
22015                         if ((args->idx - args->begin) + OPAQUE8_LEN > size) {
22016                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22017                         }
22018 
22019                         args->length = input[args->idx++];
22020 
22021                         if ((args->idx - args->begin) + args->length > size) {
22022                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22023                         }
22024 
22025                         ssl->arrays->preMasterSz = ENCRYPT_LEN;
22026 
22027                     #ifdef HAVE_PK_CALLBACKS
22028                         /* if callback then use it for shared secret */
22029                         if (ssl->ctx->EccSharedSecretCb != NULL) {
22030                             break;
22031                         }
22032                     #endif
22033 
22034                         if (!ssl->specs.static_ecdh &&
22035                             ssl->eccTempKeyPresent == 0) {
22036                             WOLFSSL_MSG("Ecc ephemeral key not made correctly");
22037                             ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
22038                         }
22039 
22040                         if (ssl->peerEccKey == NULL) {
22041                             /* alloc/init on demand */
22042                             ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
22043                                 (void**)&ssl->peerEccKey);
22044                             if (ret != 0) {
22045                                 goto exit_dcke;
22046                             }
22047                         } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
22048                             wc_ecc_free(ssl->peerEccKey);
22049                             ssl->peerEccKeyPresent = 0;
22050                             ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
22051                                                                 ssl->devId);
22052                             if (ret != 0) {
22053                                 goto exit_dcke;
22054                             }
22055                         }
22056 
22057                         if (wc_ecc_import_x963_ex(input + args->idx, args->length,
22058                                         ssl->peerEccKey, private_key->dp->id)) {
22059                             ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
22060                         }
22061 
22062                         ssl->peerEccKeyPresent = 1;
22063 
22064                         if (ret != 0) {
22065                             goto exit_dcke;
22066                         }
22067                         break;
22068                     }
22069                 #endif /* HAVE_ECC */
22070                 #ifndef NO_DH
22071                     case diffie_hellman_kea:
22072                     {
22073                         word16 clientPubSz;
22074 
22075                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
22076                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22077                         }
22078 
22079                         ato16(input + args->idx, &clientPubSz);
22080                         args->idx += OPAQUE16_LEN;
22081 
22082                         if ((args->idx - args->begin) + clientPubSz > size) {
22083                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22084                         }
22085 
22086                         args->sigSz = clientPubSz;
22087 
22088                         ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
22089                                             (void**)&ssl->buffers.serverDH_Key);
22090                         if (ret != 0) {
22091                             goto exit_dcke;
22092                         }
22093 
22094                         ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
22095                             ssl->buffers.serverDH_P.buffer,
22096                             ssl->buffers.serverDH_P.length,
22097                             ssl->buffers.serverDH_G.buffer,
22098                             ssl->buffers.serverDH_G.length);
22099                         break;
22100                     }
22101                 #endif /* !NO_DH */
22102                 #if !defined(NO_DH) && !defined(NO_PSK)
22103                     case dhe_psk_kea:
22104                     {
22105                         word16 clientSz;
22106 
22107                         /* Read in the PSK hint */
22108                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
22109                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22110                         }
22111 
22112                         ato16(input + args->idx, &clientSz);
22113                         args->idx += OPAQUE16_LEN;
22114                         if (clientSz > MAX_PSK_ID_LEN) {
22115                             ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
22116                         }
22117 
22118                         if ((args->idx - args->begin) + clientSz > size) {
22119                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22120                         }
22121 
22122                         XMEMCPY(ssl->arrays->client_identity, input + args->idx,
22123                                                                     clientSz);
22124                         args->idx += clientSz;
22125                         ssl->arrays->client_identity[clientSz] = '\0'; /* null term */
22126 
22127                         /* Read in the DHE business */
22128                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
22129                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22130                         }
22131 
22132                         ato16(input + args->idx, &clientSz);
22133                         args->idx += OPAQUE16_LEN;
22134 
22135                         if ((args->idx - args->begin) + clientSz > size) {
22136                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22137                         }
22138 
22139                         args->sigSz = clientSz;
22140 
22141                         ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
22142                                             (void**)&ssl->buffers.serverDH_Key);
22143                         if (ret != 0) {
22144                             goto exit_dcke;
22145                         }
22146 
22147                         ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
22148                             ssl->buffers.serverDH_P.buffer,
22149                             ssl->buffers.serverDH_P.length,
22150                             ssl->buffers.serverDH_G.buffer,
22151                             ssl->buffers.serverDH_G.length);
22152 
22153                         break;
22154                     }
22155                 #endif /* !NO_DH && !NO_PSK */
22156                 #if defined(HAVE_ECC) && !defined(NO_PSK)
22157                     case ecdhe_psk_kea:
22158                     {
22159                         word16 clientSz;
22160 
22161                         /* Read in the PSK hint */
22162                         if ((args->idx - args->begin) + OPAQUE16_LEN > size) {
22163                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22164                         }
22165 
22166                         ato16(input + args->idx, &clientSz);
22167                         args->idx += OPAQUE16_LEN;
22168                         if (clientSz > MAX_PSK_ID_LEN) {
22169                             ERROR_OUT(CLIENT_ID_ERROR, exit_dcke);
22170                         }
22171                         if ((args->idx - args->begin) + clientSz > size) {
22172                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22173                         }
22174 
22175                         XMEMCPY(ssl->arrays->client_identity,
22176                                                    input + args->idx, clientSz);
22177                         args->idx += clientSz;
22178                         ssl->arrays->client_identity[clientSz] = '\0'; /* null term */
22179 
22180                         /* import peer ECC key */
22181                         if ((args->idx - args->begin) + OPAQUE8_LEN > size) {
22182                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22183                         }
22184 
22185                         args->length = input[args->idx++];
22186 
22187                         if ((args->idx - args->begin) + args->length > size) {
22188                             ERROR_OUT(BUFFER_ERROR, exit_dcke);
22189                         }
22190 
22191                         args->sigSz = ENCRYPT_LEN - OPAQUE16_LEN;
22192 
22193                     #ifdef HAVE_PK_CALLBACKS
22194                         /* if callback then use it for shared secret */
22195                         if (ssl->ctx->EccSharedSecretCb != NULL) {
22196                             break;
22197                         }
22198                     #endif
22199 
22200                         if (ssl->eccTempKeyPresent == 0) {
22201                             WOLFSSL_MSG("Ecc ephemeral key not made correctly");
22202                             ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke);
22203                         }
22204 
22205                         if (ssl->peerEccKey == NULL) {
22206                             /* alloc/init on demand */
22207                             ret = AllocKey(ssl, DYNAMIC_TYPE_ECC,
22208                                 (void**)&ssl->peerEccKey);
22209                             if (ret != 0) {
22210                                 goto exit_dcke;
22211                             }
22212                         }
22213                         else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
22214                             wc_ecc_free(ssl->peerEccKey);
22215                             ssl->peerEccKeyPresent = 0;
22216                             ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap,
22217                                                                 ssl->devId);
22218                             if (ret != 0) {
22219                                 goto exit_dcke;
22220                             }
22221                         }
22222                         if (wc_ecc_import_x963_ex(input + args->idx, args->length,
22223                                  ssl->peerEccKey, ssl->eccTempKey->dp->id)) {
22224                             ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke);
22225                         }
22226 
22227                         ssl->peerEccKeyPresent = 1;
22228                         break;
22229                     }
22230                 #endif /* HAVE_ECC && !NO_PSK */
22231                     default:
22232                         ret = BAD_KEA_TYPE_E;
22233                 } /* switch (ssl->specs.kea) */
22234 
22235                 /* Check for error */
22236                 if (ret != 0) {
22237                     goto exit_dcke;
22238                 }
22239 
22240                 /* Advance state and proceed */
22241                 ssl->options.asyncState = TLS_ASYNC_DO;
22242             } /* TLS_ASYNC_BUILD */
22243 
22244             case TLS_ASYNC_DO:
22245             {
22246                 switch (ssl->specs.kea) {
22247                 #ifndef NO_RSA
22248                     case rsa_kea:
22249                     {
22250                         RsaKey* key = (RsaKey*)ssl->hsKey;
22251                         ret = RsaDec(ssl,
22252                             input + args->idx,
22253                             args->length,
22254                             &args->output,
22255                             &args->sigSz,
22256                             key,
22257                         #if defined(HAVE_PK_CALLBACKS)
22258                             ssl->buffers.key->buffer,
22259                             ssl->buffers.key->length,
22260                             ssl->RsaDecCtx
22261                         #else
22262                             NULL, 0, NULL
22263                         #endif
22264                         );
22265                         break;
22266                     } /* rsa_kea */
22267                 #endif /* !NO_RSA */
22268                 #ifndef NO_PSK
22269                     case psk_kea:
22270                     {
22271                         break;
22272                     }
22273                 #endif /* !NO_PSK */
22274                 #ifdef HAVE_NTRU
22275                     case ntru_kea:
22276                     {
22277                         break;
22278                     }
22279                 #endif /* HAVE_NTRU */
22280                 #ifdef HAVE_ECC
22281                     case ecc_diffie_hellman_kea:
22282                     {
22283                         ecc_key* private_key = ssl->eccTempKey;
22284                         if (ssl->specs.static_ecdh) {
22285                             private_key = (ecc_key*)ssl->hsKey;
22286                         }
22287 
22288                         /* Generate shared secret */
22289                         ret = EccSharedSecret(ssl,
22290                             private_key, ssl->peerEccKey,
22291                             input + args->idx, &args->length,
22292                             ssl->arrays->preMasterSecret,
22293                             &ssl->arrays->preMasterSz,
22294                             WOLFSSL_SERVER_END,
22295                         #ifdef HAVE_PK_CALLBACKS
22296                             ssl->EccSharedSecretCtx
22297                         #else
22298                             NULL
22299                         #endif
22300                         );
22301                         break;
22302                     }
22303                 #endif /* HAVE_ECC */
22304                 #ifndef NO_DH
22305                     case diffie_hellman_kea:
22306                     {
22307                         ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
22308                             ssl->buffers.serverDH_Priv.buffer,
22309                             ssl->buffers.serverDH_Priv.length,
22310                             input + args->idx,
22311                             (word16)args->sigSz,
22312                             ssl->arrays->preMasterSecret,
22313                             &ssl->arrays->preMasterSz);
22314                         break;
22315                     }
22316                 #endif /* !NO_DH */
22317                 #if !defined(NO_DH) && !defined(NO_PSK)
22318                     case dhe_psk_kea:
22319                     {
22320                         ret = DhAgree(ssl, ssl->buffers.serverDH_Key,
22321                             ssl->buffers.serverDH_Priv.buffer,
22322                             ssl->buffers.serverDH_Priv.length,
22323                             input + args->idx,
22324                             (word16)args->sigSz,
22325                             ssl->arrays->preMasterSecret + OPAQUE16_LEN,
22326                             &ssl->arrays->preMasterSz);
22327                         break;
22328                     }
22329                 #endif /* !NO_DH && !NO_PSK */
22330                 #if defined(HAVE_ECC) && !defined(NO_PSK)
22331                     case ecdhe_psk_kea:
22332                     {
22333                         /* Generate shared secret */
22334                         ret = EccSharedSecret(ssl,
22335                             ssl->eccTempKey, ssl->peerEccKey,
22336                             input + args->idx, &args->length,
22337                             ssl->arrays->preMasterSecret + OPAQUE16_LEN,
22338                             &args->sigSz,
22339                             WOLFSSL_SERVER_END,
22340                         #ifdef HAVE_PK_CALLBACKS
22341                             ssl->EccSharedSecretCtx
22342                         #else
22343                             NULL
22344                         #endif
22345                         );
22346                         break;
22347                     }
22348                 #endif /* HAVE_ECC && !NO_PSK */
22349                     default:
22350                         ret = BAD_KEA_TYPE_E;
22351                 } /* switch (ssl->specs.kea) */
22352 
22353                 /* Check for error */
22354                 if (ret != 0) {
22355                     goto exit_dcke;
22356                 }
22357 
22358                 /* Advance state and proceed */
22359                 ssl->options.asyncState = TLS_ASYNC_VERIFY;
22360             } /* TLS_ASYNC_DO */
22361 
22362             case TLS_ASYNC_VERIFY:
22363             {
22364                 switch (ssl->specs.kea) {
22365                 #ifndef NO_RSA
22366                     case rsa_kea:
22367                     {
22368                         /* Add the signature length to idx */
22369                         args->idx += args->length;
22370 
22371                         if (args->sigSz == SECRET_LEN && args->output != NULL) {
22372                             XMEMCPY(ssl->arrays->preMasterSecret, args->output, SECRET_LEN);
22373                             if (ssl->arrays->preMasterSecret[0] != ssl->chVersion.major ||
22374                                 ssl->arrays->preMasterSecret[1] != ssl->chVersion.minor) {
22375                                 ERROR_OUT(PMS_VERSION_ERROR, exit_dcke);
22376                             }
22377                         }
22378                         else {
22379                             ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
22380                         }
22381                         break;
22382                     } /* rsa_kea */
22383                 #endif /* !NO_RSA */
22384                 #ifndef NO_PSK
22385                     case psk_kea:
22386                     {
22387                         break;
22388                     }
22389                 #endif /* !NO_PSK */
22390                 #ifdef HAVE_NTRU
22391                     case ntru_kea:
22392                     {
22393                         break;
22394                     }
22395                 #endif /* HAVE_NTRU */
22396                 #ifdef HAVE_ECC
22397                     case ecc_diffie_hellman_kea:
22398                     {
22399                         /* skip past the imported peer key */
22400                         args->idx += args->length;
22401                         break;
22402                     }
22403                 #endif /* HAVE_ECC */
22404                 #ifndef NO_DH
22405                     case diffie_hellman_kea:
22406                     {
22407                         args->idx += (word16)args->sigSz;
22408                         break;
22409                     }
22410                 #endif /* !NO_DH */
22411                 #if !defined(NO_DH) && !defined(NO_PSK)
22412                     case dhe_psk_kea:
22413                     {
22414                         byte* pms = ssl->arrays->preMasterSecret;
22415                         word16 clientSz = (word16)args->sigSz;
22416 
22417                         args->idx += clientSz;
22418                         c16toa((word16)ssl->arrays->preMasterSz, pms);
22419                         ssl->arrays->preMasterSz += OPAQUE16_LEN;
22420                         pms += ssl->arrays->preMasterSz;
22421 
22422                         /* Use the PSK hint to look up the PSK and add it to the
22423                          * preMasterSecret here. */
22424                         ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
22425                             ssl->arrays->client_identity, ssl->arrays->psk_key,
22426                             MAX_PSK_KEY_LEN);
22427 
22428                         if (ssl->arrays->psk_keySz == 0 ||
22429                                 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
22430                             ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
22431                         }
22432 
22433                         c16toa((word16) ssl->arrays->psk_keySz, pms);
22434                         pms += OPAQUE16_LEN;
22435 
22436                         XMEMCPY(pms, ssl->arrays->psk_key,
22437                                                     ssl->arrays->psk_keySz);
22438                         ssl->arrays->preMasterSz += ssl->arrays->psk_keySz +
22439                                                                 OPAQUE16_LEN;
22440                         break;
22441                     }
22442                 #endif /* !NO_DH && !NO_PSK */
22443                 #if defined(HAVE_ECC) && !defined(NO_PSK)
22444                     case ecdhe_psk_kea:
22445                     {
22446                         byte* pms = ssl->arrays->preMasterSecret;
22447                         word16 clientSz = (word16)args->sigSz;
22448 
22449                         /* skip past the imported peer key */
22450                         args->idx += args->length;
22451 
22452                         /* Add preMasterSecret */
22453                         c16toa(clientSz, pms);
22454                         ssl->arrays->preMasterSz += OPAQUE16_LEN + clientSz;
22455                         pms += ssl->arrays->preMasterSz;
22456 
22457                         /* Use the PSK hint to look up the PSK and add it to the
22458                          * preMasterSecret here. */
22459                         ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
22460                             ssl->arrays->client_identity, ssl->arrays->psk_key,
22461                             MAX_PSK_KEY_LEN);
22462 
22463                         if (ssl->arrays->psk_keySz == 0 ||
22464                                    ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
22465                             ERROR_OUT(PSK_KEY_ERROR, exit_dcke);
22466                         }
22467 
22468                         c16toa((word16) ssl->arrays->psk_keySz, pms);
22469                         pms += OPAQUE16_LEN;
22470 
22471                         XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
22472                         ssl->arrays->preMasterSz +=
22473                                       ssl->arrays->psk_keySz + OPAQUE16_LEN;
22474                         break;
22475                     }
22476                 #endif /* HAVE_ECC && !NO_PSK */
22477                     default:
22478                         ret = BAD_KEA_TYPE_E;
22479                 } /* switch (ssl->specs.kea) */
22480 
22481                 /* Check for error */
22482                 if (ret != 0) {
22483                     goto exit_dcke;
22484                 }
22485 
22486                 /* Advance state and proceed */
22487                 ssl->options.asyncState = TLS_ASYNC_FINALIZE;
22488             } /* TLS_ASYNC_VERIFY */
22489 
22490             case TLS_ASYNC_FINALIZE:
22491             {
22492             #ifdef HAVE_QSH
22493                 word16 name;
22494 
22495                 if (ssl->options.haveQSH) {
22496                     /* extension name */
22497                     ato16(input + args->idx, &name);
22498                     args->idx += OPAQUE16_LEN;
22499 
22500                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
22501                         int    qshSz;
22502                         /* if qshSz is larger than 0 it is the
22503                            length of buffer used */
22504                         if ((qshSz = TLSX_QSHCipher_Parse(ssl,
22505                                 input + args->idx,
22506                                 size - args->idx + args->begin, 1)) < 0) {
22507                             ERROR_OUT(qshSz, exit_dcke);
22508                         }
22509                         args->idx += qshSz;
22510                     }
22511                     else {
22512                         /* unknown extension sent client ignored handshake */
22513                         ERROR_OUT(BUFFER_ERROR, exit_dcke);
22514                     }
22515                 }
22516             #endif /* HAVE_QSH */
22517                 ret = MakeMasterSecret(ssl);
22518 
22519                 /* Check for error */
22520                 if (ret != 0) {
22521                     goto exit_dcke;
22522                 }
22523 
22524                 /* Advance state and proceed */
22525                 ssl->options.asyncState = TLS_ASYNC_END;
22526             } /* TLS_ASYNC_FINALIZE */
22527 
22528             case TLS_ASYNC_END:
22529             {
22530                 /* Set final index */
22531                 *inOutIdx = args->idx;
22532 
22533                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
22534             #ifndef NO_CERTS
22535                 if (ssl->options.verifyPeer) {
22536                     ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
22537                 }
22538             #endif
22539                 break;
22540             } /* TLS_ASYNC_END */
22541             default:
22542                 ret = INPUT_CASE_ERROR;
22543         } /* switch(ssl->options.asyncState) */
22544 
22545     exit_dcke:
22546 
22547         WOLFSSL_LEAVE("DoClientKeyExchange", ret);
22548 
22549     #ifdef WOLFSSL_ASYNC_CRYPT
22550         /* Handle async operation */
22551         if (ret == WC_PENDING_E) {
22552             /* Mark message as not recevied so it can process again */
22553             ssl->msgsReceived.got_client_key_exchange = 0;
22554 
22555             return ret;
22556         }
22557     #endif /* WOLFSSL_ASYNC_CRYPT */
22558 
22559         /* Cleanup PMS */
22560         ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
22561         ssl->arrays->preMasterSz = 0;
22562 
22563         /* Final cleanup */
22564         FreeDckeArgs(ssl, args);
22565         FreeKeyExchange(ssl);
22566 
22567         return ret;
22568     }
22569 
22570 
22571 #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
22572     int SNI_Callback(WOLFSSL* ssl)
22573     {
22574         /* Stunnel supports a custom sni callback to switch an SSL's ctx
22575         * when SNI is received. Call it now if exists */
22576         if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) {
22577             WOLFSSL_MSG("Calling custom sni callback");
22578             if(ssl->ctx->sniRecvCb(ssl, NULL, ssl->ctx->sniRecvCbArg)
22579                     == alert_fatal) {
22580                 WOLFSSL_MSG("Error in custom sni callback. Fatal alert");
22581                 SendAlert(ssl, alert_fatal, unrecognized_name);
22582                 return FATAL_ERROR;
22583             }
22584         }
22585         return 0;
22586     }
22587 #endif /* HAVE_STUNNEL || WOLGSSL_NGINX */
22588 #endif /* NO_WOLFSSL_SERVER */
22589 
22590 
22591 #ifdef WOLFSSL_ASYNC_CRYPT
22592 int wolfSSL_AsyncPop(WOLFSSL* ssl, byte* state)
22593 {
22594     int ret = 0;
22595     WC_ASYNC_DEV* asyncDev;
22596     WOLF_EVENT* event;
22597 
22598     if (ssl == NULL) {
22599         return BAD_FUNC_ARG;
22600     }
22601 
22602     /* check for pending async */
22603     asyncDev = ssl->async.dev;
22604     if (asyncDev) {
22605         /* grab event pointer */
22606         event = &asyncDev->event;
22607 
22608         ret = wolfAsync_EventPop(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL);
22609         if (ret != WC_NOT_PENDING_E && ret != WC_PENDING_E) {
22610 
22611             /* advance key share state if doesn't need called again */
22612             if (state && (asyncDev->event.flags & WC_ASYNC_FLAG_CALL_AGAIN) == 0) {
22613                 (*state)++;
22614             }
22615 
22616             /* clear event */
22617             XMEMSET(&asyncDev->event, 0, sizeof(WOLF_EVENT));
22618 
22619             /* clear async dev */
22620             ssl->async.dev = NULL;
22621         }
22622     }
22623     else {
22624         ret = WC_NOT_PENDING_E;
22625     }
22626 
22627     WOLFSSL_LEAVE("wolfSSL_AsyncPop", ret);
22628 
22629     return ret;
22630 }
22631 
22632 int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev, word32 flags)
22633 {
22634     int ret;
22635     WOLF_EVENT* event;
22636 
22637     if (ssl == NULL || asyncDev == NULL) {
22638         return BAD_FUNC_ARG;
22639     }
22640 
22641     /* grab event pointer */
22642     event = &asyncDev->event;
22643 
22644     /* init event */
22645     ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, ssl, flags);
22646     if (ret == 0) {
22647         ssl->async.dev = asyncDev;
22648 
22649         /* place event into queue */
22650         ret = wolfAsync_EventQueuePush(&ssl->ctx->event_queue, event);
22651     }
22652 
22653     /* success means return WC_PENDING_E */
22654     if (ret == 0) {
22655         ret = WC_PENDING_E;
22656     }
22657 
22658     WOLFSSL_LEAVE("wolfSSL_AsyncPush", ret);
22659 
22660     return ret;
22661 }
22662 
22663 #endif /* WOLFSSL_ASYNC_CRYPT */
22664 
22665 
22666 #undef ERROR_OUT
22667 
22668 #endif /* WOLFCRYPT_ONLY */
22669