Renesas / SecureDweet
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     #include <wolfcrypt/src/misc.c>
00040 #endif
00041 
00042 #ifdef HAVE_LIBZ
00043     #include "zlib.h"
00044 #endif
00045 
00046 #ifdef HAVE_NTRU
00047     #include "libntruencrypt/ntru_crypto.h"
00048 #endif
00049 
00050 #if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
00051     #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
00052         #if MQX_USE_IO_OLD
00053             #include <fio.h>
00054         #else
00055             #include <nio.h>
00056         #endif
00057     #else
00058         #include <stdio.h>
00059     #endif
00060 #endif
00061 
00062 #ifdef __sun
00063     #include <sys/filio.h>
00064 #endif
00065 
00066 #ifndef TRUE
00067     #define TRUE  1
00068 #endif
00069 #ifndef FALSE
00070     #define FALSE 0
00071 #endif
00072 
00073 #ifdef _MSC_VER
00074     /* disable for while(0) cases at the .c level for now */
00075     #pragma warning(disable:4127)
00076 #endif
00077 
00078 #if defined(WOLFSSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
00079     #error \
00080 WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
00081 #endif
00082 
00083 #if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
00084     #error Cannot use both secure-renegotiation and renegotiation-indication
00085 #endif
00086 
00087 static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
00088                         const byte* input, int inSz, int type, int hashOutput);
00089 
00090 #ifndef NO_WOLFSSL_CLIENT
00091     static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
00092                                                                         word32);
00093     static int DoServerHello(WOLFSSL* ssl, const byte* input, word32*, word32);
00094     static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32*,
00095                                                                         word32);
00096     #ifndef NO_CERTS
00097         static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*,
00098                                                                         word32);
00099     #endif
00100     #ifdef HAVE_SESSION_TICKET
00101         static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32*,
00102                                                                         word32);
00103     #endif
00104 #endif
00105 
00106 
00107 #ifndef NO_WOLFSSL_SERVER
00108     static int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, word32);
00109     static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32);
00110     #if !defined(NO_RSA) || defined(HAVE_ECC)
00111         static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
00112     #endif
00113     #ifdef HAVE_STUNNEL
00114         static int SNI_Callback(WOLFSSL* ssl);
00115     #endif
00116     #ifdef WOLFSSL_DTLS
00117         static int SendHelloVerifyRequest(WOLFSSL*, const byte*, byte);
00118     #endif /* WOLFSSL_DTLS */
00119 #endif
00120 
00121 
00122 #ifdef WOLFSSL_DTLS
00123     static INLINE int DtlsCheckWindow(DtlsState* state);
00124     static INLINE int DtlsUpdateWindow(DtlsState* state);
00125 #endif
00126 
00127 
00128 typedef enum {
00129     doProcessInit = 0,
00130 #ifndef NO_WOLFSSL_SERVER
00131     runProcessOldClientHello,
00132 #endif
00133     getRecordLayerHeader,
00134     getData,
00135     runProcessingOneMessage
00136 } processReply;
00137 
00138 #ifndef NO_OLD_TLS
00139 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
00140                     int content, int verify);
00141 
00142 #endif
00143 
00144 #ifndef NO_CERTS
00145 static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes);
00146 #endif
00147 
00148 #ifdef HAVE_QSH
00149     int QSH_Init(WOLFSSL* ssl);
00150 #endif
00151 
00152 #ifndef WOLFSSL_HAVE_MIN
00153 #define WOLFSSL_HAVE_MIN
00154 
00155     static INLINE word32 min(word32 a, word32 b)
00156     {
00157         return a > b ? b : a;
00158     }
00159 
00160 #endif /* WOLFSSL_HAVE_MIN */
00161 
00162 
00163 int IsTLS(const WOLFSSL* ssl)
00164 {
00165     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
00166         return 1;
00167 
00168     return 0;
00169 }
00170 
00171 
00172 int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
00173 {
00174     if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
00175         return 1;
00176     if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
00177         return 1;
00178 
00179     return 0;
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.dtls_state.curEpoch == 0)
00190         return 0;
00191     #endif /* WOLFSSL_DTLS */
00192 
00193     return ssl->keys.encryptionOn;
00194 }
00195 
00196 
00197 #ifdef HAVE_QSH
00198 /* free all structs that where used with QSH */
00199 static int QSH_FreeAll(WOLFSSL* ssl)
00200 {
00201     QSHKey* key        = ssl->QSH_Key;
00202     QSHKey* preKey     = NULL;
00203     QSHSecret* secret  = ssl->QSH_secret;
00204     QSHScheme* list    = NULL;
00205     QSHScheme* preList = NULL;
00206 
00207     /* free elements in struct */
00208     while (key) {
00209         preKey = key;
00210         if (key->pri.buffer) {
00211             ForceZero(key->pri.buffer, key->pri.length);
00212             XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00213         }
00214         if (key->pub.buffer)
00215             XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00216         key = (QSHKey*)key->next;
00217 
00218         /* free struct */
00219         XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00220     }
00221     key = NULL;
00222 
00223 
00224     /* free all of peers QSH keys */
00225     key = ssl->peerQSHKey;
00226     while (key) {
00227         preKey = key;
00228         if (key->pri.buffer) {
00229             ForceZero(key->pri.buffer, key->pri.length);
00230             XFREE(key->pri.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00231         }
00232         if (key->pub.buffer)
00233             XFREE(key->pub.buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00234         key = (QSHKey*)key->next;
00235 
00236         /* free struct */
00237         XFREE(preKey, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00238     }
00239     key = NULL;
00240 
00241     /* free secret information */
00242     if (secret) {
00243         /* free up the QSHScheme list in QSHSecret */
00244         if (secret->list)
00245             list = secret->list;
00246         while (list) {
00247             preList = list;
00248             if (list->PK)
00249                 XFREE(list->PK, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00250             list = (QSHScheme*)list->next;
00251             XFREE(preList, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00252         }
00253 
00254         /* free secret buffers */
00255         if (secret->SerSi) {
00256             if (secret->SerSi->buffer) {
00257                 /* clear extra secret material that supplemented Master Secret*/
00258                 ForceZero(secret->SerSi->buffer, secret->SerSi->length);
00259                 XFREE(secret->SerSi->buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00260             }
00261             XFREE(secret->SerSi, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00262         }
00263         if (secret->CliSi) {
00264             if (secret->CliSi->buffer) {
00265                 /* clear extra secret material that supplemented Master Secret*/
00266                 ForceZero(secret->CliSi->buffer, secret->CliSi->length);
00267                 XFREE(secret->CliSi->buffer, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00268             }
00269             XFREE(secret->CliSi, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00270         }
00271     }
00272     XFREE(secret, ssl->heap, DYNAMIC_TYPE_TMP_ARRAY);
00273     secret = NULL;
00274 
00275     return 0;
00276 }
00277 #endif
00278 
00279 
00280 #ifdef HAVE_NTRU
00281 static WC_RNG* rng;
00282 static wolfSSL_Mutex* rngMutex;
00283 
00284 static word32 GetEntropy(unsigned char* out, word32 num_bytes)
00285 {
00286     int ret = 0;
00287 
00288     if (rng == NULL) {
00289         if ((rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), 0,
00290                                                     DYNAMIC_TYPE_TLSX)) == NULL)
00291             return DRBG_OUT_OF_MEMORY;
00292         wc_InitRng(rng);
00293     }
00294 
00295     if (rngMutex == NULL) {
00296         if ((rngMutex = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), 0,
00297                         DYNAMIC_TYPE_TLSX)) == NULL)
00298             return DRBG_OUT_OF_MEMORY;
00299         InitMutex(rngMutex);
00300     }
00301 
00302     ret |= LockMutex(rngMutex);
00303     ret |= wc_RNG_GenerateBlock(rng, out, num_bytes);
00304     ret |= UnLockMutex(rngMutex);
00305 
00306     if (ret != 0)
00307         return DRBG_ENTROPY_FAIL;
00308 
00309     return DRBG_OK;
00310 }
00311 #endif /* HAVE_NTRU */
00312 
00313 /* used by ssl.c too */
00314 void c32to24(word32 in, word24 out)
00315 {
00316     out[0] = (in >> 16) & 0xff;
00317     out[1] = (in >>  8) & 0xff;
00318     out[2] =  in & 0xff;
00319 }
00320 
00321 
00322 #ifdef WOLFSSL_DTLS
00323 
00324 static INLINE void c32to48(word32 in, byte out[6])
00325 {
00326     out[0] = 0;
00327     out[1] = 0;
00328     out[2] = (in >> 24) & 0xff;
00329     out[3] = (in >> 16) & 0xff;
00330     out[4] = (in >>  8) & 0xff;
00331     out[5] =  in & 0xff;
00332 }
00333 
00334 #endif /* WOLFSSL_DTLS */
00335 
00336 
00337 /* convert 16 bit integer to opaque */
00338 static INLINE void c16toa(word16 u16, byte* c)
00339 {
00340     c[0] = (u16 >> 8) & 0xff;
00341     c[1] =  u16 & 0xff;
00342 }
00343 
00344 
00345 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
00346     || defined(HAVE_AESGCM)
00347 /* convert 32 bit integer to opaque */
00348 static INLINE void c32toa(word32 u32, byte* c)
00349 {
00350     c[0] = (u32 >> 24) & 0xff;
00351     c[1] = (u32 >> 16) & 0xff;
00352     c[2] = (u32 >>  8) & 0xff;
00353     c[3] =  u32 & 0xff;
00354 }
00355 #endif
00356 
00357 
00358 /* convert a 24 bit integer into a 32 bit one */
00359 static INLINE void c24to32(const word24 u24, word32* u32)
00360 {
00361     *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
00362 }
00363 
00364 
00365 /* convert opaque to 16 bit integer */
00366 static INLINE void ato16(const byte* c, word16* u16)
00367 {
00368     *u16 = (word16) ((c[0] << 8) | (c[1]));
00369 }
00370 
00371 
00372 #if defined(WOLFSSL_DTLS) || defined(HAVE_SESSION_TICKET)
00373 
00374 /* convert opaque to 32 bit integer */
00375 static INLINE void ato32(const byte* c, word32* u32)
00376 {
00377     *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
00378 }
00379 
00380 #endif /* WOLFSSL_DTLS */
00381 
00382 
00383 #ifdef HAVE_LIBZ
00384 
00385     /* alloc user allocs to work with zlib */
00386     static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00387     {
00388         (void)opaque;
00389         return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00390     }
00391 
00392 
00393     static void myFree(void* opaque, void* memory)
00394     {
00395         (void)opaque;
00396         XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00397     }
00398 
00399 
00400     /* init zlib comp/decomp streams, 0 on success */
00401     static int InitStreams(WOLFSSL* ssl)
00402     {
00403         ssl->c_stream.zalloc = (alloc_func)myAlloc;
00404         ssl->c_stream.zfree  = (free_func)myFree;
00405         ssl->c_stream.opaque = (voidpf)ssl->heap;
00406 
00407         if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
00408             return ZLIB_INIT_ERROR;
00409 
00410         ssl->didStreamInit = 1;
00411 
00412         ssl->d_stream.zalloc = (alloc_func)myAlloc;
00413         ssl->d_stream.zfree  = (free_func)myFree;
00414         ssl->d_stream.opaque = (voidpf)ssl->heap;
00415 
00416         if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
00417 
00418         return 0;
00419     }
00420 
00421 
00422     static void FreeStreams(WOLFSSL* ssl)
00423     {
00424         if (ssl->didStreamInit) {
00425             deflateEnd(&ssl->c_stream);
00426             inflateEnd(&ssl->d_stream);
00427         }
00428     }
00429 
00430 
00431     /* compress in to out, return out size or error */
00432     static int myCompress(WOLFSSL* ssl, byte* in, int inSz, byte* out, int outSz)
00433     {
00434         int    err;
00435         int    currTotal = (int)ssl->c_stream.total_out;
00436 
00437         ssl->c_stream.next_in   = in;
00438         ssl->c_stream.avail_in  = inSz;
00439         ssl->c_stream.next_out  = out;
00440         ssl->c_stream.avail_out = outSz;
00441 
00442         err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
00443         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
00444 
00445         return (int)ssl->c_stream.total_out - currTotal;
00446     }
00447 
00448 
00449     /* decompress in to out, return out size or error */
00450     static int myDeCompress(WOLFSSL* ssl, byte* in,int inSz, byte* out,int outSz)
00451     {
00452         int    err;
00453         int    currTotal = (int)ssl->d_stream.total_out;
00454 
00455         ssl->d_stream.next_in   = in;
00456         ssl->d_stream.avail_in  = inSz;
00457         ssl->d_stream.next_out  = out;
00458         ssl->d_stream.avail_out = outSz;
00459 
00460         err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
00461         if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
00462 
00463         return (int)ssl->d_stream.total_out - currTotal;
00464     }
00465 
00466 #endif /* HAVE_LIBZ */
00467 
00468 
00469 void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv)
00470 {
00471     method->version    = pv;
00472     method->side       = WOLFSSL_CLIENT_END;
00473     method->downgrade  = 0;
00474 }
00475 
00476 
00477 /* Initialize SSL context, return 0 on success */
00478 int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
00479 {
00480     XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX));
00481 
00482     ctx->method   = method;
00483     ctx->refCount = 1;          /* so either CTX_free or SSL_free can release */
00484     ctx->heap     = ctx;        /* defaults to self */
00485     ctx->timeout  = WOLFSSL_SESSION_TIMEOUT;
00486     ctx->minDowngrade = TLSv1_MINOR;     /* current default */
00487 
00488     if (InitMutex(&ctx->countMutex) < 0) {
00489         WOLFSSL_MSG("Mutex error on CTX init");
00490         return BAD_MUTEX_E;
00491     }
00492 
00493 #ifndef NO_DH
00494     ctx->minDhKeySz = MIN_DHKEY_SZ;
00495 #endif
00496 
00497 #ifdef HAVE_ECC
00498     ctx->eccTempKeySz = ECDHE_SIZE;
00499 #endif
00500 
00501 #ifndef WOLFSSL_USER_IO
00502     ctx->CBIORecv = EmbedReceive;
00503     ctx->CBIOSend = EmbedSend;
00504     #ifdef WOLFSSL_DTLS
00505         if (method->version.major == DTLS_MAJOR) {
00506             ctx->CBIORecv   = EmbedReceiveFrom;
00507             ctx->CBIOSend   = EmbedSendTo;
00508         }
00509     #endif
00510 #endif /* WOLFSSL_USER_IO */
00511 
00512 #ifdef HAVE_NETX
00513     ctx->CBIORecv = NetX_Receive;
00514     ctx->CBIOSend = NetX_Send;
00515 #endif
00516 
00517 #ifdef HAVE_NTRU
00518     if (method->side == WOLFSSL_CLIENT_END)
00519         ctx->haveNTRU = 1;           /* always on cliet side */
00520                                      /* server can turn on by loading key */
00521 #endif
00522 #ifdef HAVE_ECC
00523     if (method->side == WOLFSSL_CLIENT_END) {
00524         ctx->haveECDSAsig  = 1;        /* always on cliet side */
00525         ctx->haveECC  = 1;             /* server turns on with ECC key cert */
00526         ctx->haveStaticECC = 1;        /* server can turn on by loading key */
00527     }
00528 #endif
00529 
00530 #ifdef HAVE_CAVIUM
00531     ctx->devId = NO_CAVIUM_DEVICE;
00532 #endif
00533 
00534 #ifndef NO_CERTS
00535     ctx->cm = wolfSSL_CertManagerNew();
00536     if (ctx->cm == NULL) {
00537         WOLFSSL_MSG("Bad Cert Manager New");
00538         return BAD_CERT_MANAGER_ERROR;
00539     }
00540 #endif
00541 
00542 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
00543     ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
00544 #endif
00545 
00546     return 0;
00547 }
00548 
00549 
00550 /* In case contexts are held in array and don't want to free actual ctx */
00551 void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
00552 {
00553     int i;
00554 
00555     (void)i;
00556 
00557     XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
00558     if (ctx->suites)
00559         XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
00560 
00561 #ifndef NO_DH
00562     XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00563     XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
00564 #endif
00565 
00566 #ifndef NO_CERTS
00567     FreeDer(&ctx->privateKey);
00568     FreeDer(&ctx->certificate);
00569     FreeDer(&ctx->certChain);
00570     wolfSSL_CertManagerFree(ctx->cm);
00571 #endif
00572 
00573 #ifdef HAVE_TLS_EXTENSIONS
00574     TLSX_FreeAll(ctx->extensions);
00575 
00576 #ifndef NO_WOLFSSL_SERVER
00577 
00578 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
00579  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
00580     if (ctx->certOcspRequest) {
00581         FreeOcspRequest(ctx->certOcspRequest);
00582         XFREE(ctx->certOcspRequest, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
00583     }
00584 #endif
00585 
00586 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
00587     for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
00588         if (ctx->chainOcspRequest[i]) {
00589             FreeOcspRequest(ctx->chainOcspRequest[i]);
00590             XFREE(ctx->chainOcspRequest[i], NULL, DYNAMIC_TYPE_OCSP_REQUEST);
00591         }
00592     }
00593 #endif
00594 
00595 #endif /* NO_WOLFSSL_SERVER */
00596 
00597 #endif /* HAVE_TLS_EXTENSIONS */
00598 }
00599 
00600 
00601 void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
00602 {
00603     int doFree = 0;
00604 
00605     if (LockMutex(&ctx->countMutex) != 0) {
00606         WOLFSSL_MSG("Couldn't lock count mutex");
00607         return;
00608     }
00609     ctx->refCount--;
00610     if (ctx->refCount == 0)
00611         doFree = 1;
00612     UnLockMutex(&ctx->countMutex);
00613 
00614     if (doFree) {
00615         WOLFSSL_MSG("CTX ref count down to 0, doing full free");
00616         SSL_CtxResourceFree(ctx);
00617         FreeMutex(&ctx->countMutex);
00618         XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
00619     }
00620     else {
00621         (void)ctx;
00622         WOLFSSL_MSG("CTX ref count not 0 yet, no free");
00623     }
00624 }
00625 
00626 
00627 /* Set cipher pointers to null */
00628 void InitCiphers(WOLFSSL* ssl)
00629 {
00630 #ifdef BUILD_ARC4
00631     ssl->encrypt.arc4 = NULL;
00632     ssl->decrypt.arc4 = NULL;
00633 #endif
00634 #ifdef BUILD_DES3
00635     ssl->encrypt.des3 = NULL;
00636     ssl->decrypt.des3 = NULL;
00637 #endif
00638 #ifdef BUILD_AES
00639     ssl->encrypt.aes = NULL;
00640     ssl->decrypt.aes = NULL;
00641 #endif
00642 #ifdef HAVE_CAMELLIA
00643     ssl->encrypt.cam = NULL;
00644     ssl->decrypt.cam = NULL;
00645 #endif
00646 #ifdef HAVE_HC128
00647     ssl->encrypt.hc128 = NULL;
00648     ssl->decrypt.hc128 = NULL;
00649 #endif
00650 #ifdef BUILD_RABBIT
00651     ssl->encrypt.rabbit = NULL;
00652     ssl->decrypt.rabbit = NULL;
00653 #endif
00654 #ifdef HAVE_CHACHA
00655     ssl->encrypt.chacha = NULL;
00656     ssl->decrypt.chacha = NULL;
00657 #endif
00658 #ifdef HAVE_POLY1305
00659     ssl->auth.poly1305 = NULL;
00660 #endif
00661     ssl->encrypt.setup = 0;
00662     ssl->decrypt.setup = 0;
00663 #ifdef HAVE_ONE_TIME_AUTH
00664     ssl->auth.setup    = 0;
00665 #endif
00666 #ifdef HAVE_IDEA
00667     ssl->encrypt.idea = NULL;
00668     ssl->decrypt.idea = NULL;
00669 #endif
00670 }
00671 
00672 
00673 /* Free ciphers */
00674 void FreeCiphers(WOLFSSL* ssl)
00675 {
00676     (void)ssl;
00677 #ifdef BUILD_ARC4
00678     #ifdef HAVE_CAVIUM
00679     if (ssl->devId != NO_CAVIUM_DEVICE) {
00680         wc_Arc4FreeCavium(ssl->encrypt.arc4);
00681         wc_Arc4FreeCavium(ssl->decrypt.arc4);
00682     }
00683     #endif
00684     XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00685     XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
00686 #endif
00687 #ifdef BUILD_DES3
00688     #ifdef HAVE_CAVIUM
00689     if (ssl->devId != NO_CAVIUM_DEVICE) {
00690         wc_Des3_FreeCavium(ssl->encrypt.des3);
00691         wc_Des3_FreeCavium(ssl->decrypt.des3);
00692     }
00693     #endif
00694     XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00695     XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
00696 #endif
00697 #ifdef BUILD_AES
00698     #ifdef HAVE_CAVIUM
00699     if (ssl->devId != NO_CAVIUM_DEVICE) {
00700         wc_AesFreeCavium(ssl->encrypt.aes);
00701         wc_AesFreeCavium(ssl->decrypt.aes);
00702     }
00703     #endif
00704     XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00705     XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
00706 #endif
00707 #ifdef HAVE_CAMELLIA
00708     XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00709     XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
00710 #endif
00711 #ifdef HAVE_HC128
00712     XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00713     XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
00714 #endif
00715 #ifdef BUILD_RABBIT
00716     XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00717     XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
00718 #endif
00719 #ifdef HAVE_CHACHA
00720     XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
00721     XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
00722 #endif
00723 #ifdef HAVE_POLY1305
00724     XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
00725 #endif
00726 #ifdef HAVE_IDEA
00727     XFREE(ssl->encrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
00728     XFREE(ssl->decrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
00729 #endif
00730 }
00731 
00732 
00733 void InitCipherSpecs(CipherSpecs* cs)
00734 {
00735     cs->bulk_cipher_algorithm = INVALID_BYTE;
00736     cs->cipher_type           = INVALID_BYTE;
00737     cs->mac_algorithm         = INVALID_BYTE;
00738     cs->kea                   = INVALID_BYTE;
00739     cs->sig_algo              = INVALID_BYTE;
00740 
00741     cs->hash_size   = 0;
00742     cs->static_ecdh = 0;
00743     cs->key_size    = 0;
00744     cs->iv_size     = 0;
00745     cs->block_size  = 0;
00746 }
00747 
00748 static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
00749                                                   int haveRSAsig, int haveAnon)
00750 {
00751     int idx = 0;
00752 
00753     if (haveECDSAsig) {
00754         #ifdef WOLFSSL_SHA512
00755             suites->hashSigAlgo[idx++] = sha512_mac;
00756             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00757         #endif
00758         #ifdef WOLFSSL_SHA384
00759             suites->hashSigAlgo[idx++] = sha384_mac;
00760             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00761         #endif
00762         #ifndef NO_SHA256
00763             suites->hashSigAlgo[idx++] = sha256_mac;
00764             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00765         #endif
00766         #ifndef NO_SHA
00767             suites->hashSigAlgo[idx++] = sha_mac;
00768             suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
00769         #endif
00770     }
00771 
00772     if (haveRSAsig) {
00773         #ifdef WOLFSSL_SHA512
00774             suites->hashSigAlgo[idx++] = sha512_mac;
00775             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00776         #endif
00777         #ifdef WOLFSSL_SHA384
00778             suites->hashSigAlgo[idx++] = sha384_mac;
00779             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00780         #endif
00781         #ifndef NO_SHA256
00782             suites->hashSigAlgo[idx++] = sha256_mac;
00783             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00784         #endif
00785         #ifndef NO_SHA
00786             suites->hashSigAlgo[idx++] = sha_mac;
00787             suites->hashSigAlgo[idx++] = rsa_sa_algo;
00788         #endif
00789     }
00790 
00791     if (haveAnon) {
00792         #ifdef HAVE_ANON
00793             suites->hashSigAlgo[idx++] = sha_mac;
00794             suites->hashSigAlgo[idx++] = anonymous_sa_algo;
00795         #endif
00796     }
00797 
00798     suites->hashSigAlgoSz = (word16)idx;
00799 }
00800 
00801 void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA,
00802                 word16 havePSK, word16 haveDH, word16 haveNTRU,
00803                 word16 haveECDSAsig, word16 haveECC,
00804                 word16 haveStaticECC, int side)
00805 {
00806     word16 idx = 0;
00807     int    tls    = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
00808     int    tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
00809     int    dtls   = 0;
00810     int    haveRSAsig = 1;
00811 
00812     (void)tls;  /* shut up compiler */
00813     (void)tls1_2;
00814     (void)dtls;
00815     (void)haveDH;
00816     (void)havePSK;
00817     (void)haveNTRU;
00818     (void)haveStaticECC;
00819     (void)haveECC;
00820 
00821     if (suites == NULL) {
00822         WOLFSSL_MSG("InitSuites pointer error");
00823         return;
00824     }
00825 
00826     if (suites->setSuites)
00827         return;      /* trust user settings, don't override */
00828 
00829     if (side == WOLFSSL_SERVER_END && haveStaticECC) {
00830         haveRSA = 0;   /* can't do RSA with ECDSA key */
00831         (void)haveRSA; /* some builds won't read */
00832     }
00833 
00834     if (side == WOLFSSL_SERVER_END && haveECDSAsig) {
00835         haveRSAsig = 0;     /* can't have RSA sig if signed by ECDSA */
00836         (void)haveRSAsig;   /* non ecc builds won't read */
00837     }
00838 
00839 #ifdef WOLFSSL_DTLS
00840     if (pv.major == DTLS_MAJOR) {
00841         dtls   = 1;
00842         tls    = 1;
00843         /* May be dead assignments dependant upon configuration */
00844         (void) dtls;
00845         (void) tls;
00846         tls1_2 = pv.minor <= DTLSv1_2_MINOR;
00847     }
00848 #endif
00849 
00850 #ifdef HAVE_RENEGOTIATION_INDICATION
00851     if (side == WOLFSSL_CLIENT_END) {
00852         suites->suites[idx++] = 0;
00853         suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
00854     }
00855 #endif
00856 
00857 #ifdef BUILD_TLS_QSH
00858     if (tls) {
00859         suites->suites[idx++] = QSH_BYTE;
00860         suites->suites[idx++] = TLS_QSH;
00861     }
00862 #endif
00863 
00864 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
00865    if (tls && haveNTRU && haveRSA) {
00866         suites->suites[idx++] = 0;
00867         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
00868    }
00869 #endif
00870 
00871 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
00872     if (tls && haveNTRU && haveRSA) {
00873         suites->suites[idx++] = 0;
00874         suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
00875     }
00876 #endif
00877 
00878 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
00879     if (!dtls && tls && haveNTRU && haveRSA) {
00880         suites->suites[idx++] = 0;
00881         suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
00882     }
00883 #endif
00884 
00885 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
00886     if (tls && haveNTRU && haveRSA) {
00887         suites->suites[idx++] = 0;
00888         suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
00889     }
00890 #endif
00891 
00892 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
00893     if (tls1_2 && haveECC) {
00894         suites->suites[idx++] = ECC_BYTE;
00895         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
00896     }
00897 #endif
00898 
00899 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
00900     if (tls1_2 && haveECC) {
00901         suites->suites[idx++] = ECC_BYTE;
00902         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
00903     }
00904 #endif
00905 
00906 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
00907     if (tls1_2 && haveRSA) {
00908         suites->suites[idx++] = ECC_BYTE;
00909         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
00910     }
00911 #endif
00912 
00913 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
00914     if (tls1_2 && haveRSA) {
00915         suites->suites[idx++] = ECC_BYTE;
00916         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
00917     }
00918 #endif
00919 
00920 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
00921     if (tls1_2 && haveDH && haveRSA) {
00922         suites->suites[idx++] = 0;
00923         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
00924     }
00925 #endif
00926 
00927 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
00928     if (tls1_2 && haveDH && haveRSA) {
00929         suites->suites[idx++] = 0;
00930         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
00931     }
00932 #endif
00933 
00934 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
00935     if (tls1_2 && haveRSA) {
00936         suites->suites[idx++] = 0;
00937         suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
00938     }
00939 #endif
00940 
00941 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
00942     if (tls1_2 && haveRSA) {
00943         suites->suites[idx++] = 0;
00944         suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
00945     }
00946 #endif
00947 
00948 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
00949     if (tls1_2 && haveECC && haveStaticECC) {
00950         suites->suites[idx++] = ECC_BYTE;
00951         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
00952     }
00953 #endif
00954 
00955 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
00956     if (tls1_2 && haveECC && haveStaticECC) {
00957         suites->suites[idx++] = ECC_BYTE;
00958         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
00959     }
00960 #endif
00961 
00962 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
00963     if (tls1_2 && haveRSAsig && haveStaticECC) {
00964         suites->suites[idx++] = ECC_BYTE;
00965         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
00966     }
00967 #endif
00968 
00969 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
00970     if (tls1_2 && haveRSAsig && haveStaticECC) {
00971         suites->suites[idx++] = ECC_BYTE;
00972         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
00973     }
00974 #endif
00975 
00976 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
00977     if (tls1_2 && haveDH && havePSK) {
00978         suites->suites[idx++] = 0;
00979         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
00980     }
00981 #endif
00982 
00983 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
00984     if (tls1_2 && haveDH && havePSK) {
00985         suites->suites[idx++] = 0;
00986         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
00987     }
00988 #endif
00989 
00990 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
00991     if (tls1_2 && havePSK) {
00992         suites->suites[idx++] = 0;
00993         suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
00994     }
00995 #endif
00996 
00997 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
00998     if (tls1_2 && havePSK) {
00999         suites->suites[idx++] = 0;
01000         suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
01001     }
01002 #endif
01003 
01004 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
01005     if (tls1_2 && haveECC) {
01006         suites->suites[idx++] = CHACHA_BYTE;
01007         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
01008     }
01009 #endif
01010 
01011 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
01012     if (tls1_2 && haveRSA) {
01013         suites->suites[idx++] = CHACHA_BYTE;
01014         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
01015     }
01016 #endif
01017 
01018 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
01019     if (tls1_2 && haveRSA) {
01020         suites->suites[idx++] = CHACHA_BYTE;
01021         suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
01022     }
01023 #endif
01024 
01025 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
01026     if (tls1_2 && haveRSAsig) {
01027         suites->suites[idx++] = ECC_BYTE;
01028         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
01029     }
01030 #endif
01031 
01032 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
01033     if (tls1_2 && haveECC) {
01034         suites->suites[idx++] = ECC_BYTE;
01035         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
01036     }
01037 #endif
01038 
01039 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
01040     if (tls1_2 && haveRSAsig && haveStaticECC) {
01041         suites->suites[idx++] = ECC_BYTE;
01042         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
01043     }
01044 #endif
01045 
01046 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
01047     if (tls1_2 && haveECC && haveStaticECC) {
01048         suites->suites[idx++] = ECC_BYTE;
01049         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
01050     }
01051 #endif
01052 
01053 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
01054     if (tls1_2 && haveRSAsig) {
01055         suites->suites[idx++] = ECC_BYTE;
01056         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
01057     }
01058 #endif
01059 
01060 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
01061     if (tls1_2 && haveECC) {
01062         suites->suites[idx++] = ECC_BYTE;
01063         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
01064     }
01065 #endif
01066 
01067 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
01068     if (tls1_2 && haveRSAsig && haveStaticECC) {
01069         suites->suites[idx++] = ECC_BYTE;
01070         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
01071     }
01072 #endif
01073 
01074 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
01075     if (tls1_2 && haveECC && haveStaticECC) {
01076         suites->suites[idx++] = ECC_BYTE;
01077         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
01078     }
01079 #endif
01080 
01081 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
01082     if (tls && haveECC) {
01083         suites->suites[idx++] = ECC_BYTE;
01084         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
01085     }
01086 #endif
01087 
01088 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
01089     if (tls && haveECC && haveStaticECC) {
01090         suites->suites[idx++] = ECC_BYTE;
01091         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
01092     }
01093 #endif
01094 
01095 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
01096     if (tls && haveECC) {
01097         suites->suites[idx++] = ECC_BYTE;
01098         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
01099     }
01100 #endif
01101 
01102 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
01103     if (tls && haveECC && haveStaticECC) {
01104         suites->suites[idx++] = ECC_BYTE;
01105         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
01106     }
01107 #endif
01108 
01109 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
01110     if (!dtls && tls && haveECC) {
01111         suites->suites[idx++] = ECC_BYTE;
01112         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
01113     }
01114 #endif
01115 
01116 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
01117     if (!dtls && tls && haveECC && haveStaticECC) {
01118         suites->suites[idx++] = ECC_BYTE;
01119         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
01120     }
01121 #endif
01122 
01123 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
01124     if (tls && haveECC) {
01125         suites->suites[idx++] = ECC_BYTE;
01126         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
01127     }
01128 #endif
01129 
01130 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
01131     if (tls && haveECC && haveStaticECC) {
01132         suites->suites[idx++] = ECC_BYTE;
01133         suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
01134     }
01135 #endif
01136 
01137 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
01138     if (tls && haveRSA) {
01139         suites->suites[idx++] = ECC_BYTE;
01140         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
01141     }
01142 #endif
01143 
01144 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
01145     if (tls && haveRSAsig && haveStaticECC) {
01146         suites->suites[idx++] = ECC_BYTE;
01147         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
01148     }
01149 #endif
01150 
01151 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
01152     if (tls && haveRSA) {
01153         suites->suites[idx++] = ECC_BYTE;
01154         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
01155     }
01156 #endif
01157 
01158 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
01159     if (tls && haveRSAsig && haveStaticECC) {
01160         suites->suites[idx++] = ECC_BYTE;
01161         suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
01162     }
01163 #endif
01164 
01165 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
01166     if (!dtls && tls && haveRSA) {
01167         suites->suites[idx++] = ECC_BYTE;
01168         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
01169     }
01170 #endif
01171 
01172 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
01173     if (!dtls && tls && haveRSAsig && haveStaticECC) {
01174         suites->suites[idx++] = ECC_BYTE;
01175         suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
01176     }
01177 #endif
01178 
01179 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
01180     if (tls && haveRSA) {
01181         suites->suites[idx++] = ECC_BYTE;
01182         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
01183     }
01184 #endif
01185 
01186 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
01187     if (tls && haveRSAsig && haveStaticECC) {
01188         suites->suites[idx++] = ECC_BYTE;
01189         suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
01190     }
01191 #endif
01192 
01193 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
01194     if (tls1_2 && haveECC) {
01195         suites->suites[idx++] = ECC_BYTE;
01196         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
01197     }
01198 #endif
01199 
01200 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
01201     if (tls1_2 && haveECC) {
01202         suites->suites[idx++] = ECC_BYTE;
01203         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
01204     }
01205 #endif
01206 
01207 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
01208     if (tls1_2 && haveRSA) {
01209         suites->suites[idx++] = ECC_BYTE;
01210         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
01211     }
01212 #endif
01213 
01214 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
01215     if (tls1_2 && haveRSA) {
01216         suites->suites[idx++] = ECC_BYTE;
01217         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
01218     }
01219 #endif
01220 
01221 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
01222     if (tls1_2 && haveDH && haveRSA) {
01223         suites->suites[idx++] = 0;
01224         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
01225     }
01226 #endif
01227 
01228 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
01229     if (tls1_2 && haveDH && haveRSA) {
01230         suites->suites[idx++] = 0;
01231         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
01232     }
01233 #endif
01234 
01235 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
01236     if (tls && haveDH && haveRSA) {
01237         suites->suites[idx++] = 0;
01238         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
01239     }
01240 #endif
01241 
01242 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
01243     if (tls && haveDH && haveRSA) {
01244         suites->suites[idx++] = 0;
01245         suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
01246     }
01247 #endif
01248 
01249 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
01250     if (tls1_2 && haveRSA) {
01251         suites->suites[idx++] = 0;
01252         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
01253     }
01254 #endif
01255 
01256 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
01257     if (tls1_2 && haveRSA) {
01258         suites->suites[idx++] = 0;
01259         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
01260     }
01261 #endif
01262 
01263 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
01264     if (tls && haveRSA) {
01265         suites->suites[idx++] = 0;
01266         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
01267     }
01268 #endif
01269 
01270 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
01271     if (tls && haveRSA) {
01272         suites->suites[idx++] = 0;
01273         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
01274     }
01275 #endif
01276 
01277 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
01278     if (tls1_2 && haveECC) {
01279         suites->suites[idx++] = CHACHA_BYTE;
01280         suites->suites[idx++] =
01281                               TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
01282     }
01283 #endif
01284 
01285 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
01286     if (tls1_2 && haveRSA) {
01287         suites->suites[idx++] = CHACHA_BYTE;
01288         suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
01289     }
01290 #endif
01291 
01292 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
01293     if (tls1_2 && haveRSA) {
01294         suites->suites[idx++] = CHACHA_BYTE;
01295         suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256;
01296     }
01297 #endif
01298 
01299 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
01300     if (tls && haveECC) {
01301         suites->suites[idx++] = ECC_BYTE;
01302         suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_NULL_SHA;
01303     }
01304 #endif
01305 
01306 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
01307     if (tls && haveRSA) {
01308         suites->suites[idx++] = 0;
01309         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
01310     }
01311 #endif
01312 
01313 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
01314     if (tls && haveRSA) {
01315         suites->suites[idx++] = 0;
01316         suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
01317     }
01318 #endif
01319 
01320 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
01321     if (tls && havePSK) {
01322         suites->suites[idx++] = 0;
01323         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
01324     }
01325 #endif
01326 
01327 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
01328     if (tls && haveDH && havePSK) {
01329         suites->suites[idx++] = 0;
01330         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
01331     }
01332 #endif
01333 
01334 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
01335     if (tls && havePSK) {
01336         suites->suites[idx++] = 0;
01337         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
01338     }
01339 #endif
01340 
01341 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
01342     if (tls && haveDH && havePSK) {
01343         suites->suites[idx++] = 0;
01344         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
01345     }
01346 #endif
01347 
01348 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
01349     if (tls && havePSK) {
01350         suites->suites[idx++] = 0;
01351         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
01352     }
01353 #endif
01354 
01355 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
01356     if (tls && havePSK) {
01357         suites->suites[idx++] = 0;
01358         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
01359     }
01360 #endif
01361 
01362 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
01363     if (tls && haveDH && havePSK) {
01364         suites->suites[idx++] = ECC_BYTE;
01365         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
01366     }
01367 #endif
01368 
01369 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
01370     if (tls && haveDH && havePSK) {
01371         suites->suites[idx++] = ECC_BYTE;
01372         suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
01373     }
01374 #endif
01375 
01376 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
01377     if (tls && havePSK) {
01378         suites->suites[idx++] = CHACHA_BYTE;
01379         suites->suites[idx++] = TLS_PSK_WITH_CHACHA20_POLY1305_SHA256;
01380     }
01381 #endif
01382 
01383 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
01384     if (tls && havePSK) {
01385         suites->suites[idx++] = CHACHA_BYTE;
01386         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
01387     }
01388 #endif
01389 
01390 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
01391     if (tls && havePSK) {
01392         suites->suites[idx++] = CHACHA_BYTE;
01393         suites->suites[idx++] = TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
01394     }
01395 #endif
01396 
01397 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
01398     if (tls && havePSK) {
01399         suites->suites[idx++] = ECC_BYTE;
01400         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
01401     }
01402 #endif
01403 
01404 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
01405     if (tls && havePSK) {
01406         suites->suites[idx++] = ECC_BYTE;
01407         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
01408     }
01409 #endif
01410 
01411 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
01412     if (tls && havePSK) {
01413         suites->suites[idx++] = ECC_BYTE;
01414         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
01415     }
01416 #endif
01417 
01418 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
01419     if (tls && havePSK) {
01420         suites->suites[idx++] = ECC_BYTE;
01421         suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
01422     }
01423 #endif
01424 
01425 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
01426     if (tls && havePSK) {
01427         suites->suites[idx++] = ECC_BYTE;
01428         suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
01429     }
01430 #endif
01431 
01432 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
01433     if (tls && haveDH && havePSK) {
01434         suites->suites[idx++] = 0;
01435         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
01436     }
01437 #endif
01438 
01439 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
01440     if (tls && havePSK) {
01441         suites->suites[idx++] = 0;
01442         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
01443     }
01444 #endif
01445 
01446 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
01447     if (tls && havePSK) {
01448         suites->suites[idx++] = ECC_BYTE;
01449         suites->suites[idx++] = TLS_ECDHE_PSK_WITH_NULL_SHA256;
01450     }
01451 #endif
01452 
01453 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
01454     if (tls && haveDH && havePSK) {
01455         suites->suites[idx++] = 0;
01456         suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
01457     }
01458 #endif
01459 
01460 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
01461     if (tls && havePSK) {
01462         suites->suites[idx++] = 0;
01463         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
01464     }
01465 #endif
01466 
01467 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
01468     if (tls && havePSK) {
01469         suites->suites[idx++] = 0;
01470         suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
01471     }
01472 #endif
01473 
01474 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
01475     if (!dtls && haveRSA) {
01476         suites->suites[idx++] = 0;
01477         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
01478     }
01479 #endif
01480 
01481 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
01482     if (!dtls && haveRSA) {
01483         suites->suites[idx++] = 0;
01484         suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
01485     }
01486 #endif
01487 
01488 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
01489     if (haveRSA ) {
01490         suites->suites[idx++] = 0;
01491         suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
01492     }
01493 #endif
01494 
01495 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
01496     if (!dtls && tls && haveRSA) {
01497         suites->suites[idx++] = 0;
01498         suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
01499     }
01500 #endif
01501 
01502 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
01503     if (!dtls && tls && haveRSA) {
01504         suites->suites[idx++] = 0;
01505         suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
01506     }
01507 #endif
01508 
01509 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
01510     if (!dtls && tls && haveRSA) {
01511         suites->suites[idx++] = 0;
01512         suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
01513     }
01514 #endif
01515 
01516 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
01517     if (tls && haveRSA) {
01518         suites->suites[idx++] = 0;
01519         suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
01520     }
01521 #endif
01522 
01523 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
01524     if (tls && haveRSA) {
01525         suites->suites[idx++] = 0;
01526         suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
01527     }
01528 #endif
01529 
01530 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
01531     if (!dtls && tls && haveRSA) {
01532         suites->suites[idx++] = 0;
01533         suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
01534     }
01535 #endif
01536 
01537 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
01538     if (tls && haveRSA) {
01539         suites->suites[idx++] = 0;
01540         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
01541     }
01542 #endif
01543 
01544 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
01545     if (tls && haveDH && haveRSA) {
01546         suites->suites[idx++] = 0;
01547         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
01548     }
01549 #endif
01550 
01551 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
01552     if (tls && haveRSA) {
01553         suites->suites[idx++] = 0;
01554         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
01555     }
01556 #endif
01557 
01558 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
01559     if (tls && haveDH && haveRSA) {
01560         suites->suites[idx++] = 0;
01561         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
01562     }
01563 #endif
01564 
01565 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
01566     if (tls && haveRSA) {
01567         suites->suites[idx++] = 0;
01568         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01569     }
01570 #endif
01571 
01572 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
01573     if (tls && haveDH && haveRSA) {
01574         suites->suites[idx++] = 0;
01575         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
01576     }
01577 #endif
01578 
01579 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
01580     if (tls && haveRSA) {
01581         suites->suites[idx++] = 0;
01582         suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01583     }
01584 #endif
01585 
01586 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
01587     if (tls && haveDH && haveRSA) {
01588         suites->suites[idx++] = 0;
01589         suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
01590     }
01591 #endif
01592 
01593 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
01594     if (haveRSA) {
01595         suites->suites[idx++] = 0;
01596         suites->suites[idx++] = SSL_RSA_WITH_IDEA_CBC_SHA;
01597     }
01598 #endif
01599 
01600     suites->suiteSz = idx;
01601 
01602     InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
01603 }
01604 
01605 
01606 #ifndef NO_CERTS
01607 
01608 
01609 void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
01610 {
01611     (void)dynamicFlag;
01612 
01613     if (name != NULL) {
01614         name->name        = name->staticName;
01615         name->dynamicName = 0;
01616 #ifdef OPENSSL_EXTRA
01617         XMEMSET(&name->fullName, 0, sizeof(DecodedName));
01618 #endif /* OPENSSL_EXTRA */
01619     }
01620 }
01621 
01622 
01623 void FreeX509Name(WOLFSSL_X509_NAME* name)
01624 {
01625     if (name != NULL) {
01626         if (name->dynamicName)
01627             XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
01628 #ifdef OPENSSL_EXTRA
01629         if (name->fullName.fullName != NULL)
01630             XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
01631 #endif /* OPENSSL_EXTRA */
01632     }
01633 }
01634 
01635 
01636 /* Initialize wolfSSL X509 type */
01637 void InitX509(WOLFSSL_X509* x509, int dynamicFlag)
01638 {
01639     InitX509Name(&x509->issuer, 0);
01640     InitX509Name(&x509->subject, 0);
01641     x509->version        = 0;
01642     x509->pubKey.buffer  = NULL;
01643     x509->sig.buffer     = NULL;
01644     x509->derCert        = NULL;
01645     x509->altNames       = NULL;
01646     x509->altNamesNext   = NULL;
01647     x509->dynamicMemory  = (byte)dynamicFlag;
01648     x509->isCa           = 0;
01649 #ifdef HAVE_ECC
01650     x509->pkCurveOID = 0;
01651 #endif /* HAVE_ECC */
01652 #ifdef OPENSSL_EXTRA
01653     x509->pathLength     = 0;
01654     x509->basicConstSet  = 0;
01655     x509->basicConstCrit = 0;
01656     x509->basicConstPlSet = 0;
01657     x509->subjAltNameSet = 0;
01658     x509->subjAltNameCrit = 0;
01659     x509->authKeyIdSet   = 0;
01660     x509->authKeyIdCrit  = 0;
01661     x509->authKeyId      = NULL;
01662     x509->authKeyIdSz    = 0;
01663     x509->subjKeyIdSet   = 0;
01664     x509->subjKeyIdCrit  = 0;
01665     x509->subjKeyId      = NULL;
01666     x509->subjKeyIdSz    = 0;
01667     x509->keyUsageSet    = 0;
01668     x509->keyUsageCrit   = 0;
01669     x509->keyUsage       = 0;
01670     #ifdef WOLFSSL_SEP
01671         x509->certPolicySet  = 0;
01672         x509->certPolicyCrit = 0;
01673     #endif /* WOLFSSL_SEP */
01674 #endif /* OPENSSL_EXTRA */
01675 }
01676 
01677 
01678 /* Free wolfSSL X509 type */
01679 void FreeX509(WOLFSSL_X509* x509)
01680 {
01681     if (x509 == NULL)
01682         return;
01683 
01684     FreeX509Name(&x509->issuer);
01685     FreeX509Name(&x509->subject);
01686     if (x509->pubKey.buffer)
01687         XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
01688     FreeDer(&x509->derCert);
01689     XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
01690     #ifdef OPENSSL_EXTRA
01691         XFREE(x509->authKeyId, NULL, DYNAMIC_TYPE_X509_EXT);
01692         XFREE(x509->subjKeyId, NULL, DYNAMIC_TYPE_X509_EXT);
01693     #endif /* OPENSSL_EXTRA */
01694     if (x509->altNames)
01695         FreeAltNames(x509->altNames, NULL);
01696 }
01697 
01698 
01699 #ifndef NO_RSA
01700 
01701 /* Verify RSA signature, 0 on success */
01702 int VerifyRsaSign(const byte* sig, word32 sigSz,
01703                   const byte* plain, word32 plainSz, RsaKey* key)
01704 {
01705     #ifdef WOLFSSL_SMALL_STACK
01706         byte* verifySig = NULL;
01707     #else
01708         byte verifySig[ENCRYPT_LEN];
01709     #endif
01710     byte* out = NULL;  /* inline result */
01711     int   ret;
01712 
01713     WOLFSSL_ENTER("VerifyRsaSign");
01714 
01715     if (sig == NULL || plain == NULL || key == NULL) {
01716         WOLFSSL_MSG("Null pointer input");
01717         return BAD_FUNC_ARG;
01718     }
01719 
01720     if (sigSz > ENCRYPT_LEN) {
01721         WOLFSSL_MSG("Signature buffer too big");
01722         return BUFFER_E;
01723     }
01724 
01725     #ifdef WOLFSSL_SMALL_STACK
01726         verifySig = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
01727                                    DYNAMIC_TYPE_SIGNATURE);
01728         if (verifySig == NULL)
01729             return MEMORY_ERROR;
01730     #endif
01731 
01732     XMEMCPY(verifySig, sig, sigSz);
01733     ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key);
01734 
01735     if (ret != (int)plainSz || !out || XMEMCMP(plain, out, plainSz) != 0) {
01736         WOLFSSL_MSG("RSA Signature verification failed");
01737         ret = RSA_SIGN_FAULT;
01738     } else {
01739         ret = 0;  /* RSA reset */
01740     }
01741 
01742     #ifdef WOLFSSL_SMALL_STACK
01743         XFREE(verifySig, NULL, DYNAMIC_TYPE_SIGNATURE);
01744     #endif
01745 
01746     return ret;
01747 }
01748 
01749 #endif /* NO_RSA */
01750 
01751 #endif /* NO_CERTS */
01752 
01753 
01754 /* This function inherits a WOLFSSL_CTX's fields into an SSL object.
01755    It is used during initialization and to switch an ssl's CTX with
01756    wolfSSL_Set_SSL_CTX.  Requires ssl->suites alloc and ssl-arrays with PSK
01757    SSL_SUCCESS return value on success */
01758 int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
01759 {
01760     byte havePSK = 0;
01761     byte haveAnon = 0;
01762     byte newSSL;
01763     byte haveRSA = 0;
01764     (void) haveAnon; /* Squash unused var warnings */
01765 
01766     if(!ssl || !ctx || ssl->suites == NULL)
01767         return BAD_FUNC_ARG;
01768 
01769     newSSL = ssl->ctx == NULL; /* Assign after null check */
01770 
01771 #ifndef NO_PSK
01772     if (ctx->server_hint[0] && ssl->arrays == NULL) {
01773         return BAD_FUNC_ARG;  /* needed for copy below */
01774     }
01775 #endif
01776 
01777 
01778 #ifndef NO_RSA
01779     haveRSA = 1;
01780 #endif
01781 #ifndef NO_PSK
01782     havePSK = ctx->havePSK;
01783 #endif /* NO_PSK */
01784 #ifdef HAVE_ANON
01785     haveAnon = ctx->haveAnon;
01786 #endif /* HAVE_ANON*/
01787 
01788     /* decrement previous CTX reference count if exists.
01789      * This should only happen if switching ctxs!*/
01790     if (!newSSL) {
01791         WOLFSSL_MSG("freeing old ctx to decrement reference count. Switching ctx.");
01792         wolfSSL_CTX_free(ssl->ctx);
01793     }
01794 
01795     /* increment CTX reference count */
01796     if (LockMutex(&ctx->countMutex) != 0) {
01797         WOLFSSL_MSG("Couldn't lock CTX count mutex");
01798         return BAD_MUTEX_E;
01799     }
01800     ctx->refCount++;
01801     UnLockMutex(&ctx->countMutex);
01802     ssl->ctx     = ctx; /* only for passing to calls, options could change */
01803     ssl->version = ctx->method->version;
01804 
01805 #ifdef HAVE_ECC
01806     ssl->eccTempKeySz = ctx->eccTempKeySz;
01807     ssl->pkCurveOID = ctx->pkCurveOID;
01808 #endif
01809 
01810     ssl->timeout = ctx->timeout;
01811     ssl->verifyCallback    = ctx->verifyCallback;
01812     ssl->options.side      = ctx->method->side;
01813     ssl->options.downgrade    = ctx->method->downgrade;
01814     ssl->options.minDowngrade = ctx->minDowngrade;
01815 
01816     if (ssl->options.side == WOLFSSL_SERVER_END)
01817         ssl->options.haveDH = ctx->haveDH;
01818 
01819     ssl->options.haveNTRU      = ctx->haveNTRU;
01820     ssl->options.haveECDSAsig  = ctx->haveECDSAsig;
01821     ssl->options.haveECC       = ctx->haveECC;
01822     ssl->options.haveStaticECC = ctx->haveStaticECC;
01823 
01824 #ifndef NO_PSK
01825     ssl->options.havePSK   = ctx->havePSK;
01826     ssl->options.client_psk_cb = ctx->client_psk_cb;
01827     ssl->options.server_psk_cb = ctx->server_psk_cb;
01828 #endif /* NO_PSK */
01829 
01830 #ifdef HAVE_ANON
01831     ssl->options.haveAnon = ctx->haveAnon;
01832 #endif
01833 #ifndef NO_DH
01834     ssl->options.minDhKeySz = ctx->minDhKeySz;
01835 #endif
01836 
01837     ssl->options.sessionCacheOff      = ctx->sessionCacheOff;
01838     ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
01839 
01840     ssl->options.verifyPeer     = ctx->verifyPeer;
01841     ssl->options.verifyNone     = ctx->verifyNone;
01842     ssl->options.failNoCert     = ctx->failNoCert;
01843     ssl->options.failNoCertxPSK = ctx->failNoCertxPSK;
01844     ssl->options.sendVerify     = ctx->sendVerify;
01845 
01846     ssl->heap = ctx->heap;    /* defaults to self */
01847     ssl->options.partialWrite  = ctx->partialWrite;
01848     ssl->options.quietShutdown = ctx->quietShutdown;
01849     ssl->options.groupMessages = ctx->groupMessages;
01850 
01851 #ifndef NO_DH
01852     if (ssl->options.side == WOLFSSL_SERVER_END) {
01853         ssl->buffers.serverDH_P = ctx->serverDH_P;
01854         ssl->buffers.serverDH_G = ctx->serverDH_G;
01855     }
01856 #endif
01857 
01858 #ifndef NO_CERTS
01859     /* ctx still owns certificate, certChain, key, dh, and cm */
01860     ssl->buffers.certificate = ctx->certificate;
01861     ssl->buffers.certChain = ctx->certChain;
01862     ssl->buffers.key = ctx->privateKey;
01863 #endif
01864 
01865 #ifdef HAVE_CAVIUM
01866     ssl->devId = ctx->devId;
01867 #endif
01868 
01869 #ifndef NO_PSK
01870     if (ctx->server_hint[0]) {   /* set in CTX */
01871         XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
01872         ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
01873     }
01874 #endif /* NO_PSK */
01875 
01876     if (ctx->suites)
01877         *ssl->suites = *ctx->suites;
01878     else
01879         XMEMSET(ssl->suites, 0, sizeof(Suites));
01880 
01881     /* make sure server has DH parms, and add PSK if there, add NTRU too */
01882     if (ssl->options.side == WOLFSSL_SERVER_END)
01883         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
01884                    ssl->options.haveDH, ssl->options.haveNTRU,
01885                    ssl->options.haveECDSAsig, ssl->options.haveECC,
01886                    ssl->options.haveStaticECC, ssl->options.side);
01887     else
01888         InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
01889                    ssl->options.haveNTRU, ssl->options.haveECDSAsig,
01890                    ssl->options.haveECC, ssl->options.haveStaticECC,
01891                    ssl->options.side);
01892 
01893 #ifndef NO_CERTS
01894     /* make sure server has cert and key unless using PSK or Anon
01895      * This should be true even if just switching ssl ctx */
01896     if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
01897         if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer ||
01898             !ssl->buffers.key || !ssl->buffers.key->buffer) {
01899             WOLFSSL_MSG("Server missing certificate and/or private key");
01900             return NO_PRIVATE_KEY;
01901         }
01902 #endif
01903 
01904     return SSL_SUCCESS;
01905 }
01906 
01907 
01908 /* init everything to 0, NULL, default values before calling anything that may
01909    fail so that destructor has a "good" state to cleanup
01910    0 on success */
01911 int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
01912 {
01913     int  ret;
01914 
01915     XMEMSET(ssl, 0, sizeof(WOLFSSL));
01916 
01917     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
01918     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01919 
01920     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
01921     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
01922 
01923 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
01924     InitX509(&ssl->peerCert, 0);
01925 #endif
01926 
01927     ssl->rfd = -1;   /* set to invalid descriptor */
01928     ssl->wfd = -1;
01929 
01930     ssl->IOCB_ReadCtx  = &ssl->rfd;  /* prevent invalid pointer access if not */
01931     ssl->IOCB_WriteCtx = &ssl->wfd;  /* correctly set */
01932 
01933 #ifdef HAVE_NETX
01934     ssl->IOCB_ReadCtx  = &ssl->nxCtx;  /* default NetX IO ctx, same for read */
01935     ssl->IOCB_WriteCtx = &ssl->nxCtx;  /* and write */
01936 #endif
01937 #ifdef WOLFSSL_DTLS
01938     ssl->dtls_expected_rx = MAX_MTU;
01939 #endif
01940 
01941     ssl->options.serverState = NULL_STATE;
01942     ssl->options.clientState = NULL_STATE;
01943     ssl->options.connectState = CONNECT_BEGIN;
01944     ssl->options.acceptState  = ACCEPT_BEGIN;
01945     ssl->options.handShakeState  = NULL_STATE;
01946     ssl->options.processReply = doProcessInit;
01947 
01948 #ifdef WOLFSSL_DTLS
01949     ssl->dtls_timeout_init              = DTLS_TIMEOUT_INIT;
01950     ssl->dtls_timeout_max               = DTLS_TIMEOUT_MAX;
01951     ssl->dtls_timeout                   = ssl->dtls_timeout_init;
01952 #endif
01953 
01954     #ifndef NO_OLD_TLS
01955         ssl->hmac = SSL_hmac; /* default to SSLv3 */
01956     #else
01957         ssl->hmac = TLS_hmac;
01958     #endif
01959 
01960 
01961 #ifdef WOLFSSL_DTLS
01962     ssl->buffers.dtlsCtx.fd = -1;
01963 #endif
01964 
01965     ssl->cipher.ssl = ssl;
01966 
01967 #ifdef HAVE_TLS_EXTENSIONS
01968 #ifdef HAVE_MAX_FRAGMENT
01969     ssl->max_fragment = MAX_RECORD_SIZE;
01970 #endif
01971 #ifdef HAVE_ALPN
01972     ssl->alpn_client_list = NULL;
01973 #endif
01974 #endif
01975 
01976     /* default alert state (none) */
01977     ssl->alert_history.last_rx.code  = -1;
01978     ssl->alert_history.last_rx.level = -1;
01979     ssl->alert_history.last_tx.code  = -1;
01980     ssl->alert_history.last_tx.level = -1;
01981 
01982     InitCiphers(ssl);
01983     InitCipherSpecs(&ssl->specs);
01984 
01985     /* all done with init, now can return errors, call other stuff */
01986 
01987     /* arrays */
01988     ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
01989                                                            DYNAMIC_TYPE_ARRAYS);
01990     if (ssl->arrays == NULL) {
01991         WOLFSSL_MSG("Arrays Memory error");
01992         return MEMORY_E;
01993     }
01994     XMEMSET(ssl->arrays, 0, sizeof(Arrays));
01995 
01996     /* suites */
01997     ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
01998                                    DYNAMIC_TYPE_SUITES);
01999     if (ssl->suites == NULL) {
02000         WOLFSSL_MSG("Suites Memory error");
02001         return MEMORY_E;
02002     }
02003 
02004     /* Initialize SSL with the appropriate fields from it's ctx */
02005     /* requires valid arrays and suites */
02006     if((ret =  SetSSL_CTX(ssl, ctx)) != SSL_SUCCESS)
02007         return ret;
02008 
02009     ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
02010 
02011     /* hsHashes */
02012     ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
02013                                                            DYNAMIC_TYPE_HASHES);
02014     if (ssl->hsHashes == NULL) {
02015         WOLFSSL_MSG("HS_Hashes Memory error");
02016         return MEMORY_E;
02017     }
02018 
02019 #ifndef NO_OLD_TLS
02020 #ifndef NO_MD5
02021     wc_InitMd5(&ssl->hsHashes->hashMd5);
02022 #endif
02023 #ifndef NO_SHA
02024     ret = wc_InitSha(&ssl->hsHashes->hashSha);
02025     if (ret != 0) {
02026         return ret;
02027     }
02028 #endif
02029 #endif
02030 #ifndef NO_SHA256
02031     ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
02032     if (ret != 0) {
02033         return ret;
02034     }
02035 #endif
02036 #ifdef WOLFSSL_SHA384
02037     ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
02038     if (ret != 0) {
02039         return ret;
02040     }
02041 #endif
02042 #ifdef WOLFSSL_SHA512
02043     ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
02044     if (ret != 0) {
02045         return ret;
02046     }
02047 #endif
02048 
02049     /* RNG */
02050     ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap, DYNAMIC_TYPE_RNG);
02051     if (ssl->rng == NULL) {
02052         WOLFSSL_MSG("RNG Memory error");
02053         return MEMORY_E;
02054     }
02055 
02056     if ( (ret = wc_InitRng(ssl->rng)) != 0) {
02057         WOLFSSL_MSG("RNG Init error");
02058         return ret;
02059     }
02060 
02061 #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
02062     if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
02063         ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
02064         if (ret != 0) {
02065             WOLFSSL_MSG("DTLS Cookie Secret error");
02066             return ret;
02067         }
02068     }
02069 #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
02070 
02071 #ifdef HAVE_SECRET_CALLBACK
02072     ssl->sessionSecretCb  = NULL;
02073     ssl->sessionSecretCtx = NULL;
02074 #endif
02075     return 0;
02076 }
02077 
02078 
02079 /* free use of temporary arrays */
02080 void FreeArrays(WOLFSSL* ssl, int keep)
02081 {
02082     if (ssl->arrays && keep) {
02083         /* keeps session id for user retrieval */
02084         XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
02085         ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
02086     }
02087     if (ssl->arrays) {
02088         XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
02089         ssl->arrays->pendingMsg = NULL;
02090         ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */
02091     }
02092     XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
02093     ssl->arrays = NULL;
02094 }
02095 
02096 
02097 /* In case holding SSL object in array and don't want to free actual ssl */
02098 void SSL_ResourceFree(WOLFSSL* ssl)
02099 {
02100     /* Note: any resources used during the handshake should be released in the
02101      * function FreeHandshakeResources(). Be careful with the special cases
02102      * like the RNG which may optionally be kept for the whole session. (For
02103      * example with the RNG, it isn't used beyond the handshake except when
02104      * using stream ciphers where it is retained. */
02105 
02106     FreeCiphers(ssl);
02107     FreeArrays(ssl, 0);
02108     wc_FreeRng(ssl->rng);
02109     XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
02110     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
02111     XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
02112     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
02113 
02114     /* clear keys struct after session */
02115     ForceZero(&(ssl->keys), sizeof(Keys));
02116 
02117 #ifndef NO_DH
02118     if (ssl->buffers.serverDH_Priv.buffer) {
02119         ForceZero(ssl->buffers.serverDH_Priv.buffer,
02120                                              ssl->buffers.serverDH_Priv.length);
02121     }
02122     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02123     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02124     /* parameters (p,g) may be owned by ctx */
02125     if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
02126         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02127         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02128     }
02129 #endif
02130 #ifndef NO_CERTS
02131     wolfSSL_UnloadCertsKeys(ssl);
02132 #endif
02133 #ifndef NO_RSA
02134     if (ssl->peerRsaKey) {
02135         wc_FreeRsaKey(ssl->peerRsaKey);
02136         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
02137     }
02138 #endif
02139     if (ssl->buffers.inputBuffer.dynamicFlag)
02140         ShrinkInputBuffer(ssl, FORCED_FREE);
02141     if (ssl->buffers.outputBuffer.dynamicFlag)
02142         ShrinkOutputBuffer(ssl);
02143 #ifdef WOLFSSL_DTLS
02144     DtlsPoolDelete(ssl);
02145     if (ssl->dtls_msg_list != NULL) {
02146         DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
02147         ssl->dtls_msg_list = NULL;
02148     }
02149     XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
02150     ssl->buffers.dtlsCtx.peer.sa = NULL;
02151 #ifndef NO_WOLFSSL_SERVER
02152     XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
02153           DYNAMIC_TYPE_COOKIE_PWD);
02154 #endif
02155 #endif /* WOLFSSL_DTLS */
02156 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
02157     if (ssl->biord != ssl->biowr)        /* only free write if different */
02158         wolfSSL_BIO_free(ssl->biowr);
02159     wolfSSL_BIO_free(ssl->biord);        /* always free read bio */
02160 #endif
02161 #ifdef HAVE_LIBZ
02162     FreeStreams(ssl);
02163 #endif
02164 #ifdef HAVE_ECC
02165     if (ssl->peerEccKey) {
02166         if (ssl->peerEccKeyPresent)
02167             wc_ecc_free(ssl->peerEccKey);
02168         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
02169     }
02170     if (ssl->peerEccDsaKey) {
02171         if (ssl->peerEccDsaKeyPresent)
02172             wc_ecc_free(ssl->peerEccDsaKey);
02173         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02174     }
02175     if (ssl->eccTempKey) {
02176         if (ssl->eccTempKeyPresent)
02177             wc_ecc_free(ssl->eccTempKey);
02178         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
02179     }
02180 #endif
02181 #ifdef HAVE_PK_CALLBACKS
02182     #ifdef HAVE_ECC
02183         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
02184     #endif /* HAVE_ECC */
02185     #ifndef NO_RSA
02186         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
02187     #endif /* NO_RSA */
02188 #endif /* HAVE_PK_CALLBACKS */
02189 #ifdef HAVE_TLS_EXTENSIONS
02190     TLSX_FreeAll(ssl->extensions);
02191 
02192 #ifdef HAVE_ALPN
02193     if (ssl->alpn_client_list != NULL) {
02194         XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
02195         ssl->alpn_client_list = NULL;
02196     }
02197 #endif
02198 #endif /* HAVE_TLS_EXTENSIONS */
02199 #ifdef HAVE_NETX
02200     if (ssl->nxCtx.nxPacket)
02201         nx_packet_release(ssl->nxCtx.nxPacket);
02202 #endif
02203 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
02204     FreeX509(&ssl->peerCert);
02205 #endif
02206 }
02207 
02208 #ifdef WOLFSSL_TI_HASH
02209 static void HashFinal(WOLFSSL * ssl) {
02210     byte dummyHash[32] ;
02211 #ifndef NO_MD5
02212     wc_Md5Final(&(ssl->hsHashes->hashMd5), dummyHash) ;
02213 #endif
02214 #ifndef NO_SHA
02215     wc_ShaFinal(&(ssl->hsHashes->hashSha), dummyHash) ;
02216 #endif
02217 #ifndef NO_SHA256
02218     wc_Sha256Final(&(ssl->hsHashes->hashSha256), dummyHash) ;
02219 #endif
02220 }
02221 #else
02222 
02223     #define HashFinal(ssl)
02224 
02225 #endif
02226 
02227 /* Free any handshake resources no longer needed */
02228 void FreeHandshakeResources(WOLFSSL* ssl)
02229 {
02230 
02231     HashFinal(ssl) ;
02232 #ifdef HAVE_SECURE_RENEGOTIATION
02233     if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
02234         WOLFSSL_MSG("Secure Renegotiation needs to retain handshake resources");
02235         return;
02236     }
02237 #endif
02238 
02239     /* input buffer */
02240     if (ssl->buffers.inputBuffer.dynamicFlag)
02241         ShrinkInputBuffer(ssl, NO_FORCED_FREE);
02242 
02243     /* suites */
02244     XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
02245     ssl->suites = NULL;
02246 
02247     /* hsHashes */
02248     XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
02249     ssl->hsHashes = NULL;
02250 
02251     /* RNG */
02252     if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
02253         wc_FreeRng(ssl->rng);
02254         XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
02255         ssl->rng = NULL;
02256     }
02257 
02258 #ifdef WOLFSSL_DTLS
02259     /* DTLS_POOL */
02260     if (ssl->options.dtls) {
02261         DtlsPoolDelete(ssl);
02262         DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
02263         ssl->dtls_msg_list = NULL;
02264     }
02265 #endif
02266 
02267     /* arrays */
02268     if (ssl->options.saveArrays == 0)
02269         FreeArrays(ssl, 1);
02270 
02271 #ifndef NO_RSA
02272     /* peerRsaKey */
02273     if (ssl->peerRsaKey) {
02274         wc_FreeRsaKey(ssl->peerRsaKey);
02275         XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
02276         ssl->peerRsaKey = NULL;
02277     }
02278 #endif
02279 
02280 #ifdef HAVE_ECC
02281     if (ssl->peerEccKey)
02282     {
02283         if (ssl->peerEccKeyPresent) {
02284             wc_ecc_free(ssl->peerEccKey);
02285             ssl->peerEccKeyPresent = 0;
02286         }
02287         XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
02288         ssl->peerEccKey = NULL;
02289     }
02290     if (ssl->peerEccDsaKey)
02291     {
02292         if (ssl->peerEccDsaKeyPresent) {
02293             wc_ecc_free(ssl->peerEccDsaKey);
02294             ssl->peerEccDsaKeyPresent = 0;
02295         }
02296         XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
02297         ssl->peerEccDsaKey = NULL;
02298     }
02299     if (ssl->eccTempKey)
02300     {
02301         if (ssl->eccTempKeyPresent) {
02302             wc_ecc_free(ssl->eccTempKey);
02303             ssl->eccTempKeyPresent = 0;
02304         }
02305         XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
02306         ssl->eccTempKey = NULL;
02307     }
02308 #endif
02309 #ifndef NO_DH
02310     if (ssl->buffers.serverDH_Priv.buffer) {
02311         ForceZero(ssl->buffers.serverDH_Priv.buffer,
02312                                              ssl->buffers.serverDH_Priv.length);
02313     }
02314     XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02315     ssl->buffers.serverDH_Priv.buffer = NULL;
02316     XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02317     ssl->buffers.serverDH_Pub.buffer = NULL;
02318     /* parameters (p,g) may be owned by ctx */
02319     if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
02320         XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02321         ssl->buffers.serverDH_G.buffer = NULL;
02322         XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
02323         ssl->buffers.serverDH_P.buffer = NULL;
02324     }
02325 #endif
02326 #ifndef NO_CERTS
02327     wolfSSL_UnloadCertsKeys(ssl);
02328 #endif
02329 #ifdef HAVE_PK_CALLBACKS
02330     #ifdef HAVE_ECC
02331         XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
02332         ssl->buffers.peerEccDsaKey.buffer = NULL;
02333     #endif /* HAVE_ECC */
02334     #ifndef NO_RSA
02335         XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
02336         ssl->buffers.peerRsaKey.buffer = NULL;
02337     #endif /* NO_RSA */
02338 #endif /* HAVE_PK_CALLBACKS */
02339 
02340 #ifdef HAVE_QSH
02341     QSH_FreeAll(ssl);
02342 #endif
02343 }
02344 
02345 
02346 void FreeSSL(WOLFSSL* ssl)
02347 {
02348     FreeSSL_Ctx(ssl->ctx);  /* will decrement and free underyling CTX if 0 */
02349     SSL_ResourceFree(ssl);
02350     XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
02351 }
02352 
02353 
02354 #ifdef WOLFSSL_DTLS
02355 
02356 int DtlsPoolInit(WOLFSSL* ssl)
02357 {
02358     if (ssl->dtls_pool == NULL) {
02359         DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
02360                                              ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02361         if (pool == NULL) {
02362             WOLFSSL_MSG("DTLS Buffer Pool Memory error");
02363             return MEMORY_E;
02364         }
02365         else {
02366             int i;
02367 
02368             for (i = 0; i < DTLS_POOL_SZ; i++) {
02369                 pool->buf[i].length = 0;
02370                 pool->buf[i].buffer = NULL;
02371             }
02372             pool->used = 0;
02373             ssl->dtls_pool = pool;
02374         }
02375     }
02376     return 0;
02377 }
02378 
02379 
02380 int DtlsPoolSave(WOLFSSL* ssl, const byte *src, int sz)
02381 {
02382     DtlsPool *pool = ssl->dtls_pool;
02383     if (pool != NULL && pool->used < DTLS_POOL_SZ) {
02384         buffer *pBuf = &pool->buf[pool->used];
02385         pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02386         if (pBuf->buffer == NULL) {
02387             WOLFSSL_MSG("DTLS Buffer Memory error");
02388             return MEMORY_ERROR;
02389         }
02390         XMEMCPY(pBuf->buffer, src, sz);
02391         pool->epoch[pool->used] = ssl->keys.dtls_epoch;
02392         pBuf->length = (word32)sz;
02393         pool->used++;
02394     }
02395     return 0;
02396 }
02397 
02398 
02399 void DtlsPoolReset(WOLFSSL* ssl)
02400 {
02401     DtlsPool *pool = ssl->dtls_pool;
02402     if (pool != NULL) {
02403         buffer *pBuf;
02404         int i, used;
02405 
02406         used = pool->used;
02407         for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
02408             XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02409             pBuf->buffer = NULL;
02410             pBuf->length = 0;
02411         }
02412         pool->used = 0;
02413     }
02414     ssl->dtls_timeout = ssl->dtls_timeout_init;
02415 }
02416 
02417 
02418 void DtlsPoolDelete(WOLFSSL* ssl)
02419 {
02420     if (ssl->dtls_pool != NULL) {
02421         DtlsPoolReset(ssl);
02422         XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
02423         ssl->dtls_pool = NULL;
02424     }
02425 }
02426 
02427 
02428 int DtlsPoolTimeout(WOLFSSL* ssl)
02429 {
02430     int result = -1;
02431     if (ssl->dtls_timeout <  ssl->dtls_timeout_max) {
02432         ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
02433         result = 0;
02434     }
02435     return result;
02436 }
02437 
02438 
02439 int DtlsPoolSend(WOLFSSL* ssl)
02440 {
02441     DtlsPool* pool = ssl->dtls_pool;
02442 
02443     if (pool != NULL && pool->used > 0) {
02444         int ret = 0;
02445         int     i;
02446         buffer* buf;
02447 
02448         for (i = 0, buf = pool->buf; i < pool->used; i++, buf++) {
02449             if (pool->epoch[i] == 0) {
02450                 DtlsRecordLayerHeader* dtls;
02451                 word32*                seqNumber;
02452 
02453                 dtls = (DtlsRecordLayerHeader*)buf->buffer;
02454                 seqNumber = (ssl->keys.dtls_epoch == 0) ?
02455                                 &ssl->keys.dtls_sequence_number :
02456                                 &ssl->keys.dtls_prev_sequence_number;
02457                 c32to48((*seqNumber)++, dtls->sequence_number);
02458                 if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
02459                     return ret;
02460 
02461                 XMEMCPY(ssl->buffers.outputBuffer.buffer,
02462                         buf->buffer, buf->length);
02463                 ssl->buffers.outputBuffer.idx = 0;
02464                 ssl->buffers.outputBuffer.length = buf->length;
02465             }
02466             else if (pool->epoch[i] == ssl->keys.dtls_epoch) {
02467                 byte*  input;
02468                 byte*  output;
02469                 int    inputSz, sendSz;
02470 
02471                 input = buf->buffer;
02472                 inputSz = buf->length;
02473                 sendSz = inputSz + MAX_MSG_EXTRA;
02474 
02475                 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
02476                     return ret;
02477 
02478                 output = ssl->buffers.outputBuffer.buffer +
02479                          ssl->buffers.outputBuffer.length;
02480                 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
02481                                       handshake, 0);
02482                 if (sendSz < 0)
02483                     return BUILD_MSG_ERROR;
02484 
02485                 ssl->buffers.outputBuffer.length += sendSz;
02486             }
02487 
02488             ret = SendBuffered(ssl);
02489             if (ret < 0) {
02490                 return ret;
02491             }
02492         }
02493     }
02494     return 0;
02495 }
02496 
02497 
02498 /* functions for managing DTLS datagram reordering */
02499 
02500 /* Need to allocate space for the handshake message header. The hashing
02501  * routines assume the message pointer is still within the buffer that
02502  * has the headers, and will include those headers in the hash. The store
02503  * routines need to take that into account as well. New will allocate
02504  * extra space for the headers. */
02505 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
02506 {
02507     DtlsMsg* msg = NULL;
02508 
02509     msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
02510 
02511     if (msg != NULL) {
02512         XMEMSET(msg, 0, sizeof(DtlsMsg));
02513         msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
02514                                                 heap, DYNAMIC_TYPE_DTLS_BUFFER);
02515         if (msg->buf != NULL) {
02516             msg->sz = sz;
02517             msg->type = no_shake;
02518             msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
02519         }
02520         else {
02521             XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
02522             msg = NULL;
02523         }
02524     }
02525 
02526     return msg;
02527 }
02528 
02529 void DtlsMsgDelete(DtlsMsg* item, void* heap)
02530 {
02531     (void)heap;
02532 
02533     if (item != NULL) {
02534         DtlsFrag* cur = item->fragList;
02535         while (cur != NULL) {
02536             DtlsFrag* next = cur->next;
02537             XFREE(cur, heap, DYNAMIC_TYPE_DTLS_FRAG);
02538             cur = next;
02539         }
02540         if (item->buf != NULL)
02541             XFREE(item->buf, heap, DYNAMIC_TYPE_DTLS_BUFFER);
02542         XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
02543     }
02544 }
02545 
02546 
02547 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
02548 {
02549     DtlsMsg* next;
02550     while (head) {
02551         next = head->next;
02552         DtlsMsgDelete(head, heap);
02553         head = next;
02554     }
02555 }
02556 
02557 
02558 /* Create a DTLS Fragment from *begin - end, adjust new *begin and bytesLeft */
02559 static DtlsFrag* CreateFragment(word32* begin, word32 end, const byte* data,
02560                                 byte* buf, word32* bytesLeft, void* heap)
02561 {
02562     DtlsFrag* newFrag;
02563     word32 added = end - *begin + 1;
02564 
02565     newFrag = (DtlsFrag*)XMALLOC(sizeof(DtlsFrag), heap,
02566                                  DYNAMIC_TYPE_DTLS_FRAG);
02567     if (newFrag != NULL) {
02568         newFrag->next = NULL;
02569         newFrag->begin = *begin;
02570         newFrag->end = end;
02571 
02572         XMEMCPY(buf + *begin, data, added);
02573         *bytesLeft -= added;
02574         *begin = newFrag->end + 1;
02575     }
02576 
02577     return newFrag;
02578 }
02579 
02580 
02581 int DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
02582                                    word32 fragOffset, word32 fragSz, void* heap)
02583 {
02584     if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
02585                                              (fragOffset + fragSz) <= msg->sz) {
02586         DtlsFrag* cur = msg->fragList;
02587         DtlsFrag* prev = cur;
02588         DtlsFrag* newFrag;
02589         word32 bytesLeft = fragSz; /* could be overlapping fragment */
02590         word32 startOffset = fragOffset;
02591         word32 added;
02592 
02593         msg->seq = seq;
02594         msg->type = type;
02595 
02596         if (fragOffset == 0) {
02597             XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
02598                     DTLS_HANDSHAKE_HEADER_SZ);
02599             c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
02600         }
02601 
02602         /* if no mesage data, just return */
02603         if (fragSz == 0)
02604             return 0;
02605 
02606         /* if list is empty add full fragment to front */
02607         if (cur == NULL) {
02608             newFrag = CreateFragment(&fragOffset, fragOffset + fragSz - 1, data,
02609                                      msg->msg, &bytesLeft, heap);
02610             if (newFrag == NULL)
02611                 return MEMORY_E;
02612 
02613             msg->fragSz = fragSz;
02614             msg->fragList = newFrag;
02615 
02616             return 0;
02617         }
02618 
02619         /* add to front if before current front, up to next->begin */
02620         if (fragOffset < cur->begin) {
02621             word32 end = fragOffset + fragSz - 1;
02622 
02623             if (end >= cur->begin)
02624                 end = cur->begin - 1;
02625 
02626             added = end - fragOffset + 1;
02627             newFrag = CreateFragment(&fragOffset, end, data, msg->msg,
02628                                      &bytesLeft, heap);
02629             if (newFrag == NULL)
02630                 return MEMORY_E;
02631 
02632             msg->fragSz += added;
02633 
02634             newFrag->next = cur;
02635             msg->fragList = newFrag;
02636         }
02637 
02638         /* while we have bytes left, try to find a gap to fill */
02639         while (bytesLeft > 0) {
02640             /* get previous packet in list */
02641             while (cur && (fragOffset >= cur->begin)) {
02642                 prev = cur;
02643                 cur = cur->next;
02644             }
02645 
02646             /* don't add duplicate data */
02647             if (prev->end >= fragOffset) {
02648                 if ( (fragOffset + bytesLeft - 1) <= prev->end)
02649                     return 0;
02650                 fragOffset = prev->end + 1;
02651                 bytesLeft = startOffset + fragSz - fragOffset;
02652             }
02653 
02654             if (cur == NULL)
02655                 /* we're at the end */
02656                 added = bytesLeft;
02657             else
02658                 /* we're in between two frames */
02659                 added = min(bytesLeft, cur->begin - fragOffset);
02660 
02661             /* data already there */
02662             if (added == 0)
02663                 continue;
02664 
02665             newFrag = CreateFragment(&fragOffset, fragOffset + added - 1,
02666                                      data + fragOffset - startOffset,
02667                                      msg->msg, &bytesLeft, heap);
02668             if (newFrag == NULL)
02669                 return MEMORY_E;
02670 
02671             msg->fragSz += added;
02672 
02673             newFrag->next = prev->next;
02674             prev->next = newFrag;
02675         }
02676     }
02677 
02678     return 0;
02679 }
02680 
02681 
02682 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
02683 {
02684     while (head != NULL && head->seq != seq) {
02685         head = head->next;
02686     }
02687     return head;
02688 }
02689 
02690 
02691 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
02692         word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
02693 {
02694 
02695     /* See if seq exists in the list. If it isn't in the list, make
02696      * a new item of size dataSz, copy fragSz bytes from data to msg->msg
02697      * starting at offset fragOffset, and add fragSz to msg->fragSz. If
02698      * the seq is in the list and it isn't full, copy fragSz bytes from
02699      * data to msg->msg starting at offset fragOffset, and add fragSz to
02700      * msg->fragSz. Insertions take into account data already in the list
02701      * in case there are overlaps in the handshake message due to retransmit
02702      * messages. The new item should be inserted into the list in its
02703      * proper position.
02704      *
02705      * 1. Find seq in list, or where seq should go in list. If seq not in
02706      *    list, create new item and insert into list. Either case, keep
02707      *    pointer to item.
02708      * 2. Copy the data from the message to the stored message where it
02709      *    belongs without overlaps.
02710      */
02711 
02712     if (head != NULL) {
02713         DtlsMsg* cur = DtlsMsgFind(head, seq);
02714         if (cur == NULL) {
02715             cur = DtlsMsgNew(dataSz, heap);
02716             if (cur != NULL) {
02717                 if (DtlsMsgSet(cur, seq, data, type,
02718                                                 fragOffset, fragSz, heap) < 0) {
02719                     DtlsMsgDelete(cur, heap);
02720                     return head;
02721                 }
02722                 head = DtlsMsgInsert(head, cur);
02723             }
02724         }
02725         else {
02726             /* If this fails, the data is just dropped. */
02727             DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz, heap);
02728         }
02729     }
02730     else {
02731         head = DtlsMsgNew(dataSz, heap);
02732         if (DtlsMsgSet(head, seq, data, type, fragOffset, fragSz, heap) < 0) {
02733             DtlsMsgDelete(head, heap);
02734             return NULL;
02735         }
02736     }
02737 
02738     return head;
02739 }
02740 
02741 
02742 /* DtlsMsgInsert() is an in-order insert. */
02743 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
02744 {
02745     if (head == NULL || item->seq < head->seq) {
02746         item->next = head;
02747         head = item;
02748     }
02749     else if (head->next == NULL) {
02750         head->next = item;
02751     }
02752     else {
02753         DtlsMsg* cur = head->next;
02754         DtlsMsg* prev = head;
02755         while (cur) {
02756             if (item->seq < cur->seq) {
02757                 item->next = cur;
02758                 prev->next = item;
02759                 break;
02760             }
02761             prev = cur;
02762             cur = cur->next;
02763         }
02764         if (cur == NULL) {
02765             prev->next = item;
02766         }
02767     }
02768 
02769     return head;
02770 }
02771 
02772 #endif /* WOLFSSL_DTLS */
02773 
02774 #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
02775 
02776 ProtocolVersion MakeSSLv3(void)
02777 {
02778     ProtocolVersion pv;
02779     pv.major = SSLv3_MAJOR;
02780     pv.minor = SSLv3_MINOR;
02781 
02782     return pv;
02783 }
02784 
02785 #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
02786 
02787 
02788 #ifdef WOLFSSL_DTLS
02789 
02790 ProtocolVersion MakeDTLSv1(void)
02791 {
02792     ProtocolVersion pv;
02793     pv.major = DTLS_MAJOR;
02794     pv.minor = DTLS_MINOR;
02795 
02796     return pv;
02797 }
02798 
02799 ProtocolVersion MakeDTLSv1_2(void)
02800 {
02801     ProtocolVersion pv;
02802     pv.major = DTLS_MAJOR;
02803     pv.minor = DTLSv1_2_MINOR;
02804 
02805     return pv;
02806 }
02807 
02808 #endif /* WOLFSSL_DTLS */
02809 
02810 
02811 
02812 
02813 #ifdef USE_WINDOWS_API
02814 
02815     word32 LowResTimer(void)
02816     {
02817         static int           init = 0;
02818         static LARGE_INTEGER freq;
02819         LARGE_INTEGER        count;
02820 
02821         if (!init) {
02822             QueryPerformanceFrequency(&freq);
02823             init = 1;
02824         }
02825 
02826         QueryPerformanceCounter(&count);
02827 
02828         return (word32)(count.QuadPart / freq.QuadPart);
02829     }
02830 
02831 #elif defined(HAVE_RTP_SYS)
02832 
02833     #include "rtptime.h"
02834 
02835     word32 LowResTimer(void)
02836     {
02837         return (word32)rtp_get_system_sec();
02838     }
02839 
02840 
02841 #elif defined(MICRIUM)
02842 
02843     word32 LowResTimer(void)
02844     {
02845         NET_SECURE_OS_TICK  clk = 0;
02846 
02847         #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
02848             clk = NetSecure_OS_TimeGet();
02849         #endif
02850         return (word32)clk;
02851     }
02852 
02853 
02854 #elif defined(MICROCHIP_TCPIP_V5)
02855 
02856     word32 LowResTimer(void)
02857     {
02858         return (word32) (TickGet() / TICKS_PER_SECOND);
02859     }
02860 
02861 
02862 #elif defined(MICROCHIP_TCPIP)
02863 
02864     #if defined(MICROCHIP_MPLAB_HARMONY)
02865 
02866         #include <system/tmr/sys_tmr.h>
02867 
02868         word32 LowResTimer(void)
02869         {
02870             return (word32) (SYS_TMR_TickCountGet() /
02871                              SYS_TMR_TickCounterFrequencyGet());
02872         }
02873 
02874     #else
02875 
02876         word32 LowResTimer(void)
02877         {
02878             return (word32) (SYS_TICK_Get() / SYS_TICK_TicksPerSecondGet());
02879         }
02880 
02881     #endif
02882 
02883 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
02884 
02885     word32 LowResTimer(void)
02886     {
02887         TIME_STRUCT mqxTime;
02888 
02889         _time_get_elapsed(&mqxTime);
02890 
02891         return (word32) mqxTime.SECONDS;
02892     }
02893 
02894 #elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)
02895 
02896     #include "fsl_pit_driver.h"
02897 
02898     word32 LowResTimer(void)
02899     {
02900         return PIT_DRV_GetUs();
02901     }
02902 
02903 #elif defined(WOLFSSL_TIRTOS)
02904 
02905     word32 LowResTimer(void)
02906     {
02907         return (word32) Seconds_get();
02908     }
02909 
02910 #elif defined(USER_TICKS)
02911 #if 0
02912     word32 LowResTimer(void)
02913     {
02914         /*
02915         write your own clock tick function if don't want time(0)
02916         needs second accuracy but doesn't have to correlated to EPOCH
02917         */
02918     }
02919 #endif
02920 
02921 #elif defined(TIME_OVERRIDES)
02922 
02923     /* use same asn time overrides unless user wants tick override above */
02924 
02925     #ifndef HAVE_TIME_T_TYPE
02926         typedef long time_t;
02927     #endif
02928     extern time_t XTIME(time_t * timer);
02929 
02930     word32 LowResTimer(void)
02931     {
02932         return (word32) XTIME(0);
02933     }
02934 
02935 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
02936 
02937     #include <time.h>
02938 
02939     word32 LowResTimer(void)
02940     {
02941         return (word32)time(0);
02942     }
02943 
02944 
02945 #endif /* USE_WINDOWS_API */
02946 
02947 
02948 #ifndef NO_CERTS
02949 static int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz)
02950 {
02951 #ifdef HAVE_FUZZER
02952     if (ssl->fuzzerCb)
02953         ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
02954 #endif
02955 #ifndef NO_OLD_TLS
02956 #ifndef NO_SHA
02957     wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz);
02958 #endif
02959 #ifndef NO_MD5
02960     wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz);
02961 #endif
02962 #endif
02963 
02964     if (IsAtLeastTLSv1_2(ssl)) {
02965         int ret;
02966 
02967 #ifndef NO_SHA256
02968         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, output, sz);
02969         if (ret != 0)
02970             return ret;
02971 #endif
02972 #ifdef WOLFSSL_SHA384
02973         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, output, sz);
02974         if (ret != 0)
02975             return ret;
02976 #endif
02977 #ifdef WOLFSSL_SHA512
02978         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, output, sz);
02979         if (ret != 0)
02980             return ret;
02981 #endif
02982     }
02983 
02984     return 0;
02985 }
02986 #endif /* NO_CERTS */
02987 
02988 
02989 /* add output to md5 and sha handshake hashes, exclude record header */
02990 static int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
02991 {
02992     const byte* adj = output + RECORD_HEADER_SZ + ivSz;
02993     sz -= RECORD_HEADER_SZ;
02994 
02995 #ifdef HAVE_FUZZER
02996     if (ssl->fuzzerCb)
02997         ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
02998 #endif
02999 #ifdef WOLFSSL_DTLS
03000     if (ssl->options.dtls) {
03001         adj += DTLS_RECORD_EXTRA;
03002         sz  -= DTLS_RECORD_EXTRA;
03003     }
03004 #endif
03005 #ifndef NO_OLD_TLS
03006 #ifndef NO_SHA
03007     wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
03008 #endif
03009 #ifndef NO_MD5
03010     wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
03011 #endif
03012 #endif
03013 
03014     if (IsAtLeastTLSv1_2(ssl)) {
03015         int ret;
03016 
03017 #ifndef NO_SHA256
03018         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
03019         if (ret != 0)
03020             return ret;
03021 #endif
03022 #ifdef WOLFSSL_SHA384
03023         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
03024         if (ret != 0)
03025             return ret;
03026 #endif
03027 #ifdef WOLFSSL_SHA512
03028         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
03029         if (ret != 0)
03030             return ret;
03031 #endif
03032     }
03033 
03034     return 0;
03035 }
03036 
03037 
03038 /* add input to md5 and sha handshake hashes, include handshake header */
03039 static int HashInput(WOLFSSL* ssl, const byte* input, int sz)
03040 {
03041     const byte* adj = input - HANDSHAKE_HEADER_SZ;
03042     sz += HANDSHAKE_HEADER_SZ;
03043 
03044 #ifdef WOLFSSL_DTLS
03045     if (ssl->options.dtls) {
03046         adj -= DTLS_HANDSHAKE_EXTRA;
03047         sz  += DTLS_HANDSHAKE_EXTRA;
03048     }
03049 #endif
03050 
03051 #ifndef NO_OLD_TLS
03052 #ifndef NO_SHA
03053     wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
03054 #endif
03055 #ifndef NO_MD5
03056     wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
03057 #endif
03058 #endif
03059 
03060     if (IsAtLeastTLSv1_2(ssl)) {
03061         int ret;
03062 
03063 #ifndef NO_SHA256
03064         ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
03065         if (ret != 0)
03066             return ret;
03067 #endif
03068 #ifdef WOLFSSL_SHA384
03069         ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
03070         if (ret != 0)
03071             return ret;
03072 #endif
03073 #ifdef WOLFSSL_SHA512
03074         ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
03075         if (ret != 0)
03076             return ret;
03077 #endif
03078     }
03079 
03080     return 0;
03081 }
03082 
03083 
03084 /* add record layer header for message */
03085 static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl)
03086 {
03087     RecordLayerHeader* rl;
03088 
03089     /* record layer header */
03090     rl = (RecordLayerHeader*)output;
03091     rl->type    = type;
03092     rl->pvMajor = ssl->version.major;       /* type and version same in each */
03093     rl->pvMinor = ssl->version.minor;
03094 
03095 #ifdef WOLFSSL_ALTERNATIVE_DOWNGRADE
03096     if (ssl->options.side == WOLFSSL_CLIENT_END
03097     &&  ssl->options.connectState == CONNECT_BEGIN
03098     && !ssl->options.resuming)
03099         rl->pvMinor = ssl->options.downgrade ? ssl->options.minDowngrade
03100                                              : ssl->version.minor;
03101 #endif
03102 
03103     if (!ssl->options.dtls)
03104         c16toa((word16)length, rl->length);
03105     else {
03106 #ifdef WOLFSSL_DTLS
03107         DtlsRecordLayerHeader* dtls;
03108 
03109         /* dtls record layer header extensions */
03110         dtls = (DtlsRecordLayerHeader*)output;
03111         c16toa(ssl->keys.dtls_epoch, dtls->epoch);
03112         c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
03113         c16toa((word16)length, dtls->length);
03114 #endif
03115     }
03116 }
03117 
03118 
03119 /* add handshake header for message */
03120 static void AddHandShakeHeader(byte* output, word32 length,
03121                                word32 fragOffset, word32 fragLength,
03122                                byte type, WOLFSSL* ssl)
03123 {
03124     HandShakeHeader* hs;
03125     (void)fragOffset;
03126     (void)fragLength;
03127     (void)ssl;
03128 
03129     /* handshake header */
03130     hs = (HandShakeHeader*)output;
03131     hs->type = type;
03132     c32to24(length, hs->length);         /* type and length same for each */
03133 #ifdef WOLFSSL_DTLS
03134     if (ssl->options.dtls) {
03135         DtlsHandShakeHeader* dtls;
03136 
03137         /* dtls handshake header extensions */
03138         dtls = (DtlsHandShakeHeader*)output;
03139         c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
03140         c32to24(fragOffset, dtls->fragment_offset);
03141         c32to24(fragLength, dtls->fragment_length);
03142     }
03143 #endif
03144 }
03145 
03146 
03147 /* add both headers for handshake message */
03148 static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
03149 {
03150     word32 lengthAdj = HANDSHAKE_HEADER_SZ;
03151     word32 outputAdj = RECORD_HEADER_SZ;
03152 
03153 #ifdef WOLFSSL_DTLS
03154     if (ssl->options.dtls) {
03155         lengthAdj += DTLS_HANDSHAKE_EXTRA;
03156         outputAdj += DTLS_RECORD_EXTRA;
03157     }
03158 #endif
03159 
03160     AddRecordHeader(output, length + lengthAdj, handshake, ssl);
03161     AddHandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
03162 }
03163 
03164 
03165 #ifndef NO_CERTS
03166 static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
03167                            word32 length, byte type, WOLFSSL* ssl)
03168 {
03169     word32 lengthAdj = HANDSHAKE_HEADER_SZ;
03170     word32 outputAdj = RECORD_HEADER_SZ;
03171     (void)fragSz;
03172 
03173 #ifdef WOLFSSL_DTLS
03174     if (ssl->options.dtls) {
03175         lengthAdj += DTLS_HANDSHAKE_EXTRA;
03176         outputAdj += DTLS_RECORD_EXTRA;
03177     }
03178 #endif
03179 
03180     AddRecordHeader(output, fragSz + lengthAdj, handshake, ssl);
03181     AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
03182 }
03183 #endif /* NO_CERTS */
03184 
03185 
03186 /* return bytes received, -1 on error */
03187 static int Receive(WOLFSSL* ssl, byte* buf, word32 sz)
03188 {
03189     int recvd;
03190 
03191     if (ssl->ctx->CBIORecv == NULL) {
03192         WOLFSSL_MSG("Your IO Recv callback is null, please set");
03193         return -1;
03194     }
03195 
03196 retry:
03197     recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
03198     if (recvd < 0)
03199         switch (recvd) {
03200             case WOLFSSL_CBIO_ERR_GENERAL:        /* general/unknown error */
03201                 return -1;
03202 
03203             case WOLFSSL_CBIO_ERR_WANT_READ:      /* want read, would block */
03204                 return WANT_READ;
03205 
03206             case WOLFSSL_CBIO_ERR_CONN_RST:       /* connection reset */
03207                 #ifdef USE_WINDOWS_API
03208                 if (ssl->options.dtls) {
03209                     goto retry;
03210                 }
03211                 #endif
03212                 ssl->options.connReset = 1;
03213                 return -1;
03214 
03215             case WOLFSSL_CBIO_ERR_ISR:            /* interrupt */
03216                 /* see if we got our timeout */
03217                 #ifdef WOLFSSL_CALLBACKS
03218                     if (ssl->toInfoOn) {
03219                         struct itimerval timeout;
03220                         getitimer(ITIMER_REAL, &timeout);
03221                         if (timeout.it_value.tv_sec == 0 &&
03222                                                 timeout.it_value.tv_usec == 0) {
03223                             XSTRNCPY(ssl->timeoutInfo.timeoutName,
03224                                     "recv() timeout", MAX_TIMEOUT_NAME_SZ);
03225                             WOLFSSL_MSG("Got our timeout");
03226                             return WANT_READ;
03227                         }
03228                     }
03229                 #endif
03230                 goto retry;
03231 
03232             case WOLFSSL_CBIO_ERR_CONN_CLOSE:     /* peer closed connection */
03233                 ssl->options.isClosed = 1;
03234                 return -1;
03235 
03236             case WOLFSSL_CBIO_ERR_TIMEOUT:
03237 #ifdef WOLFSSL_DTLS
03238                 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
03239                     goto retry;
03240                 else
03241 #endif
03242                     return -1;
03243 
03244             default:
03245                 return recvd;
03246         }
03247 
03248     return recvd;
03249 }
03250 
03251 
03252 /* Switch dynamic output buffer back to static, buffer is assumed clear */
03253 void ShrinkOutputBuffer(WOLFSSL* ssl)
03254 {
03255     WOLFSSL_MSG("Shrinking output buffer\n");
03256     XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
03257           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
03258     ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
03259     ssl->buffers.outputBuffer.bufferSize  = STATIC_BUFFER_LEN;
03260     ssl->buffers.outputBuffer.dynamicFlag = 0;
03261     ssl->buffers.outputBuffer.offset      = 0;
03262 }
03263 
03264 
03265 /* Switch dynamic input buffer back to static, keep any remaining input */
03266 /* forced free means cleaning up */
03267 void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
03268 {
03269     int usedLength = ssl->buffers.inputBuffer.length -
03270                      ssl->buffers.inputBuffer.idx;
03271     if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
03272         return;
03273 
03274     WOLFSSL_MSG("Shrinking input buffer\n");
03275 
03276     if (!forcedFree && usedLength)
03277         XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
03278                ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
03279                usedLength);
03280 
03281     XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
03282           ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
03283     ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
03284     ssl->buffers.inputBuffer.bufferSize  = STATIC_BUFFER_LEN;
03285     ssl->buffers.inputBuffer.dynamicFlag = 0;
03286     ssl->buffers.inputBuffer.offset      = 0;
03287     ssl->buffers.inputBuffer.idx = 0;
03288     ssl->buffers.inputBuffer.length = usedLength;
03289 }
03290 
03291 int SendBuffered(WOLFSSL* ssl)
03292 {
03293     if (ssl->ctx->CBIOSend == NULL) {
03294         WOLFSSL_MSG("Your IO Send callback is null, please set");
03295         return SOCKET_ERROR_E;
03296     }
03297 
03298     while (ssl->buffers.outputBuffer.length > 0) {
03299         int sent = ssl->ctx->CBIOSend(ssl,
03300                                       (char*)ssl->buffers.outputBuffer.buffer +
03301                                       ssl->buffers.outputBuffer.idx,
03302                                       (int)ssl->buffers.outputBuffer.length,
03303                                       ssl->IOCB_WriteCtx);
03304         if (sent < 0) {
03305             switch (sent) {
03306 
03307                 case WOLFSSL_CBIO_ERR_WANT_WRITE:        /* would block */
03308                     return WANT_WRITE;
03309 
03310                 case WOLFSSL_CBIO_ERR_CONN_RST:          /* connection reset */
03311                     ssl->options.connReset = 1;
03312                     break;
03313 
03314                 case WOLFSSL_CBIO_ERR_ISR:               /* interrupt */
03315                     /* see if we got our timeout */
03316                     #ifdef WOLFSSL_CALLBACKS
03317                         if (ssl->toInfoOn) {
03318                             struct itimerval timeout;
03319                             getitimer(ITIMER_REAL, &timeout);
03320                             if (timeout.it_value.tv_sec == 0 &&
03321                                                 timeout.it_value.tv_usec == 0) {
03322                                 XSTRNCPY(ssl->timeoutInfo.timeoutName,
03323                                         "send() timeout", MAX_TIMEOUT_NAME_SZ);
03324                                 WOLFSSL_MSG("Got our timeout");
03325                                 return WANT_WRITE;
03326                             }
03327                         }
03328                     #endif
03329                     continue;
03330 
03331                 case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
03332                     ssl->options.connReset = 1;  /* treat same as reset */
03333                     break;
03334 
03335                 default:
03336                     return SOCKET_ERROR_E;
03337             }
03338 
03339             return SOCKET_ERROR_E;
03340         }
03341 
03342         if (sent > (int)ssl->buffers.outputBuffer.length) {
03343             WOLFSSL_MSG("SendBuffered() out of bounds read");
03344             return SEND_OOB_READ_E;
03345         }
03346 
03347         ssl->buffers.outputBuffer.idx += sent;
03348         ssl->buffers.outputBuffer.length -= sent;
03349     }
03350 
03351     ssl->buffers.outputBuffer.idx = 0;
03352 
03353     if (ssl->buffers.outputBuffer.dynamicFlag)
03354         ShrinkOutputBuffer(ssl);
03355 
03356     return 0;
03357 }
03358 
03359 
03360 /* Grow the output buffer */
03361 static INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
03362 {
03363     byte* tmp;
03364     byte  hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
03365                                       RECORD_HEADER_SZ;
03366     byte  align = WOLFSSL_GENERAL_ALIGNMENT;
03367     /* the encrypted data will be offset from the front of the buffer by
03368        the header, if the user wants encrypted alignment they need
03369        to define their alignment requirement */
03370 
03371     if (align) {
03372        while (align < hdrSz)
03373            align *= 2;
03374     }
03375 
03376     tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
03377                           ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
03378     WOLFSSL_MSG("growing output buffer\n");
03379 
03380     if (!tmp) return MEMORY_E;
03381     if (align)
03382         tmp += align - hdrSz;
03383 
03384     if (ssl->buffers.outputBuffer.length)
03385         XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
03386                ssl->buffers.outputBuffer.length);
03387 
03388     if (ssl->buffers.outputBuffer.dynamicFlag)
03389         XFREE(ssl->buffers.outputBuffer.buffer -
03390               ssl->buffers.outputBuffer.offset, ssl->heap,
03391               DYNAMIC_TYPE_OUT_BUFFER);
03392     ssl->buffers.outputBuffer.dynamicFlag = 1;
03393     if (align)
03394         ssl->buffers.outputBuffer.offset = align - hdrSz;
03395     else
03396         ssl->buffers.outputBuffer.offset = 0;
03397     ssl->buffers.outputBuffer.buffer = tmp;
03398     ssl->buffers.outputBuffer.bufferSize = size +
03399                                            ssl->buffers.outputBuffer.length;
03400     return 0;
03401 }
03402 
03403 
03404 /* Grow the input buffer, should only be to read cert or big app data */
03405 int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
03406 {
03407     byte* tmp;
03408     byte  hdrSz = DTLS_RECORD_HEADER_SZ;
03409     byte  align = ssl->options.dtls ? WOLFSSL_GENERAL_ALIGNMENT : 0;
03410     /* the encrypted data will be offset from the front of the buffer by
03411        the dtls record header, if the user wants encrypted alignment they need
03412        to define their alignment requirement. in tls we read record header
03413        to get size of record and put actual data back at front, so don't need */
03414 
03415     if (align) {
03416        while (align < hdrSz)
03417            align *= 2;
03418     }
03419     tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
03420                           DYNAMIC_TYPE_IN_BUFFER);
03421     WOLFSSL_MSG("growing input buffer\n");
03422 
03423     if (!tmp) return MEMORY_E;
03424     if (align)
03425         tmp += align - hdrSz;
03426 
03427     if (usedLength)
03428         XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
03429                     ssl->buffers.inputBuffer.idx, usedLength);
03430 
03431     if (ssl->buffers.inputBuffer.dynamicFlag)
03432         XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
03433               ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
03434 
03435     ssl->buffers.inputBuffer.dynamicFlag = 1;
03436     if (align)
03437         ssl->buffers.inputBuffer.offset = align - hdrSz;
03438     else
03439         ssl->buffers.inputBuffer.offset = 0;
03440     ssl->buffers.inputBuffer.buffer = tmp;
03441     ssl->buffers.inputBuffer.bufferSize = size + usedLength;
03442     ssl->buffers.inputBuffer.idx    = 0;
03443     ssl->buffers.inputBuffer.length = usedLength;
03444 
03445     return 0;
03446 }
03447 
03448 
03449 /* check available size into output buffer, make room if needed */
03450 int CheckAvailableSize(WOLFSSL *ssl, int size)
03451 {
03452 
03453     if (size < 0) {
03454         WOLFSSL_MSG("CheckAvailableSize() called with negative number");
03455         return BAD_FUNC_ARG;
03456     }
03457 
03458     if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
03459                                              < (word32)size) {
03460         if (GrowOutputBuffer(ssl, size) < 0)
03461             return MEMORY_E;
03462     }
03463 
03464     return 0;
03465 }
03466 
03467 
03468 /* do all verify and sanity checks on record header */
03469 static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
03470                            RecordLayerHeader* rh, word16 *size)
03471 {
03472     if (!ssl->options.dtls) {
03473 #ifdef HAVE_FUZZER
03474         if (ssl->fuzzerCb)
03475             ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
03476                     ssl->fuzzerCtx);
03477 #endif
03478         XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
03479         *inOutIdx += RECORD_HEADER_SZ;
03480         ato16(rh->length, size);
03481     }
03482     else {
03483 #ifdef WOLFSSL_DTLS
03484         /* type and version in same sport */
03485         XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
03486         *inOutIdx += ENUM_LEN + VERSION_SZ;
03487         ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
03488         *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
03489         ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
03490         *inOutIdx += 4;  /* advance past rest of seq */
03491         ato16(input + *inOutIdx, size);
03492         *inOutIdx += LENGTH_SZ;
03493 #ifdef HAVE_FUZZER
03494         if (ssl->fuzzerCb)
03495             ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
03496                            VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
03497                            FUZZ_HEAD, ssl->fuzzerCtx);
03498 #endif
03499 #endif
03500     }
03501 
03502 #ifdef WOLFSSL_DTLS
03503     if (ssl->options.dtls &&
03504         (!DtlsCheckWindow(&ssl->keys.dtls_state) ||
03505          (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) {
03506             return SEQUENCE_ERROR;
03507     }
03508 #endif
03509 
03510     /* catch version mismatch */
03511     if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
03512         if (ssl->options.side == WOLFSSL_SERVER_END &&
03513             ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)
03514 
03515             WOLFSSL_MSG("Client attempting to connect with different version");
03516         else if (ssl->options.side == WOLFSSL_CLIENT_END &&
03517                                  ssl->options.downgrade &&
03518                                  ssl->options.connectState < FIRST_REPLY_DONE)
03519             WOLFSSL_MSG("Server attempting to accept with different version");
03520         else if (ssl->options.dtls
03521                     && (ssl->options.acceptState == ACCEPT_BEGIN
03522                     || ssl->options.acceptState == CLIENT_HELLO_SENT))
03523             /* Do not check version until Server Hello or Hello Again (2) */
03524             WOLFSSL_MSG("Use version for formatting only in DTLS till ");
03525         else {
03526             WOLFSSL_MSG("SSL version error");
03527             return VERSION_ERROR;              /* only use requested version */
03528         }
03529     }
03530 
03531     /* record layer length check */
03532 #ifdef HAVE_MAX_FRAGMENT
03533     if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
03534         SendAlert(ssl, alert_fatal, record_overflow);
03535         return LENGTH_ERROR;
03536     }
03537 #else
03538     if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
03539         return LENGTH_ERROR;
03540 #endif
03541 
03542     /* verify record type here as well */
03543     switch (rh->type) {
03544         case handshake:
03545         case change_cipher_spec:
03546         case application_data:
03547         case alert:
03548             break;
03549         case no_type:
03550         default:
03551             WOLFSSL_MSG("Unknown Record Type");
03552             return UNKNOWN_RECORD_TYPE;
03553     }
03554 
03555     /* haven't decrypted this record yet */
03556     ssl->keys.decryptedCur = 0;
03557 
03558     return 0;
03559 }
03560 
03561 
03562 static int GetHandShakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
03563                               byte *type, word32 *size, word32 totalSz)
03564 {
03565     const byte *ptr = input + *inOutIdx;
03566     (void)ssl;
03567 
03568     *inOutIdx += HANDSHAKE_HEADER_SZ;
03569     if (*inOutIdx > totalSz)
03570         return BUFFER_E;
03571 
03572     *type = ptr[0];
03573     c24to32(&ptr[1], size);
03574 
03575     return 0;
03576 }
03577 
03578 
03579 #ifdef WOLFSSL_DTLS
03580 static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
03581                                   word32* inOutIdx, byte *type, word32 *size,
03582                                   word32 *fragOffset, word32 *fragSz,
03583                                   word32 totalSz)
03584 {
03585     word32 idx = *inOutIdx;
03586 
03587     *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
03588     if (*inOutIdx > totalSz)
03589         return BUFFER_E;
03590 
03591     *type = input[idx++];
03592     c24to32(input + idx, size);
03593     idx += BYTE3_LEN;
03594 
03595     ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
03596     idx += DTLS_HANDSHAKE_SEQ_SZ;
03597 
03598     c24to32(input + idx, fragOffset);
03599     idx += DTLS_HANDSHAKE_FRAG_SZ;
03600     c24to32(input + idx, fragSz);
03601 
03602     return 0;
03603 }
03604 #endif
03605 
03606 
03607 #ifndef NO_OLD_TLS
03608 /* fill with MD5 pad size since biggest required */
03609 static const byte PAD1[PAD_MD5] =
03610                               { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03611                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03612                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03613                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03614                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
03615                                 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
03616                               };
03617 static const byte PAD2[PAD_MD5] =
03618                               { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03619                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03620                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03621                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03622                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
03623                                 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
03624                               };
03625 
03626 /* calculate MD5 hash for finished */
03627 #ifdef WOLFSSL_TI_HASH
03628 #include <wolfssl/wolfcrypt/hash.h>
03629 #endif
03630 
03631 static void BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
03632 {
03633 
03634     byte md5_result[MD5_DIGEST_SIZE];
03635 
03636 #ifdef WOLFSSL_SMALL_STACK
03637         Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03638         Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03639 #else
03640         Md5 md5[1];
03641         Md5 md5_2[1];
03642 #endif
03643 
03644     /* make md5 inner */
03645     md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
03646 
03647     wc_Md5Update(&ssl->hsHashes->hashMd5, sender, SIZEOF_SENDER);
03648     wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
03649     wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
03650     wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
03651     wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
03652 
03653     /* make md5 outer */
03654     wc_InitMd5(md5_2) ;
03655     wc_Md5Update(md5_2, ssl->arrays->masterSecret,SECRET_LEN);
03656     wc_Md5Update(md5_2, PAD2, PAD_MD5);
03657     wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
03658     wc_Md5Final(md5_2, hashes->md5);
03659 
03660 #ifdef WOLFSSL_SMALL_STACK
03661     XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03662     XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03663 #endif
03664 
03665 }
03666 
03667 
03668 /* calculate SHA hash for finished */
03669 static void BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
03670 {
03671     byte sha_result[SHA_DIGEST_SIZE];
03672 
03673 #ifdef WOLFSSL_SMALL_STACK
03674         Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03675         Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
03676 #else
03677         Sha sha[1];
03678         Sha sha2[1] ;
03679 #endif
03680     /* make sha inner */
03681     sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
03682 
03683     wc_ShaUpdate(&ssl->hsHashes->hashSha, sender, SIZEOF_SENDER);
03684     wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
03685     wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
03686     wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
03687     wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
03688 
03689     /* make sha outer */
03690     wc_InitSha(sha2) ;
03691     wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
03692     wc_ShaUpdate(sha2, PAD2, PAD_SHA);
03693     wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
03694     wc_ShaFinal(sha2, hashes->sha);
03695 
03696 #ifdef WOLFSSL_SMALL_STACK
03697     XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03698     XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03699 #endif
03700 
03701 }
03702 #endif
03703 
03704 /* Finished doesn't support SHA512, not SHA512 cipher suites yet */
03705 static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
03706 {
03707     int ret = 0;
03708 #ifdef WOLFSSL_SMALL_STACK
03709     #ifdef WOLFSSL_SHA384
03710         Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,                                                                        DYNAMIC_TYPE_TMP_BUFFER);
03711     #endif
03712 #else
03713     #ifdef WOLFSSL_SHA384
03714         Sha384 sha384[1];
03715     #endif
03716 #endif
03717 
03718 #ifdef WOLFSSL_SMALL_STACK
03719     if (ssl == NULL
03720     #ifdef WOLFSSL_SHA384
03721         || sha384 == NULL
03722     #endif
03723         ) {
03724     #ifdef WOLFSSL_SHA384
03725         XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03726     #endif
03727         return MEMORY_E;
03728     }
03729 #endif
03730 
03731     /* store current states, building requires get_digest which resets state */
03732 #ifdef WOLFSSL_SHA384
03733     sha384[0] = ssl->hsHashes->hashSha384;
03734 #endif
03735 
03736 #ifndef NO_TLS
03737     if (ssl->options.tls) {
03738         ret = BuildTlsFinished(ssl, hashes, sender);
03739     }
03740 #endif
03741 #ifndef NO_OLD_TLS
03742     if (!ssl->options.tls) {
03743         BuildMD5(ssl, hashes, sender);
03744         BuildSHA(ssl, hashes, sender);
03745     }
03746 #endif
03747 
03748     /* restore */
03749     if (IsAtLeastTLSv1_2(ssl)) {
03750     #ifdef WOLFSSL_SHA384
03751         ssl->hsHashes->hashSha384 = sha384[0];
03752     #endif
03753     }
03754 
03755 #ifdef WOLFSSL_SMALL_STACK
03756 #ifdef WOLFSSL_SHA384
03757     XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
03758 #endif
03759 #endif
03760 
03761     return ret;
03762 }
03763 
03764 
03765     /* cipher requirements */
03766     enum {
03767         REQUIRES_RSA,
03768         REQUIRES_DHE,
03769         REQUIRES_ECC,
03770         REQUIRES_ECC_STATIC,
03771         REQUIRES_PSK,
03772         REQUIRES_NTRU,
03773         REQUIRES_RSA_SIG
03774     };
03775 
03776 
03777 
03778     /* Does this cipher suite (first, second) have the requirement
03779        an ephemeral key exchange will still require the key for signing
03780        the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
03781     static int CipherRequires(byte first, byte second, int requirement)
03782     {
03783 
03784         if (first == CHACHA_BYTE) {
03785 
03786         switch (second) {
03787 
03788         case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
03789             if (requirement == REQUIRES_RSA)
03790                 return 1;
03791             break;
03792 
03793         case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
03794             if (requirement == REQUIRES_ECC)
03795                 return 1;
03796             break;
03797 
03798         case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
03799             if (requirement == REQUIRES_RSA)
03800                 return 1;
03801             if (requirement == REQUIRES_DHE)
03802                 return 1;
03803             break;
03804 
03805         case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
03806             if (requirement == REQUIRES_RSA)
03807                 return 1;
03808             break;
03809 
03810         case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
03811             if (requirement == REQUIRES_ECC)
03812                 return 1;
03813             break;
03814 
03815         case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
03816             if (requirement == REQUIRES_RSA)
03817                 return 1;
03818             if (requirement == REQUIRES_DHE)
03819                 return 1;
03820             break;
03821 
03822 
03823         case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
03824             if (requirement == REQUIRES_PSK)
03825                 return 1;
03826             break;
03827 
03828         case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 :
03829             if (requirement == REQUIRES_PSK)
03830                 return 1;
03831             break;
03832 
03833         case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 :
03834             if (requirement == REQUIRES_PSK)
03835                 return 1;
03836             if (requirement == REQUIRES_DHE)
03837                 return 1;
03838             break;
03839             }
03840         }
03841 
03842         /* ECC extensions */
03843         if (first == ECC_BYTE) {
03844 
03845         switch (second) {
03846 
03847 #ifndef NO_RSA
03848         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
03849             if (requirement == REQUIRES_RSA)
03850                 return 1;
03851             break;
03852 
03853         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
03854             if (requirement == REQUIRES_ECC_STATIC)
03855                 return 1;
03856             if (requirement == REQUIRES_RSA_SIG)
03857                 return 1;
03858             break;
03859 
03860 #ifndef NO_DES3
03861         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
03862             if (requirement == REQUIRES_RSA)
03863                 return 1;
03864             break;
03865 
03866         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
03867             if (requirement == REQUIRES_ECC_STATIC)
03868                 return 1;
03869             if (requirement == REQUIRES_RSA_SIG)
03870                 return 1;
03871             break;
03872 #endif
03873 
03874 #ifndef NO_RC4
03875         case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
03876             if (requirement == REQUIRES_RSA)
03877                 return 1;
03878             break;
03879 
03880         case TLS_ECDH_RSA_WITH_RC4_128_SHA :
03881             if (requirement == REQUIRES_ECC_STATIC)
03882                 return 1;
03883             if (requirement == REQUIRES_RSA_SIG)
03884                 return 1;
03885             break;
03886 #endif
03887 #endif /* NO_RSA */
03888 
03889 #ifndef NO_DES3
03890         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
03891             if (requirement == REQUIRES_ECC)
03892                 return 1;
03893             break;
03894 
03895         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
03896             if (requirement == REQUIRES_ECC_STATIC)
03897                 return 1;
03898             break;
03899 #endif
03900 #ifndef NO_RC4
03901         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
03902             if (requirement == REQUIRES_ECC)
03903                 return 1;
03904             break;
03905 
03906         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
03907             if (requirement == REQUIRES_ECC_STATIC)
03908                 return 1;
03909             break;
03910 #endif
03911 #ifndef NO_RSA
03912         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
03913             if (requirement == REQUIRES_RSA)
03914                 return 1;
03915             break;
03916 
03917         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
03918             if (requirement == REQUIRES_ECC_STATIC)
03919                 return 1;
03920             if (requirement == REQUIRES_RSA_SIG)
03921                 return 1;
03922             break;
03923 #endif
03924 
03925         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
03926             if (requirement == REQUIRES_ECC)
03927                 return 1;
03928             break;
03929 
03930         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
03931             if (requirement == REQUIRES_ECC_STATIC)
03932                 return 1;
03933             break;
03934 
03935         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
03936             if (requirement == REQUIRES_ECC)
03937                 return 1;
03938             break;
03939 
03940         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
03941             if (requirement == REQUIRES_ECC_STATIC)
03942                 return 1;
03943             break;
03944 
03945         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
03946             if (requirement == REQUIRES_ECC)
03947                 return 1;
03948             break;
03949 
03950         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
03951             if (requirement == REQUIRES_ECC)
03952                 return 1;
03953             break;
03954 
03955         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
03956             if (requirement == REQUIRES_ECC_STATIC)
03957                 return 1;
03958             break;
03959 
03960         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
03961             if (requirement == REQUIRES_ECC_STATIC)
03962                 return 1;
03963             break;
03964 
03965 #ifndef NO_RSA
03966         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
03967             if (requirement == REQUIRES_RSA)
03968                 return 1;
03969             break;
03970 
03971         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
03972             if (requirement == REQUIRES_RSA)
03973                 return 1;
03974             break;
03975 
03976         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
03977             if (requirement == REQUIRES_ECC_STATIC)
03978                 return 1;
03979             if (requirement == REQUIRES_RSA_SIG)
03980                 return 1;
03981             break;
03982 
03983         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
03984             if (requirement == REQUIRES_ECC_STATIC)
03985                 return 1;
03986             if (requirement == REQUIRES_RSA_SIG)
03987                 return 1;
03988             break;
03989 
03990         case TLS_RSA_WITH_AES_128_CCM_8 :
03991         case TLS_RSA_WITH_AES_256_CCM_8 :
03992             if (requirement == REQUIRES_RSA)
03993                 return 1;
03994             if (requirement == REQUIRES_RSA_SIG)
03995                 return 1;
03996             break;
03997 
03998         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
03999         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
04000             if (requirement == REQUIRES_RSA)
04001                 return 1;
04002             if (requirement == REQUIRES_RSA_SIG)
04003                 return 1;
04004             break;
04005 
04006         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
04007         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
04008             if (requirement == REQUIRES_RSA_SIG)
04009                 return 1;
04010             if (requirement == REQUIRES_ECC_STATIC)
04011                 return 1;
04012             break;
04013 #endif
04014 
04015         case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
04016         case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
04017             if (requirement == REQUIRES_ECC)
04018                 return 1;
04019             break;
04020 
04021         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
04022         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
04023             if (requirement == REQUIRES_ECC)
04024                 return 1;
04025             break;
04026 
04027         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
04028         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
04029             if (requirement == REQUIRES_ECC)
04030                 return 1;
04031             if (requirement == REQUIRES_ECC_STATIC)
04032                 return 1;
04033             break;
04034 
04035         case TLS_PSK_WITH_AES_128_CCM:
04036         case TLS_PSK_WITH_AES_256_CCM:
04037         case TLS_PSK_WITH_AES_128_CCM_8:
04038         case TLS_PSK_WITH_AES_256_CCM_8:
04039             if (requirement == REQUIRES_PSK)
04040                 return 1;
04041             break;
04042 
04043         case TLS_DHE_PSK_WITH_AES_128_CCM:
04044         case TLS_DHE_PSK_WITH_AES_256_CCM:
04045             if (requirement == REQUIRES_PSK)
04046                 return 1;
04047             if (requirement == REQUIRES_DHE)
04048                 return 1;
04049             break;
04050 
04051         case TLS_ECDHE_ECDSA_WITH_NULL_SHA :
04052             if (requirement == REQUIRES_ECC)
04053                 return 1;
04054             break;
04055 
04056         case TLS_ECDHE_PSK_WITH_NULL_SHA256 :
04057             if (requirement == REQUIRES_PSK)
04058                 return 1;
04059             break;
04060 
04061         case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 :
04062             if (requirement == REQUIRES_PSK)
04063                 return 1;
04064             break;
04065 
04066         default:
04067             WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
04068             return 0;
04069         }   /* switch */
04070         }   /* if     */
04071         if (first != ECC_BYTE && first != CHACHA_BYTE) {   /* normal suites */
04072         switch (second) {
04073 
04074 #ifndef NO_RSA
04075         case SSL_RSA_WITH_RC4_128_SHA :
04076             if (requirement == REQUIRES_RSA)
04077                 return 1;
04078             break;
04079 
04080         case SSL_RSA_WITH_RC4_128_MD5 :
04081             if (requirement == REQUIRES_RSA)
04082                 return 1;
04083             break;
04084 
04085         case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
04086             if (requirement == REQUIRES_RSA)
04087                 return 1;
04088             break;
04089 
04090         case TLS_NTRU_RSA_WITH_RC4_128_SHA :
04091             if (requirement == REQUIRES_NTRU)
04092                 return 1;
04093             break;
04094 
04095         case TLS_RSA_WITH_AES_128_CBC_SHA :
04096             if (requirement == REQUIRES_RSA)
04097                 return 1;
04098             break;
04099 
04100         case TLS_RSA_WITH_AES_128_CBC_SHA256 :
04101             if (requirement == REQUIRES_RSA)
04102                 return 1;
04103             break;
04104 
04105         case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
04106             if (requirement == REQUIRES_NTRU)
04107                 return 1;
04108             break;
04109 
04110         case TLS_RSA_WITH_AES_256_CBC_SHA :
04111             if (requirement == REQUIRES_RSA)
04112                 return 1;
04113             break;
04114 
04115         case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
04116             if (requirement == REQUIRES_NTRU)
04117                 return 1;
04118             break;
04119 
04120         case TLS_RSA_WITH_AES_256_CBC_SHA256 :
04121             if (requirement == REQUIRES_RSA)
04122                 return 1;
04123             break;
04124 
04125         case TLS_RSA_WITH_NULL_SHA :
04126         case TLS_RSA_WITH_NULL_SHA256 :
04127             if (requirement == REQUIRES_RSA)
04128                 return 1;
04129             break;
04130 
04131         case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
04132             if (requirement == REQUIRES_NTRU)
04133                 return 1;
04134             break;
04135 
04136         case SSL_RSA_WITH_IDEA_CBC_SHA :
04137             if (requirement == REQUIRES_RSA)
04138                 return 1;
04139             break;
04140 #endif
04141 
04142         case TLS_PSK_WITH_AES_128_GCM_SHA256 :
04143         case TLS_PSK_WITH_AES_256_GCM_SHA384 :
04144         case TLS_PSK_WITH_AES_128_CBC_SHA256 :
04145         case TLS_PSK_WITH_AES_256_CBC_SHA384 :
04146         case TLS_PSK_WITH_AES_128_CBC_SHA :
04147         case TLS_PSK_WITH_AES_256_CBC_SHA :
04148         case TLS_PSK_WITH_NULL_SHA384 :
04149         case TLS_PSK_WITH_NULL_SHA256 :
04150         case TLS_PSK_WITH_NULL_SHA :
04151             if (requirement == REQUIRES_PSK)
04152                 return 1;
04153             break;
04154 
04155         case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
04156         case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
04157         case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
04158         case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
04159         case TLS_DHE_PSK_WITH_NULL_SHA384 :
04160         case TLS_DHE_PSK_WITH_NULL_SHA256 :
04161             if (requirement == REQUIRES_DHE)
04162                 return 1;
04163             if (requirement == REQUIRES_PSK)
04164                 return 1;
04165             break;
04166 
04167 #ifndef NO_RSA
04168         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
04169             if (requirement == REQUIRES_RSA)
04170                 return 1;
04171             if (requirement == REQUIRES_DHE)
04172                 return 1;
04173             break;
04174 
04175         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
04176             if (requirement == REQUIRES_RSA)
04177                 return 1;
04178             if (requirement == REQUIRES_DHE)
04179                 return 1;
04180             break;
04181 
04182         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
04183             if (requirement == REQUIRES_RSA)
04184                 return 1;
04185             if (requirement == REQUIRES_DHE)
04186                 return 1;
04187             break;
04188 
04189         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
04190             if (requirement == REQUIRES_RSA)
04191                 return 1;
04192             if (requirement == REQUIRES_DHE)
04193                 return 1;
04194             break;
04195 
04196         case TLS_RSA_WITH_HC_128_MD5 :
04197             if (requirement == REQUIRES_RSA)
04198                 return 1;
04199             break;
04200 
04201         case TLS_RSA_WITH_HC_128_SHA :
04202             if (requirement == REQUIRES_RSA)
04203                 return 1;
04204             break;
04205 
04206         case TLS_RSA_WITH_HC_128_B2B256:
04207             if (requirement == REQUIRES_RSA)
04208                 return 1;
04209             break;
04210 
04211         case TLS_RSA_WITH_AES_128_CBC_B2B256:
04212         case TLS_RSA_WITH_AES_256_CBC_B2B256:
04213             if (requirement == REQUIRES_RSA)
04214                 return 1;
04215             break;
04216 
04217         case TLS_RSA_WITH_RABBIT_SHA :
04218             if (requirement == REQUIRES_RSA)
04219                 return 1;
04220             break;
04221 
04222         case TLS_RSA_WITH_AES_128_GCM_SHA256 :
04223         case TLS_RSA_WITH_AES_256_GCM_SHA384 :
04224             if (requirement == REQUIRES_RSA)
04225                 return 1;
04226             break;
04227 
04228         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
04229         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
04230             if (requirement == REQUIRES_RSA)
04231                 return 1;
04232             if (requirement == REQUIRES_DHE)
04233                 return 1;
04234             break;
04235 
04236         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
04237         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
04238         case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
04239         case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
04240             if (requirement == REQUIRES_RSA)
04241                 return 1;
04242             break;
04243 
04244         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
04245         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
04246         case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
04247         case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
04248             if (requirement == REQUIRES_RSA)
04249                 return 1;
04250             if (requirement == REQUIRES_RSA_SIG)
04251                 return 1;
04252             if (requirement == REQUIRES_DHE)
04253                 return 1;
04254             break;
04255 #endif
04256 #ifdef HAVE_ANON
04257         case TLS_DH_anon_WITH_AES_128_CBC_SHA :
04258             if (requirement == REQUIRES_DHE)
04259                 return 1;
04260             break;
04261 #endif
04262 
04263         default:
04264             WOLFSSL_MSG("Unsupported cipher suite, CipherRequires");
04265             return 0;
04266         }  /* switch */
04267         }  /* if ECC / Normal suites else */
04268 
04269         return 0;
04270     }
04271 
04272 
04273 #ifndef NO_CERTS
04274 
04275 
04276 /* Match names with wildcards, each wildcard can represent a single name
04277    component or fragment but not mulitple names, i.e.,
04278    *.z.com matches y.z.com but not x.y.z.com
04279 
04280    return 1 on success */
04281 static int MatchDomainName(const char* pattern, int len, const char* str)
04282 {
04283     char p, s;
04284 
04285     if (pattern == NULL || str == NULL || len <= 0)
04286         return 0;
04287 
04288     while (len > 0) {
04289 
04290         p = (char)XTOLOWER((unsigned char)*pattern++);
04291         if (p == 0)
04292             break;
04293 
04294         if (p == '*') {
04295             while (--len > 0 &&
04296                          (p = (char)XTOLOWER((unsigned char)*pattern++)) == '*')
04297                 ;
04298 
04299             if (len == 0)
04300                 p = '\0';
04301 
04302             while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
04303                 if (s == p)
04304                     break;
04305                 if (s == '.')
04306                     return 0;
04307                 str++;
04308             }
04309         }
04310         else {
04311             if (p != (char)XTOLOWER((unsigned char) *str))
04312                 return 0;
04313         }
04314 
04315         if (*str != '\0')
04316             str++;
04317 
04318         if (len > 0)
04319             len--;
04320     }
04321 
04322     return *str == '\0';
04323 }
04324 
04325 
04326 /* try to find an altName match to domain, return 1 on success */
04327 static int CheckAltNames(DecodedCert* dCert, char* domain)
04328 {
04329     int        match = 0;
04330     DNS_entry* altName = NULL;
04331 
04332     WOLFSSL_MSG("Checking AltNames");
04333 
04334     if (dCert)
04335         altName = dCert->altNames;
04336 
04337     while (altName) {
04338         WOLFSSL_MSG("    individual AltName check");
04339 
04340         if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
04341             match = 1;
04342             break;
04343         }
04344 
04345         altName = altName->next;
04346     }
04347 
04348     return match;
04349 }
04350 
04351 
04352 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
04353 
04354 /* Copy parts X509 needs from Decoded cert, 0 on success */
04355 int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
04356 {
04357     int ret = 0;
04358 
04359     if (x509 == NULL || dCert == NULL)
04360         return BAD_FUNC_ARG;
04361 
04362     x509->version = dCert->version + 1;
04363 
04364     XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
04365     x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
04366     x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
04367 #ifdef OPENSSL_EXTRA
04368     if (dCert->issuerName.fullName != NULL) {
04369         XMEMCPY(&x509->issuer.fullName,
04370                                        &dCert->issuerName, sizeof(DecodedName));
04371         x509->issuer.fullName.fullName = (char*)XMALLOC(
04372                         dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
04373         if (x509->issuer.fullName.fullName != NULL)
04374             XMEMCPY(x509->issuer.fullName.fullName,
04375                      dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
04376     }
04377 #endif /* OPENSSL_EXTRA */
04378 
04379     XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
04380     x509->subject.name[ASN_NAME_MAX - 1] = '\0';
04381     x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
04382 #ifdef OPENSSL_EXTRA
04383     if (dCert->subjectName.fullName != NULL) {
04384         XMEMCPY(&x509->subject.fullName,
04385                                       &dCert->subjectName, sizeof(DecodedName));
04386         x509->subject.fullName.fullName = (char*)XMALLOC(
04387                        dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
04388         if (x509->subject.fullName.fullName != NULL)
04389             XMEMCPY(x509->subject.fullName.fullName,
04390                    dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
04391     }
04392 #endif /* OPENSSL_EXTRA */
04393 
04394     XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
04395     x509->serialSz = dCert->serialSz;
04396     if (dCert->subjectCNLen < ASN_NAME_MAX) {
04397         XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
04398         x509->subjectCN[dCert->subjectCNLen] = '\0';
04399     }
04400     else
04401         x509->subjectCN[0] = '\0';
04402 
04403 #ifdef WOLFSSL_SEP
04404     {
04405         int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
04406         if (minSz > 0) {
04407             x509->deviceTypeSz = minSz;
04408             XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
04409         }
04410         else
04411             x509->deviceTypeSz = 0;
04412         minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
04413         if (minSz != 0) {
04414             x509->hwTypeSz = minSz;
04415             XMEMCPY(x509->hwType, dCert->hwType, minSz);
04416         }
04417         else
04418             x509->hwTypeSz = 0;
04419         minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
04420         if (minSz != 0) {
04421             x509->hwSerialNumSz = minSz;
04422             XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
04423         }
04424         else
04425             x509->hwSerialNumSz = 0;
04426     }
04427 #endif /* WOLFSSL_SEP */
04428     {
04429         int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
04430         if (minSz != 0) {
04431             x509->notBeforeSz = minSz;
04432             XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
04433         }
04434         else
04435             x509->notBeforeSz = 0;
04436         minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
04437         if (minSz != 0) {
04438             x509->notAfterSz = minSz;
04439             XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
04440         }
04441         else
04442             x509->notAfterSz = 0;
04443     }
04444 
04445     if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
04446         x509->pubKey.buffer = (byte*)XMALLOC(
04447                               dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
04448         if (x509->pubKey.buffer != NULL) {
04449             x509->pubKeyOID = dCert->keyOID;
04450             x509->pubKey.length = dCert->pubKeySize;
04451             XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
04452         }
04453         else
04454             ret = MEMORY_E;
04455     }
04456 
04457     if (dCert->signature != NULL && dCert->sigLength != 0) {
04458         x509->sig.buffer = (byte*)XMALLOC(
04459                                 dCert->sigLength, NULL, DYNAMIC_TYPE_SIGNATURE);
04460         if (x509->sig.buffer == NULL) {
04461             ret = MEMORY_E;
04462         }
04463         else {
04464             XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
04465             x509->sig.length = dCert->sigLength;
04466             x509->sigOID = dCert->signatureOID;
04467         }
04468     }
04469 
04470     /* store cert for potential retrieval */
04471     if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, NULL) == 0) {
04472         XMEMCPY(x509->derCert->buffer, dCert->source, dCert->maxIdx);
04473     }
04474     else {
04475         ret = MEMORY_E;
04476     }
04477 
04478     x509->altNames       = dCert->altNames;
04479     dCert->weOwnAltNames = 0;
04480     x509->altNamesNext   = x509->altNames;  /* index hint */
04481 
04482     x509->isCa = dCert->isCA;
04483 #ifdef OPENSSL_EXTRA
04484     x509->pathLength = dCert->pathLength;
04485     x509->keyUsage = dCert->extKeyUsage;
04486 
04487     x509->basicConstSet = dCert->extBasicConstSet;
04488     x509->basicConstCrit = dCert->extBasicConstCrit;
04489     x509->basicConstPlSet = dCert->extBasicConstPlSet;
04490     x509->subjAltNameSet = dCert->extSubjAltNameSet;
04491     x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
04492     x509->authKeyIdSet = dCert->extAuthKeyIdSet;
04493     x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
04494     if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
04495         x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, NULL,
04496                                          DYNAMIC_TYPE_X509_EXT);
04497         if (x509->authKeyId != NULL) {
04498             XMEMCPY(x509->authKeyId,
04499                                  dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
04500             x509->authKeyIdSz = dCert->extAuthKeyIdSz;
04501         }
04502         else
04503             ret = MEMORY_E;
04504     }
04505     x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
04506     x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
04507     if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
04508         x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, NULL,
04509                                          DYNAMIC_TYPE_X509_EXT);
04510         if (x509->subjKeyId != NULL) {
04511             XMEMCPY(x509->subjKeyId,
04512                                  dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
04513             x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
04514         }
04515         else
04516             ret = MEMORY_E;
04517     }
04518     x509->keyUsageSet = dCert->extKeyUsageSet;
04519     x509->keyUsageCrit = dCert->extKeyUsageCrit;
04520     #ifdef WOLFSSL_SEP
04521         x509->certPolicySet = dCert->extCertPolicySet;
04522         x509->certPolicyCrit = dCert->extCertPolicyCrit;
04523     #endif /* WOLFSSL_SEP */
04524 #endif /* OPENSSL_EXTRA */
04525 #ifdef HAVE_ECC
04526     x509->pkCurveOID = dCert->pkCurveOID;
04527 #endif /* HAVE_ECC */
04528 
04529     return ret;
04530 }
04531 
04532 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
04533 
04534 
04535 static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
04536                                                                 word32 size)
04537 {
04538     word32 listSz;
04539     word32 begin = *inOutIdx;
04540     int    ret = 0;
04541     int    anyError = 0;
04542     int    totalCerts = 0;    /* number of certs in certs buffer */
04543     int    count;
04544     buffer certs[MAX_CHAIN_DEPTH];
04545 
04546 #ifdef WOLFSSL_SMALL_STACK
04547     char*                  domain = NULL;
04548     DecodedCert*           dCert  = NULL;
04549     WOLFSSL_X509_STORE_CTX* store  = NULL;
04550 #else
04551     char                   domain[ASN_NAME_MAX];
04552     DecodedCert            dCert[1];
04553     WOLFSSL_X509_STORE_CTX  store[1];
04554 #endif
04555 
04556 #ifdef WOLFSSL_TRUST_PEER_CERT
04557     byte haveTrustPeer = 0; /* was cert verified by loaded trusted peer cert */
04558 #endif
04559 
04560     #ifdef WOLFSSL_CALLBACKS
04561         if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
04562         if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
04563     #endif
04564 
04565     if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
04566         return BUFFER_ERROR;
04567 
04568     c24to32(input + *inOutIdx, &listSz);
04569     *inOutIdx += OPAQUE24_LEN;
04570 
04571     if (listSz > MAX_RECORD_SIZE)
04572         return BUFFER_E;
04573 
04574     if ((*inOutIdx - begin) + listSz != size)
04575         return BUFFER_ERROR;
04576 
04577     WOLFSSL_MSG("Loading peer's cert chain");
04578     /* first put cert chain into buffer so can verify top down
04579        we're sent bottom up */
04580     while (listSz) {
04581         word32 certSz;
04582 
04583         if (totalCerts >= MAX_CHAIN_DEPTH)
04584             return MAX_CHAIN_ERROR;
04585 
04586         if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
04587             return BUFFER_ERROR;
04588 
04589         c24to32(input + *inOutIdx, &certSz);
04590         *inOutIdx += OPAQUE24_LEN;
04591 
04592         if ((*inOutIdx - begin) + certSz > size)
04593             return BUFFER_ERROR;
04594 
04595         certs[totalCerts].length = certSz;
04596         certs[totalCerts].buffer = input + *inOutIdx;
04597 
04598 #ifdef SESSION_CERTS
04599         if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
04600                                        certSz < MAX_X509_SIZE) {
04601             ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
04602             XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
04603                     input + *inOutIdx, certSz);
04604             ssl->session.chain.count++;
04605         } else {
04606             WOLFSSL_MSG("Couldn't store chain cert for session");
04607         }
04608 #endif
04609 
04610         *inOutIdx += certSz;
04611         listSz -= certSz + CERT_HEADER_SZ;
04612 
04613         totalCerts++;
04614         WOLFSSL_MSG("    Put another cert into chain");
04615     }
04616 
04617     count = totalCerts;
04618 
04619 #ifdef WOLFSSL_SMALL_STACK
04620     dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
04621                                                        DYNAMIC_TYPE_TMP_BUFFER);
04622     if (dCert == NULL)
04623         return MEMORY_E;
04624 #endif
04625 
04626 #ifdef WOLFSSL_TRUST_PEER_CERT
04627     /* if using trusted peer certs check before verify chain and CA test */
04628     if (count > 0) {
04629         TrustedPeerCert* tp = NULL;
04630 
04631         InitDecodedCert(dCert, certs[0].buffer, certs[0].length, ssl->heap);
04632         ret = ParseCertRelative(dCert, CERT_TYPE, 0, ssl->ctx->cm);
04633         #ifndef NO_SKID
04634             if (dCert->extAuthKeyIdSet) {
04635                 tp = GetTrustedPeer(ssl->ctx->cm, dCert->extSubjKeyId,
04636                                                                  WC_MATCH_SKID);
04637             }
04638             else { /* if the cert has no SKID try to match by name */
04639                 tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash,
04640                                                                  WC_MATCH_NAME);
04641             }
04642         #else /* NO_SKID */
04643             tp = GetTrustedPeer(ssl->ctx->cm, dCert->subjectHash,
04644                                                                  WC_MATCH_NAME);
04645         #endif /* NO SKID */
04646         WOLFSSL_MSG("Checking for trusted peer cert");
04647 
04648         if (tp == NULL) {
04649             /* no trusted peer cert */
04650             WOLFSSL_MSG("No matching trusted peer cert. Checking CAs");
04651             FreeDecodedCert(dCert);
04652         } else if (MatchTrustedPeer(tp, dCert)){
04653             WOLFSSL_MSG("Found matching trusted peer cert");
04654             haveTrustPeer = 1;
04655         } else {
04656             WOLFSSL_MSG("Trusted peer cert did not match!");
04657             FreeDecodedCert(dCert);
04658         }
04659     }
04660     if (!haveTrustPeer) { /* do not verify chain if trusted peer cert found */
04661 #endif /* WOLFSSL_TRUST_PEER_CERT */
04662 
04663     /* verify up to peer's first */
04664     while (count > 1) {
04665         buffer myCert = certs[count - 1];
04666         byte* subjectHash;
04667 
04668         InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
04669         ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
04670                                 ssl->ctx->cm);
04671         #ifndef NO_SKID
04672             subjectHash = dCert->extSubjKeyId;
04673         #else
04674             subjectHash = dCert->subjectHash;
04675         #endif
04676 
04677         if (ret == 0 && dCert->isCA == 0) {
04678             WOLFSSL_MSG("Chain cert is not a CA, not adding as one");
04679         }
04680         else if (ret == 0 && ssl->options.verifyNone) {
04681             WOLFSSL_MSG("Chain cert not verified by option, not adding as CA");
04682         }
04683         else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
04684             DerBuffer* add = NULL;
04685             ret = AllocDer(&add, myCert.length, CA_TYPE, ssl->heap);
04686             if (ret < 0) {
04687             #ifdef WOLFSSL_SMALL_STACK
04688                 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04689             #endif
04690                 return ret;
04691             }
04692 
04693             WOLFSSL_MSG("Adding CA from chain");
04694 
04695             XMEMCPY(add->buffer, myCert.buffer, myCert.length);
04696 
04697             /* already verified above */
04698             ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0);
04699             if (ret == 1) ret = 0;   /* SSL_SUCCESS for external */
04700         }
04701         else if (ret != 0) {
04702             WOLFSSL_MSG("Failed to verify CA from chain");
04703         }
04704         else {
04705             WOLFSSL_MSG("Verified CA from chain and already had it");
04706         }
04707 
04708 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
04709         if (ret == 0) {
04710             int doCrlLookup = 1;
04711 
04712 #ifdef HAVE_OCSP
04713         #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
04714             if (ssl->status_request_v2)
04715                 ret = TLSX_CSR2_InitRequests(ssl->extensions, dCert, 0);
04716             else /* skips OCSP and force CRL check */
04717         #endif
04718             if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
04719                 WOLFSSL_MSG("Doing Non Leaf OCSP check");
04720                 ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL);
04721                 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
04722                 if (ret != 0) {
04723                     doCrlLookup = 0;
04724                     WOLFSSL_MSG("\tOCSP Lookup not ok");
04725                 }
04726             }
04727 #endif /* HAVE_OCSP */
04728 
04729 #ifdef HAVE_CRL
04730             if (ret == 0 && doCrlLookup && ssl->ctx->cm->crlEnabled
04731                                                  && ssl->ctx->cm->crlCheckAll) {
04732                 WOLFSSL_MSG("Doing Non Leaf CRL check");
04733                 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
04734 
04735                 if (ret != 0) {
04736                     WOLFSSL_MSG("\tCRL check not ok");
04737                 }
04738             }
04739 #else
04740             (void)doCrlLookup;
04741 #endif /* HAVE_CRL */
04742         }
04743 #endif /* HAVE_OCSP || HAVE_CRL */
04744 
04745         if (ret != 0 && anyError == 0)
04746             anyError = ret;   /* save error from last time */
04747 
04748         FreeDecodedCert(dCert);
04749         count--;
04750     }
04751 
04752 #ifdef WOLFSSL_TRUST_PEER_CERT
04753     } /* end of if (haveTrustPeer) -- a check for if already verified */
04754 #endif
04755 
04756     /* peer's, may not have one if blank client cert sent by TLSv1.2 */
04757     if (count) {
04758         buffer myCert = certs[0];
04759         int    fatal  = 0;
04760 
04761         WOLFSSL_MSG("Verifying Peer's cert");
04762 
04763 #ifdef WOLFSSL_TRUST_PEER_CERT
04764         if (!haveTrustPeer) { /* do not parse again if previously verified */
04765 #endif
04766         InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
04767         ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
04768                                 ssl->ctx->cm);
04769 #ifdef WOLFSSL_TRUST_PEER_CERT
04770         }
04771 #endif
04772 
04773         if (ret == 0) {
04774             WOLFSSL_MSG("Verified Peer's cert");
04775             fatal = 0;
04776         }
04777         else if (ret == ASN_PARSE_E) {
04778             WOLFSSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
04779             fatal = 1;
04780         }
04781         else {
04782             WOLFSSL_MSG("Failed to verify Peer's cert");
04783             if (ssl->verifyCallback) {
04784                 WOLFSSL_MSG("\tCallback override available, will continue");
04785                 fatal = 0;
04786             }
04787             else {
04788                 WOLFSSL_MSG("\tNo callback override available, fatal");
04789                 fatal = 1;
04790             }
04791         }
04792 
04793 #ifdef HAVE_SECURE_RENEGOTIATION
04794         if (fatal == 0 && ssl->secure_renegotiation
04795                        && ssl->secure_renegotiation->enabled) {
04796 
04797             if (IsEncryptionOn(ssl, 0)) {
04798                 /* compare against previous time */
04799                 if (XMEMCMP(dCert->subjectHash,
04800                             ssl->secure_renegotiation->subject_hash,
04801                             SHA_DIGEST_SIZE) != 0) {
04802                     WOLFSSL_MSG("Peer sent different cert during scr, fatal");
04803                     fatal = 1;
04804                     ret   = SCR_DIFFERENT_CERT_E;
04805                 }
04806             }
04807 
04808             /* cache peer's hash */
04809             if (fatal == 0) {
04810                 XMEMCPY(ssl->secure_renegotiation->subject_hash,
04811                         dCert->subjectHash, SHA_DIGEST_SIZE);
04812             }
04813         }
04814 #endif
04815 
04816 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
04817         if (fatal == 0) {
04818             int doLookup = 1;
04819 
04820             if (ssl->options.side == WOLFSSL_CLIENT_END) {
04821 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
04822                 if (ssl->status_request) {
04823                     fatal = TLSX_CSR_InitRequest(ssl->extensions, dCert);
04824                     doLookup = 0;
04825                 }
04826 #endif
04827 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
04828                 if (ssl->status_request_v2) {
04829                     fatal = TLSX_CSR2_InitRequests(ssl->extensions, dCert, 1);
04830                     doLookup = 0;
04831                 }
04832 #endif
04833             }
04834 
04835 #ifdef HAVE_OCSP
04836             if (doLookup && ssl->ctx->cm->ocspEnabled) {
04837                 WOLFSSL_MSG("Doing Leaf OCSP check");
04838                 ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL);
04839                 doLookup = (ret == OCSP_CERT_UNKNOWN);
04840                 if (ret != 0) {
04841                     WOLFSSL_MSG("\tOCSP Lookup not ok");
04842                     fatal = 0;
04843                 }
04844             }
04845 #endif /* HAVE_OCSP */
04846 
04847 #ifdef HAVE_CRL
04848             if (doLookup && ssl->ctx->cm->crlEnabled) {
04849                 WOLFSSL_MSG("Doing Leaf CRL check");
04850                 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
04851                 if (ret != 0) {
04852                     WOLFSSL_MSG("\tCRL check not ok");
04853                     fatal = 0;
04854                 }
04855             }
04856 #endif /* HAVE_CRL */
04857             (void)doLookup;
04858         }
04859 #endif /* HAVE_OCSP || HAVE_CRL */
04860 
04861 #ifdef KEEP_PEER_CERT
04862         {
04863             /* set X509 format for peer cert even if fatal */
04864             int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
04865             if (copyRet == MEMORY_E)
04866                 fatal = 1;
04867         }
04868 #endif
04869 
04870 #ifndef IGNORE_KEY_EXTENSIONS
04871         if (dCert->extKeyUsageSet) {
04872             if ((ssl->specs.kea == rsa_kea) &&
04873                 (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
04874                 ret = KEYUSE_ENCIPHER_E;
04875             }
04876             if ((ssl->specs.sig_algo == rsa_sa_algo ||
04877                     (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
04878                          !ssl->specs.static_ecdh)) &&
04879                 (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
04880                 WOLFSSL_MSG("KeyUse Digital Sig not set");
04881                 ret = KEYUSE_SIGNATURE_E;
04882             }
04883         }
04884 
04885         if (dCert->extExtKeyUsageSet) {
04886             if (ssl->options.side == WOLFSSL_CLIENT_END) {
04887                 if ((dCert->extExtKeyUsage &
04888                         (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
04889                     WOLFSSL_MSG("ExtKeyUse Server Auth not set");
04890                     ret = EXTKEYUSE_AUTH_E;
04891                 }
04892             }
04893             else {
04894                 if ((dCert->extExtKeyUsage &
04895                         (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
04896                     WOLFSSL_MSG("ExtKeyUse Client Auth not set");
04897                     ret = EXTKEYUSE_AUTH_E;
04898                 }
04899             }
04900         }
04901 #endif /* IGNORE_KEY_EXTENSIONS */
04902 
04903         if (fatal) {
04904             FreeDecodedCert(dCert);
04905         #ifdef WOLFSSL_SMALL_STACK
04906             XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04907         #endif
04908             ssl->error = ret;
04909             return ret;
04910         }
04911         ssl->options.havePeerCert = 1;
04912 
04913 #ifdef WOLFSSL_SMALL_STACK
04914         domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04915         if (domain == NULL) {
04916             FreeDecodedCert(dCert);
04917             XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
04918             return MEMORY_E;
04919         }
04920 #endif
04921         /* store for callback use */
04922         if (dCert->subjectCNLen < ASN_NAME_MAX) {
04923             XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen);
04924             domain[dCert->subjectCNLen] = '\0';
04925         }
04926         else
04927             domain[0] = '\0';
04928 
04929         if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
04930             if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
04931                                 (char*)ssl->buffers.domainName.buffer) == 0) {
04932                 WOLFSSL_MSG("DomainName match on common name failed");
04933                 if (CheckAltNames(dCert,
04934                                  (char*)ssl->buffers.domainName.buffer) == 0 ) {
04935                     WOLFSSL_MSG("DomainName match on alt names failed too");
04936                     ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
04937                 }
04938             }
04939         }
04940 
04941         /* decode peer key */
04942         switch (dCert->keyOID) {
04943         #ifndef NO_RSA
04944             case RSAk:
04945                 {
04946                     word32 idx = 0;
04947                     int    keyRet = 0;
04948 
04949                     if (ssl->peerRsaKey == NULL) {
04950                         ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey),
04951                                                    ssl->heap, DYNAMIC_TYPE_RSA);
04952                         if (ssl->peerRsaKey == NULL) {
04953                             WOLFSSL_MSG("PeerRsaKey Memory error");
04954                             keyRet = MEMORY_E;
04955                         } else {
04956                             keyRet = wc_InitRsaKey(ssl->peerRsaKey,
04957                                                    ssl->ctx->heap);
04958                         }
04959                     } else if (ssl->peerRsaKeyPresent) {
04960                         /* don't leak on reuse */
04961                         wc_FreeRsaKey(ssl->peerRsaKey);
04962                         ssl->peerRsaKeyPresent = 0;
04963                         keyRet = wc_InitRsaKey(ssl->peerRsaKey, ssl->heap);
04964                     }
04965 
04966                     if (keyRet != 0 || wc_RsaPublicKeyDecode(dCert->publicKey,
04967                                &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) {
04968                         ret = PEER_KEY_ERROR;
04969                     }
04970                     else {
04971                         ssl->peerRsaKeyPresent = 1;
04972                         #ifdef HAVE_PK_CALLBACKS
04973                             #ifndef NO_RSA
04974                                 ssl->buffers.peerRsaKey.buffer =
04975                                        (byte*)XMALLOC(dCert->pubKeySize,
04976                                                ssl->heap, DYNAMIC_TYPE_RSA);
04977                                 if (ssl->buffers.peerRsaKey.buffer == NULL)
04978                                     ret = MEMORY_ERROR;
04979                                 else {
04980                                     XMEMCPY(ssl->buffers.peerRsaKey.buffer,
04981                                            dCert->publicKey, dCert->pubKeySize);
04982                                     ssl->buffers.peerRsaKey.length =
04983                                             dCert->pubKeySize;
04984                                 }
04985                             #endif /* NO_RSA */
04986                         #endif /*HAVE_PK_CALLBACKS */
04987                     }
04988                 }
04989                 break;
04990         #endif /* NO_RSA */
04991         #ifdef HAVE_NTRU
04992             case NTRUk:
04993                 {
04994                     if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
04995                         ret = PEER_KEY_ERROR;
04996                     }
04997                     else {
04998                         XMEMCPY(ssl->peerNtruKey, dCert->publicKey,
04999                                                              dCert->pubKeySize);
05000                         ssl->peerNtruKeyLen = (word16)dCert->pubKeySize;
05001                         ssl->peerNtruKeyPresent = 1;
05002                     }
05003                 }
05004                 break;
05005         #endif /* HAVE_NTRU */
05006         #ifdef HAVE_ECC
05007             case ECDSAk:
05008                 {
05009                     if (ssl->peerEccDsaKey == NULL) {
05010                         /* alloc/init on demand */
05011                         ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
05012                                               ssl->ctx->heap, DYNAMIC_TYPE_ECC);
05013                         if (ssl->peerEccDsaKey == NULL) {
05014                             WOLFSSL_MSG("PeerEccDsaKey Memory error");
05015                             return MEMORY_E;
05016                         }
05017                         wc_ecc_init(ssl->peerEccDsaKey);
05018                     } else if (ssl->peerEccDsaKeyPresent) {
05019                         /* don't leak on reuse */
05020                         wc_ecc_free(ssl->peerEccDsaKey);
05021                         ssl->peerEccDsaKeyPresent = 0;
05022                         wc_ecc_init(ssl->peerEccDsaKey);
05023                     }
05024                     if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
05025                                         ssl->peerEccDsaKey) != 0) {
05026                         ret = PEER_KEY_ERROR;
05027                     }
05028                     else {
05029                         ssl->peerEccDsaKeyPresent = 1;
05030                         #ifdef HAVE_PK_CALLBACKS
05031                             #ifdef HAVE_ECC
05032                                 ssl->buffers.peerEccDsaKey.buffer =
05033                                        (byte*)XMALLOC(dCert->pubKeySize,
05034                                                ssl->heap, DYNAMIC_TYPE_ECC);
05035                                 if (ssl->buffers.peerEccDsaKey.buffer == NULL)
05036                                     ret = MEMORY_ERROR;
05037                                 else {
05038                                     XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
05039                                            dCert->publicKey, dCert->pubKeySize);
05040                                     ssl->buffers.peerEccDsaKey.length =
05041                                             dCert->pubKeySize;
05042                                 }
05043                             #endif /* HAVE_ECC */
05044                         #endif /*HAVE_PK_CALLBACKS */
05045                     }
05046                 }
05047                 break;
05048         #endif /* HAVE_ECC */
05049             default:
05050                 break;
05051         }
05052 
05053         FreeDecodedCert(dCert);
05054     }
05055 
05056 #ifdef WOLFSSL_SMALL_STACK
05057     XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05058 
05059     store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX),
05060                                                  NULL, DYNAMIC_TYPE_TMP_BUFFER);
05061     if (store == NULL) {
05062         XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05063         return MEMORY_E;
05064     }
05065 #endif
05066 
05067     if (anyError != 0 && ret == 0)
05068         ret = anyError;
05069 
05070     if (ret != 0) {
05071         if (!ssl->options.verifyNone) {
05072             int why = bad_certificate;
05073 
05074             if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
05075                 why = certificate_expired;
05076             if (ssl->verifyCallback) {
05077                 int ok;
05078 
05079                 store->error = ret;
05080                 store->error_depth = totalCerts;
05081                 store->discardSessionCerts = 0;
05082                 store->domain = domain;
05083                 store->userCtx = ssl->verifyCbCtx;
05084 #ifdef KEEP_PEER_CERT
05085                 store->current_cert = &ssl->peerCert;
05086 #else
05087                 store->current_cert = NULL;
05088 #endif
05089 #if defined(HAVE_FORTRESS) || defined(HAVE_STUNNEL)
05090                 store->ex_data = ssl;
05091 #endif
05092                 ok = ssl->verifyCallback(0, store);
05093                 if (ok) {
05094                     WOLFSSL_MSG("Verify callback overriding error!");
05095                     ret = 0;
05096                 }
05097                 #ifdef SESSION_CERTS
05098                 if (store->discardSessionCerts) {
05099                     WOLFSSL_MSG("Verify callback requested discard sess certs");
05100                     ssl->session.chain.count = 0;
05101                 }
05102                 #endif
05103             }
05104             if (ret != 0) {
05105                 SendAlert(ssl, alert_fatal, why);   /* try to send */
05106                 ssl->options.isClosed = 1;
05107             }
05108         }
05109         ssl->error = ret;
05110     }
05111 #ifdef WOLFSSL_ALWAYS_VERIFY_CB
05112     else {
05113         if (ssl->verifyCallback) {
05114             int ok;
05115 
05116             store->error = ret;
05117             store->error_depth = totalCerts;
05118             store->discardSessionCerts = 0;
05119             store->domain = domain;
05120             store->userCtx = ssl->verifyCbCtx;
05121 #ifdef KEEP_PEER_CERT
05122             store->current_cert = &ssl->peerCert;
05123 #endif
05124             store->ex_data = ssl;
05125 
05126             ok = ssl->verifyCallback(1, store);
05127             if (!ok) {
05128                 WOLFSSL_MSG("Verify callback overriding valid certificate!");
05129                 ret = -1;
05130                 SendAlert(ssl, alert_fatal, bad_certificate);
05131                 ssl->options.isClosed = 1;
05132             }
05133             #ifdef SESSION_CERTS
05134             if (store->discardSessionCerts) {
05135                 WOLFSSL_MSG("Verify callback requested discard sess certs");
05136                 ssl->session.chain.count = 0;
05137             }
05138             #endif
05139         }
05140     }
05141 #endif
05142 
05143     if (ssl->options.verifyNone &&
05144                               (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
05145         WOLFSSL_MSG("Ignoring CRL problem based on verify setting");
05146         ret = ssl->error = 0;
05147     }
05148 
05149     if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END)
05150         ssl->options.serverState = SERVER_CERT_COMPLETE;
05151 
05152     if (IsEncryptionOn(ssl, 0)) {
05153         *inOutIdx += ssl->keys.padSz;
05154     }
05155 
05156 #ifdef WOLFSSL_SMALL_STACK
05157     XFREE(store,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
05158     XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05159 #endif
05160 
05161     return ret;
05162 }
05163 
05164 
05165 static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
05166                                                                     word32 size)
05167 {
05168     int    ret = 0;
05169     byte   status_type;
05170     word32 status_length;
05171 
05172     if (size < ENUM_LEN + OPAQUE24_LEN)
05173         return BUFFER_ERROR;
05174 
05175     status_type = input[(*inOutIdx)++];
05176 
05177     c24to32(input + *inOutIdx, &status_length);
05178     *inOutIdx += OPAQUE24_LEN;
05179 
05180     if (size != ENUM_LEN + OPAQUE24_LEN + status_length)
05181         return BUFFER_ERROR;
05182 
05183     switch (status_type) {
05184 
05185     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
05186      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05187 
05188         /* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
05189         case WOLFSSL_CSR2_OCSP: {
05190             OcspRequest* request;
05191 
05192             #ifdef WOLFSSL_SMALL_STACK
05193                 CertStatus* status;
05194                 OcspResponse* response;
05195             #else
05196                 CertStatus status[1];
05197                 OcspResponse response[1];
05198             #endif
05199 
05200             do {
05201                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
05202                     if (ssl->status_request) {
05203                         request = TLSX_CSR_GetRequest(ssl->extensions);
05204                         ssl->status_request = 0;
05205                         break;
05206                     }
05207                 #endif
05208 
05209                 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
05210                     if (ssl->status_request_v2) {
05211                         request = TLSX_CSR2_GetRequest(ssl->extensions,
05212                                                                 status_type, 0);
05213                         ssl->status_request_v2 = 0;
05214                         break;
05215                     }
05216                 #endif
05217 
05218                 return BUFFER_ERROR;
05219             } while(0);
05220 
05221             if (request == NULL)
05222                 return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */
05223 
05224             #ifdef WOLFSSL_SMALL_STACK
05225                 status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
05226                                                        DYNAMIC_TYPE_TMP_BUFFER);
05227                 response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
05228                                                        DYNAMIC_TYPE_TMP_BUFFER);
05229 
05230                 if (status == NULL || response == NULL) {
05231                     if (status)
05232                         XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05233                     if (response)
05234                         XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05235 
05236                     return MEMORY_ERROR;
05237                 }
05238             #endif
05239 
05240             InitOcspResponse(response, status, input +*inOutIdx, status_length);
05241 
05242             if ((OcspResponseDecode(response, ssl->ctx->cm) != 0)
05243             ||  (response->responseStatus != OCSP_SUCCESSFUL)
05244             ||  (response->status->status != CERT_GOOD)
05245             ||  (CompareOcspReqResp(request, response) != 0))
05246                 ret = BAD_CERTIFICATE_STATUS_ERROR;
05247 
05248             *inOutIdx += status_length;
05249 
05250             #ifdef WOLFSSL_SMALL_STACK
05251                 XFREE(status,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
05252                 XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05253             #endif
05254 
05255         }
05256         break;
05257 
05258     #endif
05259 
05260     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05261 
05262         case WOLFSSL_CSR2_OCSP_MULTI: {
05263             OcspRequest* request;
05264             word32 list_length = status_length;
05265             byte   index = 0;
05266 
05267             #ifdef WOLFSSL_SMALL_STACK
05268                 CertStatus* status;
05269                 OcspResponse* response;
05270             #else
05271                 CertStatus status[1];
05272                 OcspResponse response[1];
05273             #endif
05274 
05275             do {
05276                 if (ssl->status_request_v2) {
05277                     ssl->status_request_v2 = 0;
05278                     break;
05279                 }
05280 
05281                 return BUFFER_ERROR;
05282             } while(0);
05283 
05284             #ifdef WOLFSSL_SMALL_STACK
05285                 status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
05286                                                        DYNAMIC_TYPE_TMP_BUFFER);
05287                 response = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
05288                                                        DYNAMIC_TYPE_TMP_BUFFER);
05289 
05290                 if (status == NULL || response == NULL) {
05291                     if (status)
05292                         XFREE(status, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05293                     if (response)
05294                         XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05295 
05296                     return MEMORY_ERROR;
05297                 }
05298             #endif
05299 
05300             while (list_length && ret == 0) {
05301                 if (OPAQUE24_LEN > list_length) {
05302                     ret = BUFFER_ERROR;
05303                     break;
05304                 }
05305 
05306                 c24to32(input + *inOutIdx, &status_length);
05307                 *inOutIdx   += OPAQUE24_LEN;
05308                 list_length -= OPAQUE24_LEN;
05309 
05310                 if (status_length > list_length) {
05311                     ret = BUFFER_ERROR;
05312                     break;
05313                 }
05314 
05315                 if (status_length) {
05316                     InitOcspResponse(response, status, input +*inOutIdx,
05317                                                                  status_length);
05318 
05319                     if ((OcspResponseDecode(response, ssl->ctx->cm) != 0)
05320                     ||  (response->responseStatus != OCSP_SUCCESSFUL)
05321                     ||  (response->status->status != CERT_GOOD))
05322                         ret = BAD_CERTIFICATE_STATUS_ERROR;
05323 
05324                     while (ret == 0) {
05325                         request = TLSX_CSR2_GetRequest(ssl->extensions,
05326                                                           status_type, index++);
05327 
05328                         if (request == NULL)
05329                             ret = BAD_CERTIFICATE_STATUS_ERROR;
05330                         else if (CompareOcspReqResp(request, response) == 0)
05331                             break;
05332                         else if (index == 1) /* server cert must be OK */
05333                             ret = BAD_CERTIFICATE_STATUS_ERROR;
05334                     }
05335 
05336                     *inOutIdx   += status_length;
05337                     list_length -= status_length;
05338                 }
05339             }
05340 
05341             #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
05342                 ssl->status_request_v2 = 0;
05343             #endif
05344 
05345             #ifdef WOLFSSL_SMALL_STACK
05346                 XFREE(status,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
05347                 XFREE(response, NULL, DYNAMIC_TYPE_TMP_BUFFER);
05348             #endif
05349 
05350         }
05351         break;
05352 
05353     #endif
05354 
05355         default:
05356             ret = BUFFER_ERROR;
05357     }
05358 
05359     if (ret != 0)
05360         SendAlert(ssl, alert_fatal, bad_certificate_status_response);
05361 
05362     return ret;
05363 }
05364 
05365 #endif /* !NO_CERTS */
05366 
05367 
05368 static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
05369                                                     word32 size, word32 totalSz)
05370 {
05371     (void)input;
05372 
05373     if (size) /* must be 0 */
05374         return BUFFER_ERROR;
05375 
05376     if (IsEncryptionOn(ssl, 0)) {
05377         /* access beyond input + size should be checked against totalSz */
05378         if (*inOutIdx + ssl->keys.padSz > totalSz)
05379             return BUFFER_E;
05380 
05381         *inOutIdx += ssl->keys.padSz;
05382     }
05383 
05384     if (ssl->options.side == WOLFSSL_SERVER_END) {
05385         SendAlert(ssl, alert_fatal, unexpected_message); /* try */
05386         return FATAL_ERROR;
05387     }
05388 #ifdef HAVE_SECURE_RENEGOTIATION
05389     else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
05390         ssl->secure_renegotiation->startScr = 1;
05391         return 0;
05392     }
05393 #endif
05394     else {
05395         return SendAlert(ssl, alert_warning, no_renegotiation);
05396     }
05397 }
05398 
05399 
05400 int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
05401                                                       word32 totalSz, int sniff)
05402 {
05403     word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
05404 
05405     if (finishedSz != size)
05406         return BUFFER_ERROR;
05407 
05408     /* check against totalSz */
05409     if (*inOutIdx + size + ssl->keys.padSz > totalSz)
05410         return BUFFER_E;
05411 
05412     #ifdef WOLFSSL_CALLBACKS
05413         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
05414         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
05415     #endif
05416 
05417     if (sniff == NO_SNIFF) {
05418         if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
05419             WOLFSSL_MSG("Verify finished error on hashes");
05420             return VERIFY_FINISHED_ERROR;
05421         }
05422     }
05423 
05424 #ifdef HAVE_SECURE_RENEGOTIATION
05425     if (ssl->secure_renegotiation) {
05426         /* save peer's state */
05427         if (ssl->options.side == WOLFSSL_CLIENT_END)
05428             XMEMCPY(ssl->secure_renegotiation->server_verify_data,
05429                     input + *inOutIdx, TLS_FINISHED_SZ);
05430         else
05431             XMEMCPY(ssl->secure_renegotiation->client_verify_data,
05432                     input + *inOutIdx, TLS_FINISHED_SZ);
05433     }
05434 #endif
05435 
05436     /* force input exhaustion at ProcessReply consuming padSz */
05437     *inOutIdx += size + ssl->keys.padSz;
05438 
05439     if (ssl->options.side == WOLFSSL_CLIENT_END) {
05440         ssl->options.serverState = SERVER_FINISHED_COMPLETE;
05441         if (!ssl->options.resuming) {
05442             ssl->options.handShakeState = HANDSHAKE_DONE;
05443             ssl->options.handShakeDone  = 1;
05444         }
05445     }
05446     else {
05447         ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
05448         if (ssl->options.resuming) {
05449             ssl->options.handShakeState = HANDSHAKE_DONE;
05450             ssl->options.handShakeDone  = 1;
05451         }
05452     }
05453 
05454     return 0;
05455 }
05456 
05457 
05458 /* Make sure no duplicates, no fast forward, or other problems; 0 on success */
05459 static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
05460 {
05461     /* verify not a duplicate, mark received, check state */
05462     switch (type) {
05463 
05464 #ifndef NO_WOLFSSL_CLIENT
05465         case hello_request:
05466             if (ssl->msgsReceived.got_hello_request) {
05467                 WOLFSSL_MSG("Duplicate HelloRequest received");
05468                 return DUPLICATE_MSG_E;
05469             }
05470             ssl->msgsReceived.got_hello_request = 1;
05471 
05472             break;
05473 #endif
05474 
05475 #ifndef NO_WOLFSSL_SERVER
05476         case client_hello:
05477             if (ssl->msgsReceived.got_client_hello) {
05478                 WOLFSSL_MSG("Duplicate ClientHello received");
05479                 return DUPLICATE_MSG_E;
05480             }
05481             ssl->msgsReceived.got_client_hello = 1;
05482 
05483             break;
05484 #endif
05485 
05486 #ifndef NO_WOLFSSL_CLIENT
05487         case server_hello:
05488             if (ssl->msgsReceived.got_server_hello) {
05489                 WOLFSSL_MSG("Duplicate ServerHello received");
05490                 return DUPLICATE_MSG_E;
05491             }
05492             ssl->msgsReceived.got_server_hello = 1;
05493 
05494             break;
05495 #endif
05496 
05497 #ifndef NO_WOLFSSL_CLIENT
05498         case hello_verify_request:
05499             if (ssl->msgsReceived.got_hello_verify_request) {
05500                 WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
05501                 return DUPLICATE_MSG_E;
05502             }
05503             ssl->msgsReceived.got_hello_verify_request = 1;
05504 
05505             break;
05506 #endif
05507 
05508 #ifndef NO_WOLFSSL_CLIENT
05509         case session_ticket:
05510             if (ssl->msgsReceived.got_session_ticket) {
05511                 WOLFSSL_MSG("Duplicate SessionTicket received");
05512                 return DUPLICATE_MSG_E;
05513             }
05514             ssl->msgsReceived.got_session_ticket = 1;
05515 
05516             break;
05517 #endif
05518 
05519         case certificate:
05520             if (ssl->msgsReceived.got_certificate) {
05521                 WOLFSSL_MSG("Duplicate Certificate received");
05522                 return DUPLICATE_MSG_E;
05523             }
05524             ssl->msgsReceived.got_certificate = 1;
05525 
05526 #ifndef NO_WOLFSSL_CLIENT
05527             if (ssl->options.side == WOLFSSL_CLIENT_END) {
05528                 if ( ssl->msgsReceived.got_server_hello == 0) {
05529                     WOLFSSL_MSG("No ServerHello before Cert");
05530                     return OUT_OF_ORDER_E;
05531                 }
05532             }
05533 #endif
05534 #ifndef NO_WOLFSSL_SERVER
05535             if (ssl->options.side == WOLFSSL_SERVER_END) {
05536                 if ( ssl->msgsReceived.got_client_hello == 0) {
05537                     WOLFSSL_MSG("No ClientHello before Cert");
05538                     return OUT_OF_ORDER_E;
05539                 }
05540             }
05541 #endif
05542             break;
05543 
05544 #ifndef NO_WOLFSSL_CLIENT
05545         case certificate_status:
05546             if (ssl->msgsReceived.got_certificate_status) {
05547                 WOLFSSL_MSG("Duplicate CertificateSatatus received");
05548                 return DUPLICATE_MSG_E;
05549             }
05550             ssl->msgsReceived.got_certificate_status = 1;
05551 
05552             if (ssl->msgsReceived.got_certificate == 0) {
05553                 WOLFSSL_MSG("No Certificate before CertificateStatus");
05554                 return OUT_OF_ORDER_E;
05555             }
05556             if (ssl->msgsReceived.got_server_key_exchange != 0) {
05557                 WOLFSSL_MSG("CertificateStatus after ServerKeyExchange");
05558                 return OUT_OF_ORDER_E;
05559             }
05560 
05561             break;
05562 #endif
05563 
05564 #ifndef NO_WOLFSSL_CLIENT
05565         case server_key_exchange:
05566             if (ssl->msgsReceived.got_server_key_exchange) {
05567                 WOLFSSL_MSG("Duplicate ServerKeyExchange received");
05568                 return DUPLICATE_MSG_E;
05569             }
05570             ssl->msgsReceived.got_server_key_exchange = 1;
05571 
05572             if (ssl->msgsReceived.got_server_hello == 0) {
05573                 WOLFSSL_MSG("No ServerHello before ServerKeyExchange");
05574                 return OUT_OF_ORDER_E;
05575             }
05576             if (ssl->msgsReceived.got_certificate_status == 0) {
05577 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
05578                 if (ssl->status_request) {
05579                     int ret;
05580 
05581                     WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
05582                     if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0)
05583                         return ret;
05584                 }
05585 #endif
05586 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
05587                 if (ssl->status_request_v2) {
05588                     int ret;
05589 
05590                     WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
05591                     if ((ret = TLSX_CSR2_ForceRequest(ssl)) != 0)
05592                         return ret;
05593                 }
05594 #endif
05595             }
05596 
05597             break;
05598 #endif
05599 
05600 #ifndef NO_WOLFSSL_CLIENT
05601         case certificate_request:
05602             if (ssl->msgsReceived.got_certificate_request) {
05603                 WOLFSSL_MSG("Duplicate CertificateRequest received");
05604                 return DUPLICATE_MSG_E;
05605             }
05606             ssl->msgsReceived.got_certificate_request = 1;
05607 
05608             break;
05609 #endif
05610 
05611 #ifndef NO_WOLFSSL_CLIENT
05612         case server_hello_done:
05613             if (ssl->msgsReceived.got_server_hello_done) {
05614                 WOLFSSL_MSG("Duplicate ServerHelloDone received");
05615                 return DUPLICATE_MSG_E;
05616             }
05617             ssl->msgsReceived.got_server_hello_done = 1;
05618 
05619             if (ssl->msgsReceived.got_certificate == 0) {
05620                 if (ssl->specs.kea == psk_kea ||
05621                     ssl->specs.kea == dhe_psk_kea ||
05622                     ssl->specs.kea == ecdhe_psk_kea ||
05623                     ssl->options.usingAnon_cipher) {
05624                     WOLFSSL_MSG("No Cert required");
05625                 } else {
05626                     WOLFSSL_MSG("No Certificate before ServerHelloDone");
05627                     return OUT_OF_ORDER_E;
05628                 }
05629             }
05630             if (ssl->msgsReceived.got_server_key_exchange == 0) {
05631                 int pskNoServerHint = 0;  /* not required in this case */
05632 
05633                 #ifndef NO_PSK
05634                     if (ssl->specs.kea == psk_kea &&
05635                                                ssl->arrays->server_hint[0] == 0)
05636                         pskNoServerHint = 1;
05637                 #endif
05638                 if (ssl->specs.static_ecdh == 1 ||
05639                     ssl->specs.kea == rsa_kea ||
05640                     ssl->specs.kea == ntru_kea ||
05641                     pskNoServerHint) {
05642                     WOLFSSL_MSG("No KeyExchange required");
05643                 } else {
05644                     WOLFSSL_MSG("No ServerKeyExchange before ServerDone");
05645                     return OUT_OF_ORDER_E;
05646                 }
05647             }
05648             break;
05649 #endif
05650 
05651 #ifndef NO_WOLFSSL_SERVER
05652         case certificate_verify:
05653             if (ssl->msgsReceived.got_certificate_verify) {
05654                 WOLFSSL_MSG("Duplicate CertificateVerify received");
05655                 return DUPLICATE_MSG_E;
05656             }
05657             ssl->msgsReceived.got_certificate_verify = 1;
05658 
05659             if ( ssl->msgsReceived.got_certificate == 0) {
05660                 WOLFSSL_MSG("No Cert before CertVerify");
05661                 return OUT_OF_ORDER_E;
05662             }
05663             break;
05664 #endif
05665 
05666 #ifndef NO_WOLFSSL_SERVER
05667         case client_key_exchange:
05668             if (ssl->msgsReceived.got_client_key_exchange) {
05669                 WOLFSSL_MSG("Duplicate ClientKeyExchange received");
05670                 return DUPLICATE_MSG_E;
05671             }
05672             ssl->msgsReceived.got_client_key_exchange = 1;
05673 
05674             if (ssl->msgsReceived.got_client_hello == 0) {
05675                 WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
05676                 return OUT_OF_ORDER_E;
05677             }
05678             break;
05679 #endif
05680 
05681         case finished:
05682             if (ssl->msgsReceived.got_finished) {
05683                 WOLFSSL_MSG("Duplicate Finished received");
05684                 return DUPLICATE_MSG_E;
05685             }
05686             ssl->msgsReceived.got_finished = 1;
05687 
05688             if (ssl->msgsReceived.got_change_cipher == 0) {
05689                 WOLFSSL_MSG("Finished received before ChangeCipher");
05690                 return NO_CHANGE_CIPHER_E;
05691             }
05692 
05693             break;
05694 
05695         case change_cipher_hs:
05696             if (ssl->msgsReceived.got_change_cipher) {
05697                 WOLFSSL_MSG("Duplicate ChangeCipher received");
05698                 return DUPLICATE_MSG_E;
05699             }
05700             ssl->msgsReceived.got_change_cipher = 1;
05701 
05702 #ifndef NO_WOLFSSL_CLIENT
05703             if (ssl->options.side == WOLFSSL_CLIENT_END) {
05704                 if (!ssl->options.resuming &&
05705                                  ssl->msgsReceived.got_server_hello_done == 0) {
05706                     WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
05707                     return OUT_OF_ORDER_E;
05708                 }
05709             }
05710 #endif
05711 #ifndef NO_WOLFSSL_SERVER
05712             if (ssl->options.side == WOLFSSL_SERVER_END) {
05713                 if (!ssl->options.resuming &&
05714                                ssl->msgsReceived.got_client_key_exchange == 0) {
05715                     WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
05716                     return OUT_OF_ORDER_E;
05717                 }
05718             }
05719 #endif
05720 
05721             break;
05722 
05723         default:
05724             WOLFSSL_MSG("Unknown message type");
05725             return SANITY_MSG_E;
05726     }
05727 
05728     return 0;
05729 }
05730 
05731 
05732 static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
05733                           byte type, word32 size, word32 totalSz)
05734 {
05735     int ret = 0;
05736     (void)totalSz;
05737 
05738     WOLFSSL_ENTER("DoHandShakeMsgType");
05739 
05740     /* make sure can read the message */
05741     if (*inOutIdx + size > totalSz)
05742         return INCOMPLETE_DATA;
05743 
05744     /* sanity check msg received */
05745     if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
05746         WOLFSSL_MSG("Sanity Check on handshake message type received failed");
05747         return ret;
05748     }
05749 
05750 #ifdef WOLFSSL_CALLBACKS
05751     /* add name later, add on record and handshake header part back on */
05752     if (ssl->toInfoOn) {
05753         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
05754         AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
05755                       size + add, ssl->heap);
05756         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
05757     }
05758 #endif
05759 
05760     if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
05761         WOLFSSL_MSG("HandShake message after handshake complete");
05762         SendAlert(ssl, alert_fatal, unexpected_message);
05763         return OUT_OF_ORDER_E;
05764     }
05765 
05766     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
05767                ssl->options.serverState == NULL_STATE && type != server_hello) {
05768         WOLFSSL_MSG("First server message not server hello");
05769         SendAlert(ssl, alert_fatal, unexpected_message);
05770         return OUT_OF_ORDER_E;
05771     }
05772 
05773     if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
05774             type == server_hello_done &&
05775             ssl->options.serverState < SERVER_HELLO_COMPLETE) {
05776         WOLFSSL_MSG("Server hello done received before server hello in DTLS");
05777         SendAlert(ssl, alert_fatal, unexpected_message);
05778         return OUT_OF_ORDER_E;
05779     }
05780 
05781     if (ssl->options.side == WOLFSSL_SERVER_END &&
05782                ssl->options.clientState == NULL_STATE && type != client_hello) {
05783         WOLFSSL_MSG("First client message not client hello");
05784         SendAlert(ssl, alert_fatal, unexpected_message);
05785         return OUT_OF_ORDER_E;
05786     }
05787 
05788     /* above checks handshake state */
05789     /* hello_request not hashed */
05790     /* Also, skip hashing the client_hello message here for DTLS. It will be
05791      * hashed later if the DTLS cookie is correct. */
05792     if (type != hello_request && !(ssl->options.dtls && type == client_hello)) {
05793         ret = HashInput(ssl, input + *inOutIdx, size);
05794         if (ret != 0) return ret;
05795     }
05796 
05797     switch (type) {
05798 
05799     case hello_request:
05800         WOLFSSL_MSG("processing hello request");
05801         ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
05802         break;
05803 
05804 #ifndef NO_WOLFSSL_CLIENT
05805     case hello_verify_request:
05806         WOLFSSL_MSG("processing hello verify request");
05807         ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
05808         break;
05809 
05810     case server_hello:
05811         WOLFSSL_MSG("processing server hello");
05812         ret = DoServerHello(ssl, input, inOutIdx, size);
05813         break;
05814 
05815 #ifndef NO_CERTS
05816     case certificate_request:
05817         WOLFSSL_MSG("processing certificate request");
05818         ret = DoCertificateRequest(ssl, input, inOutIdx, size);
05819         break;
05820 #endif
05821 
05822     case server_key_exchange:
05823         WOLFSSL_MSG("processing server key exchange");
05824         ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
05825         break;
05826 
05827 #ifdef HAVE_SESSION_TICKET
05828     case session_ticket:
05829         WOLFSSL_MSG("processing session ticket");
05830         ret = DoSessionTicket(ssl, input, inOutIdx, size);
05831         break;
05832 #endif /* HAVE_SESSION_TICKET */
05833 #endif
05834 
05835 #ifndef NO_CERTS
05836     case certificate:
05837         WOLFSSL_MSG("processing certificate");
05838         ret = DoCertificate(ssl, input, inOutIdx, size);
05839         break;
05840 
05841     case certificate_status:
05842         WOLFSSL_MSG("processing certificate status");
05843         ret = DoCertificateStatus(ssl, input, inOutIdx, size);
05844         break;
05845 #endif
05846 
05847     case server_hello_done:
05848         WOLFSSL_MSG("processing server hello done");
05849         #ifdef WOLFSSL_CALLBACKS
05850             if (ssl->hsInfoOn)
05851                 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
05852             if (ssl->toInfoOn)
05853                 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
05854         #endif
05855         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
05856         if (IsEncryptionOn(ssl, 0)) {
05857             *inOutIdx += ssl->keys.padSz;
05858         }
05859         if (ssl->options.resuming) {
05860             WOLFSSL_MSG("Not resuming as thought");
05861             ssl->options.resuming = 0;
05862         }
05863         break;
05864 
05865     case finished:
05866         WOLFSSL_MSG("processing finished");
05867         ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
05868         break;
05869 
05870 #ifndef NO_WOLFSSL_SERVER
05871     case client_hello:
05872         WOLFSSL_MSG("processing client hello");
05873         ret = DoClientHello(ssl, input, inOutIdx, size);
05874         break;
05875 
05876     case client_key_exchange:
05877         WOLFSSL_MSG("processing client key exchange");
05878         ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
05879         break;
05880 
05881 #if !defined(NO_RSA) || defined(HAVE_ECC)
05882     case certificate_verify:
05883         WOLFSSL_MSG("processing certificate verify");
05884         ret = DoCertificateVerify(ssl, input, inOutIdx, size);
05885         break;
05886 #endif /* !NO_RSA || HAVE_ECC */
05887 
05888 #endif /* !NO_WOLFSSL_SERVER */
05889 
05890     default:
05891         WOLFSSL_MSG("Unknown handshake message type");
05892         ret = UNKNOWN_HANDSHAKE_TYPE;
05893         break;
05894     }
05895 
05896     WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
05897     return ret;
05898 }
05899 
05900 
05901 static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
05902                           word32 totalSz)
05903 {
05904     int    ret = 0;
05905     word32 inputLength;
05906 
05907     WOLFSSL_ENTER("DoHandShakeMsg()");
05908 
05909     if (ssl->arrays == NULL) {
05910         byte   type;
05911         word32 size;
05912 
05913         if (GetHandShakeHeader(ssl,input,inOutIdx,&type, &size, totalSz) != 0)
05914             return PARSE_ERROR;
05915 
05916         return DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
05917     }
05918 
05919     inputLength = ssl->buffers.inputBuffer.length - *inOutIdx;
05920 
05921     /* If there is a pending fragmented handshake message,
05922      * pending message size will be non-zero. */
05923     if (ssl->arrays->pendingMsgSz == 0) {
05924         byte   type;
05925         word32 size;
05926 
05927         if (GetHandShakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
05928             return PARSE_ERROR;
05929 
05930         /* Cap the maximum size of a handshake message to something reasonable.
05931          * By default is the maximum size of a certificate message assuming
05932          * nine 2048-bit RSA certificates in the chain. */
05933         if (size > MAX_HANDSHAKE_SZ) {
05934             WOLFSSL_MSG("Handshake message too large");
05935             return HANDSHAKE_SIZE_ERROR;
05936         }
05937 
05938         /* size is the size of the certificate message payload */
05939         if (inputLength - HANDSHAKE_HEADER_SZ < size) {
05940             ssl->arrays->pendingMsgType = type;
05941             ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
05942             ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
05943                                                      ssl->heap,
05944                                                      DYNAMIC_TYPE_ARRAYS);
05945             if (ssl->arrays->pendingMsg == NULL)
05946                 return MEMORY_E;
05947             XMEMCPY(ssl->arrays->pendingMsg,
05948                     input + *inOutIdx - HANDSHAKE_HEADER_SZ,
05949                     inputLength);
05950             ssl->arrays->pendingMsgOffset = inputLength;
05951             *inOutIdx += inputLength - HANDSHAKE_HEADER_SZ;
05952             return 0;
05953         }
05954 
05955         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
05956     }
05957     else {
05958         if (inputLength + ssl->arrays->pendingMsgOffset
05959                                                   > ssl->arrays->pendingMsgSz) {
05960 
05961             return BUFFER_ERROR;
05962         }
05963         else {
05964             XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
05965                     input + *inOutIdx, inputLength);
05966             ssl->arrays->pendingMsgOffset += inputLength;
05967             *inOutIdx += inputLength;
05968         }
05969 
05970         if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
05971         {
05972             word32 idx = 0;
05973             ret = DoHandShakeMsgType(ssl,
05974                                      ssl->arrays->pendingMsg
05975                                                           + HANDSHAKE_HEADER_SZ,
05976                                      &idx, ssl->arrays->pendingMsgType,
05977                                      ssl->arrays->pendingMsgSz
05978                                                           - HANDSHAKE_HEADER_SZ,
05979                                      ssl->arrays->pendingMsgSz);
05980             XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
05981             ssl->arrays->pendingMsg = NULL;
05982             ssl->arrays->pendingMsgSz = 0;
05983         }
05984     }
05985 
05986     WOLFSSL_LEAVE("DoHandShakeMsg()", ret);
05987     return ret;
05988 }
05989 
05990 
05991 #ifdef WOLFSSL_DTLS
05992 
05993 static INLINE int DtlsCheckWindow(DtlsState* state)
05994 {
05995     word32 cur;
05996     word32 next;
05997     DtlsSeq window;
05998 
05999     if (state->curEpoch == state->nextEpoch) {
06000         next = state->nextSeq;
06001         window = state->window;
06002     }
06003     else if (state->curEpoch < state->nextEpoch) {
06004         next = state->prevSeq;
06005         window = state->prevWindow;
06006     }
06007     else {
06008         return 0;
06009     }
06010 
06011     cur = state->curSeq;
06012 
06013     if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
06014         return 0;
06015     }
06016     else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) {
06017         return 0;
06018     }
06019 
06020     return 1;
06021 }
06022 
06023 
06024 static INLINE int DtlsUpdateWindow(DtlsState* state)
06025 {
06026     word32 cur;
06027     word32* next;
06028     DtlsSeq* window;
06029 
06030     if (state->curEpoch == state->nextEpoch) {
06031         next = &state->nextSeq;
06032         window = &state->window;
06033     }
06034     else {
06035         next = &state->prevSeq;
06036         window = &state->prevWindow;
06037     }
06038 
06039     cur = state->curSeq;
06040 
06041     if (cur < *next) {
06042         *window |= ((DtlsSeq)1 << (*next - cur - 1));
06043     }
06044     else {
06045         *window <<= (1 + cur - *next);
06046         *window |= 1;
06047         *next = cur + 1;
06048     }
06049 
06050     return 1;
06051 }
06052 
06053 
06054 static int DtlsMsgDrain(WOLFSSL* ssl)
06055 {
06056     DtlsMsg* item = ssl->dtls_msg_list;
06057     int ret = 0;
06058 
06059     /* While there is an item in the store list, and it is the expected
06060      * message, and it is complete, and there hasn't been an error in the
06061      * last messge... */
06062     while (item != NULL &&
06063             ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
06064             item->fragSz == item->sz &&
06065             ret == 0) {
06066         word32 idx = 0;
06067         ssl->keys.dtls_expected_peer_handshake_number++;
06068         ret = DoHandShakeMsgType(ssl, item->msg,
06069                                  &idx, item->type, item->sz, item->sz);
06070         ssl->dtls_msg_list = item->next;
06071         DtlsMsgDelete(item, ssl->heap);
06072         item = ssl->dtls_msg_list;
06073     }
06074 
06075     return ret;
06076 }
06077 
06078 
06079 static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
06080                           word32 totalSz)
06081 {
06082     byte type;
06083     word32 size;
06084     word32 fragOffset, fragSz;
06085     int ret = 0;
06086 
06087     WOLFSSL_ENTER("DoDtlsHandShakeMsg()");
06088     if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
06089                                &size, &fragOffset, &fragSz, totalSz) != 0)
06090         return PARSE_ERROR;
06091 
06092     if (*inOutIdx + fragSz > totalSz)
06093         return INCOMPLETE_DATA;
06094 
06095     /* Check the handshake sequence number first. If out of order,
06096      * add the current message to the list. If the message is in order,
06097      * but it is a fragment, add the current message to the list, then
06098      * check the head of the list to see if it is complete, if so, pop
06099      * it out as the current message. If the message is complete and in
06100      * order, process it. Check the head of the list to see if it is in
06101      * order, if so, process it. (Repeat until list exhausted.) If the
06102      * head is out of order, return for more processing.
06103      */
06104     if (ssl->keys.dtls_peer_handshake_number >
06105                                 ssl->keys.dtls_expected_peer_handshake_number) {
06106         /* Current message is out of order. It will get stored in the list.
06107          * Storing also takes care of defragmentation. If the messages is a
06108          * client hello, we need to process this out of order; the server
06109          * is not supposed to keep state, but the second client hello will
06110          * have a different handshake sequence number than is expected, and
06111          * the server shouldn't be expecting any particular handshake sequence
06112          * number. (If the cookie changes multiple times in quick succession,
06113          * the client could be sending multiple new client hello messages
06114          * with newer and newer cookies.) */
06115         if (type != client_hello) {
06116             ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
06117                             ssl->keys.dtls_peer_handshake_number,
06118                             input + *inOutIdx, size, type,
06119                             fragOffset, fragSz, ssl->heap);
06120             *inOutIdx += fragSz;
06121             ret = 0;
06122         }
06123         else {
06124             ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
06125             if (ret == 0) {
06126                 ssl->keys.dtls_expected_peer_handshake_number =
06127                     ssl->keys.dtls_peer_handshake_number + 1;
06128             }
06129         }
06130     }
06131     else if (ssl->keys.dtls_peer_handshake_number <
06132                                 ssl->keys.dtls_expected_peer_handshake_number) {
06133         /* Already saw this message and processed it. It can be ignored. */
06134         *inOutIdx += fragSz;
06135         if(type == finished )
06136             *inOutIdx += ssl->keys.padSz;
06137         ret = DtlsPoolSend(ssl);
06138     }
06139     else if (fragSz < size) {
06140         /* Since this branch is in order, but fragmented, dtls_msg_list will be
06141          * pointing to the message with this fragment in it. Check it to see
06142          * if it is completed. */
06143         ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
06144                         ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
06145                         size, type, fragOffset, fragSz, ssl->heap);
06146         *inOutIdx += fragSz;
06147         ret = 0;
06148         if (ssl->dtls_msg_list != NULL &&
06149             ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
06150             ret = DtlsMsgDrain(ssl);
06151     }
06152     else {
06153         /* This branch is in order next, and a complete message. */
06154         ssl->keys.dtls_expected_peer_handshake_number++;
06155         ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
06156         if (ret == 0 && ssl->dtls_msg_list != NULL)
06157             ret = DtlsMsgDrain(ssl);
06158     }
06159 
06160     WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret);
06161     return ret;
06162 }
06163 #endif
06164 
06165 
06166 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
06167     || defined(HAVE_AESGCM)
06168 static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
06169 {
06170 #ifdef WOLFSSL_DTLS
06171     if (ssl->options.dtls) {
06172         if (verify)
06173             return ssl->keys.dtls_state.curSeq; /* explicit from peer */
06174         else
06175             return ssl->keys.dtls_sequence_number - 1; /* already incremented */
06176     }
06177 #endif
06178     if (verify)
06179         return ssl->keys.peer_sequence_number++;
06180     else
06181         return ssl->keys.sequence_number++;
06182 }
06183 #endif
06184 
06185 
06186 #ifdef HAVE_AEAD
06187 static INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
06188 {
06189     int i;
06190     for (i = AEAD_MAX_EXP_SZ-1; i >= 0; i--) {
06191         if (++ssl->keys.aead_exp_IV[i]) return;
06192     }
06193 }
06194 
06195 
06196 #if defined(HAVE_POLY1305) && defined(HAVE_CHACHA)
06197 /* Used for the older version of creating AEAD tags with Poly1305 */
06198 static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
06199                        byte* cipher, word16 sz, byte* tag)
06200 {
06201     int ret       = 0;
06202     int msglen    = (sz - ssl->specs.aead_mac_size);
06203     word32 keySz  = 32;
06204     byte padding[8]; /* used to temporarily store lengths */
06205 
06206 #ifdef CHACHA_AEAD_TEST
06207       printf("Using old version of poly1305 input.\n");
06208 #endif
06209 
06210     if (msglen < 0)
06211         return INPUT_CASE_ERROR;
06212 
06213     if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
06214         return ret;
06215 
06216     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
06217                    AEAD_AUTH_DATA_SZ)) != 0)
06218         return ret;
06219 
06220     /* length of additional input plus padding */
06221     XMEMSET(padding, 0, sizeof(padding));
06222     padding[0] = AEAD_AUTH_DATA_SZ;
06223     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding,
06224                     sizeof(padding))) != 0)
06225         return ret;
06226 
06227 
06228     /* add cipher info and then its length */
06229     XMEMSET(padding, 0, sizeof(padding));
06230     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
06231         return ret;
06232 
06233     /* 32 bit size of cipher to 64 bit endian */
06234     padding[0] =  msglen        & 0xff;
06235     padding[1] = (msglen >>  8) & 0xff;
06236     padding[2] = (msglen >> 16) & 0xff;
06237     padding[3] = (msglen >> 24) & 0xff;
06238     if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
06239         != 0)
06240         return ret;
06241 
06242     /* generate tag */
06243     if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
06244         return ret;
06245 
06246     return ret;
06247 }
06248 
06249 
06250 static int  ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
06251                               word16 sz)
06252 {
06253     const byte* additionalSrc = input - RECORD_HEADER_SZ;
06254     int ret       = 0;
06255     word32 msgLen = (sz - ssl->specs.aead_mac_size);
06256     byte tag[POLY1305_AUTH_SZ];
06257     byte add[AEAD_AUTH_DATA_SZ];
06258     byte nonce[CHACHA20_NONCE_SZ];
06259     byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
06260     #ifdef CHACHA_AEAD_TEST
06261         int i;
06262     #endif
06263 
06264     XMEMSET(tag,   0, sizeof(tag));
06265     XMEMSET(nonce, 0, sizeof(nonce));
06266     XMEMSET(poly,  0, sizeof(poly));
06267     XMEMSET(add,   0, sizeof(add));
06268 
06269     if (ssl->options.oldPoly != 0) {
06270         /* get nonce */
06271         c32toa(ssl->keys.sequence_number, nonce + CHACHA20_OLD_OFFSET);
06272     }
06273 
06274     /* opaque SEQ number stored for AD */
06275     c32toa(GetSEQIncrement(ssl, 0), add + AEAD_SEQ_OFFSET);
06276 
06277     /* Store the type, version. Unfortunately, they are in
06278      * the input buffer ahead of the plaintext. */
06279     #ifdef WOLFSSL_DTLS
06280         if (ssl->options.dtls) {
06281             c16toa(ssl->keys.dtls_epoch, add);
06282             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
06283         }
06284     #endif
06285 
06286     /* add TLS message size to additional data */
06287     add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
06288     add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
06289 
06290     XMEMCPY(add + AEAD_TYPE_OFFSET, additionalSrc, 3);
06291 
06292     #ifdef CHACHA_AEAD_TEST
06293         printf("Encrypt Additional : ");
06294         for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
06295             printf("%02x", add[i]);
06296         }
06297         printf("\n\n");
06298         printf("input before encryption :\n");
06299         for (i = 0; i < sz; i++) {
06300             printf("%02x", input[i]);
06301             if ((i + 1) % 16 == 0)
06302                 printf("\n");
06303         }
06304         printf("\n");
06305     #endif
06306 
06307     if (ssl->options.oldPoly == 0) {
06308         /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
06309          * record sequence number XORed with client_write_IV/server_write_IV */
06310         XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, CHACHA20_IMP_IV_SZ);
06311         nonce[4]  ^= add[0];
06312         nonce[5]  ^= add[1];
06313         nonce[6]  ^= add[2];
06314         nonce[7]  ^= add[3];
06315         nonce[8]  ^= add[4];
06316         nonce[9]  ^= add[5];
06317         nonce[10] ^= add[6];
06318         nonce[11] ^= add[7];
06319     }
06320 
06321     /* set the nonce for chacha and get poly1305 key */
06322     if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) {
06323         ForceZero(nonce, CHACHA20_NONCE_SZ);
06324         return ret;
06325     }
06326 
06327     ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
06328     /* create Poly1305 key using chacha20 keystream */
06329     if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, poly,
06330                                                       poly, sizeof(poly))) != 0)
06331         return ret;
06332 
06333     /* encrypt the plain text */
06334     if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out,
06335                                                          input, msgLen)) != 0) {
06336         ForceZero(poly, sizeof(poly));
06337         return ret;
06338     }
06339 
06340     /* get the poly1305 tag using either old padding scheme or more recent */
06341     if (ssl->options.oldPoly != 0) {
06342         if ((ret = Poly1305TagOld(ssl, add, (const byte* )out,
06343                                                          poly, sz, tag)) != 0) {
06344             ForceZero(poly, sizeof(poly));
06345             return ret;
06346         }
06347     }
06348     else {
06349         if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
06350                                                           sizeof(poly))) != 0) {
06351             ForceZero(poly, sizeof(poly));
06352             return ret;
06353         }
06354         if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
06355                             sizeof(add), out, msgLen, tag, sizeof(tag))) != 0) {
06356             ForceZero(poly, sizeof(poly));
06357             return ret;
06358         }
06359     }
06360     ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
06361 
06362     /* append tag to ciphertext */
06363     XMEMCPY(out + msgLen, tag, sizeof(tag));
06364 
06365     AeadIncrementExpIV(ssl);
06366 
06367     #ifdef CHACHA_AEAD_TEST
06368        printf("mac tag :\n");
06369         for (i = 0; i < 16; i++) {
06370            printf("%02x", tag[i]);
06371            if ((i + 1) % 16 == 0)
06372                printf("\n");
06373         }
06374        printf("\n\noutput after encrypt :\n");
06375         for (i = 0; i < sz; i++) {
06376            printf("%02x", out[i]);
06377            if ((i + 1) % 16 == 0)
06378                printf("\n");
06379         }
06380         printf("\n");
06381     #endif
06382 
06383     return ret;
06384 }
06385 
06386 
06387 static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
06388                            word16 sz)
06389 {
06390     byte add[AEAD_AUTH_DATA_SZ];
06391     byte nonce[CHACHA20_NONCE_SZ];
06392     byte tag[POLY1305_AUTH_SZ];
06393     byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
06394     int ret    = 0;
06395     int msgLen = (sz - ssl->specs.aead_mac_size);
06396 
06397     #ifdef CHACHA_AEAD_TEST
06398        int i;
06399        printf("input before decrypt :\n");
06400         for (i = 0; i < sz; i++) {
06401            printf("%02x", input[i]);
06402            if ((i + 1) % 16 == 0)
06403                printf("\n");
06404         }
06405         printf("\n");
06406     #endif
06407 
06408     XMEMSET(tag,   0, sizeof(tag));
06409     XMEMSET(poly,  0, sizeof(poly));
06410     XMEMSET(nonce, 0, sizeof(nonce));
06411     XMEMSET(add,   0, sizeof(add));
06412 
06413     if (ssl->options.oldPoly != 0) {
06414         /* get nonce */
06415         c32toa(ssl->keys.peer_sequence_number, nonce + CHACHA20_OLD_OFFSET);
06416     }
06417 
06418     /* sequence number field is 64-bits, we only use 32-bits */
06419     c32toa(GetSEQIncrement(ssl, 1), add + AEAD_SEQ_OFFSET);
06420 
06421     /* get AD info */
06422     add[AEAD_TYPE_OFFSET] = ssl->curRL.type;
06423     add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
06424     add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
06425 
06426     /* Store the type, version. */
06427     #ifdef WOLFSSL_DTLS
06428         if (ssl->options.dtls)
06429             c16toa(ssl->keys.dtls_state.curEpoch, add);
06430     #endif
06431 
06432     /* add TLS message size to additional data */
06433     add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff;
06434     add[AEAD_AUTH_DATA_SZ - 1] =  msgLen       & 0xff;
06435 
06436     #ifdef CHACHA_AEAD_TEST
06437         printf("Decrypt Additional : ");
06438         for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) {
06439             printf("%02x", add[i]);
06440         }
06441         printf("\n\n");
06442     #endif
06443 
06444     if (ssl->options.oldPoly == 0) {
06445         /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
06446          * record sequence number XORed with client_write_IV/server_write_IV */
06447         XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, CHACHA20_IMP_IV_SZ);
06448         nonce[4]  ^= add[0];
06449         nonce[5]  ^= add[1];
06450         nonce[6]  ^= add[2];
06451         nonce[7]  ^= add[3];
06452         nonce[8]  ^= add[4];
06453         nonce[9]  ^= add[5];
06454         nonce[10] ^= add[6];
06455         nonce[11] ^= add[7];
06456     }
06457 
06458     /* set nonce and get poly1305 key */
06459     if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) {
06460         ForceZero(nonce, CHACHA20_NONCE_SZ);
06461         return ret;
06462     }
06463 
06464     ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */
06465     /* use chacha20 keystream to get poly1305 key for tag */
06466     if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, poly,
06467                                                       poly, sizeof(poly))) != 0)
06468         return ret;
06469 
06470     /* get the tag using Poly1305 */
06471     if (ssl->options.oldPoly != 0) {
06472         if ((ret = Poly1305TagOld(ssl, add, input, poly, sz, tag)) != 0) {
06473             ForceZero(poly, sizeof(poly));
06474             return ret;
06475         }
06476     }
06477     else {
06478         if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly,
06479                                                           sizeof(poly))) != 0) {
06480             ForceZero(poly, sizeof(poly));
06481             return ret;
06482         }
06483         if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add,
06484                    sizeof(add), (byte*)input, msgLen, tag, sizeof(tag))) != 0) {
06485             ForceZero(poly, sizeof(poly));
06486             return ret;
06487         }
06488     }
06489     ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
06490 
06491     /* check tag sent along with packet */
06492     if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) {
06493         WOLFSSL_MSG("MAC did not match");
06494         SendAlert(ssl, alert_fatal, bad_record_mac);
06495         return VERIFY_MAC_ERROR;
06496     }
06497 
06498     /* if the tag was good decrypt message */
06499     if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain,
06500                                                            input, msgLen)) != 0)
06501         return ret;
06502 
06503     #ifdef CHACHA_AEAD_TEST
06504        printf("plain after decrypt :\n");
06505         for (i = 0; i < sz; i++) {
06506            printf("%02x", plain[i]);
06507            if ((i + 1) % 16 == 0)
06508                printf("\n");
06509         }
06510         printf("\n");
06511     #endif
06512 
06513     return ret;
06514 }
06515 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
06516 #endif /* HAVE_AEAD */
06517 
06518 
06519 static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz)
06520 {
06521     int ret = 0;
06522 
06523     (void)out;
06524     (void)input;
06525     (void)sz;
06526 
06527     if (ssl->encrypt.setup == 0) {
06528         WOLFSSL_MSG("Encrypt ciphers not setup");
06529         return ENCRYPT_ERROR;
06530     }
06531 
06532 #ifdef HAVE_FUZZER
06533     if (ssl->fuzzerCb)
06534         ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
06535 #endif
06536 
06537     switch (ssl->specs.bulk_cipher_algorithm) {
06538         #ifdef BUILD_ARC4
06539             case wolfssl_rc4:
06540                 wc_Arc4Process(ssl->encrypt.arc4, out, input, sz);
06541                 break;
06542         #endif
06543 
06544         #ifdef BUILD_DES3
06545             case wolfssl_triple_des:
06546                 ret = wc_Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
06547                 break;
06548         #endif
06549 
06550         #ifdef BUILD_AES
06551             case wolfssl_aes:
06552                 ret = wc_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
06553                 break;
06554         #endif
06555 
06556         #ifdef BUILD_AESGCM
06557             case wolfssl_aes_gcm:
06558                 {
06559                     byte additional[AEAD_AUTH_DATA_SZ];
06560                     byte nonce[AESGCM_NONCE_SZ];
06561                     const byte* additionalSrc = input - 5;
06562 
06563                     XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
06564 
06565                     /* sequence number field is 64-bits, we only use 32-bits */
06566                     c32toa(GetSEQIncrement(ssl, 0),
06567                                             additional + AEAD_SEQ_OFFSET);
06568 
06569                     /* Store the type, version. Unfortunately, they are in
06570                      * the input buffer ahead of the plaintext. */
06571                     #ifdef WOLFSSL_DTLS
06572                         if (ssl->options.dtls) {
06573                             c16toa(ssl->keys.dtls_epoch, additional);
06574                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
06575                         }
06576                     #endif
06577                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
06578 
06579                     /* Store the length of the plain text minus the explicit
06580                      * IV length minus the authentication tag size. */
06581                     c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06582                                                 additional + AEAD_LEN_OFFSET);
06583                     XMEMCPY(nonce,
06584                                  ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ);
06585                     XMEMCPY(nonce + AESGCM_IMP_IV_SZ,
06586                                      ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
06587                     ret = wc_AesGcmEncrypt(ssl->encrypt.aes,
06588                                out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
06589                                sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06590                                  nonce, AESGCM_NONCE_SZ,
06591                                  out + sz - ssl->specs.aead_mac_size,
06592                                  ssl->specs.aead_mac_size,
06593                                  additional, AEAD_AUTH_DATA_SZ);
06594                     AeadIncrementExpIV(ssl);
06595                     ForceZero(nonce, AESGCM_NONCE_SZ);
06596                 }
06597                 break;
06598         #endif
06599 
06600         #ifdef HAVE_AESCCM
06601             /* AEAD CCM uses same size as macros for AESGCM */
06602             case wolfssl_aes_ccm:
06603                 {
06604                     byte additional[AEAD_AUTH_DATA_SZ];
06605                     byte nonce[AESGCM_NONCE_SZ];
06606                     const byte* additionalSrc = input - 5;
06607 
06608                     XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
06609 
06610                     /* sequence number field is 64-bits, we only use 32-bits */
06611                     c32toa(GetSEQIncrement(ssl, 0),
06612                                             additional + AEAD_SEQ_OFFSET);
06613 
06614                     /* Store the type, version. Unfortunately, they are in
06615                      * the input buffer ahead of the plaintext. */
06616                     #ifdef WOLFSSL_DTLS
06617                         if (ssl->options.dtls) {
06618                             c16toa(ssl->keys.dtls_epoch, additional);
06619                             additionalSrc -= DTLS_HANDSHAKE_EXTRA;
06620                         }
06621                     #endif
06622                     XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
06623 
06624                     /* Store the length of the plain text minus the explicit
06625                      * IV length minus the authentication tag size. */
06626                     c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06627                                                 additional + AEAD_LEN_OFFSET);
06628                     XMEMCPY(nonce,
06629                                  ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ);
06630                     XMEMCPY(nonce + AESGCM_IMP_IV_SZ,
06631                                      ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
06632                     ret = wc_AesCcmEncrypt(ssl->encrypt.aes,
06633                         out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
06634                             sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06635                         nonce, AESGCM_NONCE_SZ,
06636                         out + sz - ssl->specs.aead_mac_size,
06637                         ssl->specs.aead_mac_size,
06638                         additional, AEAD_AUTH_DATA_SZ);
06639                     AeadIncrementExpIV(ssl);
06640                     ForceZero(nonce, AESGCM_NONCE_SZ);
06641                 }
06642                 break;
06643         #endif
06644 
06645         #ifdef HAVE_CAMELLIA
06646             case wolfssl_camellia:
06647                 wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
06648                 break;
06649         #endif
06650 
06651         #ifdef HAVE_HC128
06652             case wolfssl_hc128:
06653                 ret = wc_Hc128_Process(ssl->encrypt.hc128, out, input, sz);
06654                 break;
06655         #endif
06656 
06657         #ifdef BUILD_RABBIT
06658             case wolfssl_rabbit:
06659                 ret = wc_RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
06660                 break;
06661         #endif
06662 
06663         #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
06664             case wolfssl_chacha:
06665                 ret = ChachaAEADEncrypt(ssl, out, input, sz);
06666                 break;
06667         #endif
06668 
06669         #ifdef HAVE_NULL_CIPHER
06670             case wolfssl_cipher_null:
06671                 if (input != out) {
06672                     XMEMMOVE(out, input, sz);
06673                 }
06674                 break;
06675         #endif
06676 
06677         #ifdef HAVE_IDEA
06678             case wolfssl_idea:
06679                 ret = wc_IdeaCbcEncrypt(ssl->encrypt.idea, out, input, sz);
06680                 break;
06681         #endif
06682 
06683             default:
06684                 WOLFSSL_MSG("wolfSSL Encrypt programming error");
06685                 ret = ENCRYPT_ERROR;
06686     }
06687 
06688     return ret;
06689 }
06690 
06691 
06692 
06693 static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
06694                            word16 sz)
06695 {
06696     int ret = 0;
06697 
06698     (void)plain;
06699     (void)input;
06700     (void)sz;
06701 
06702     if (ssl->decrypt.setup == 0) {
06703         WOLFSSL_MSG("Decrypt ciphers not setup");
06704         return DECRYPT_ERROR;
06705     }
06706 
06707     switch (ssl->specs.bulk_cipher_algorithm) {
06708         #ifdef BUILD_ARC4
06709             case wolfssl_rc4:
06710                 wc_Arc4Process(ssl->decrypt.arc4, plain, input, sz);
06711                 break;
06712         #endif
06713 
06714         #ifdef BUILD_DES3
06715             case wolfssl_triple_des:
06716                 ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
06717                 break;
06718         #endif
06719 
06720         #ifdef BUILD_AES
06721             case wolfssl_aes:
06722                 ret = wc_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
06723                 break;
06724         #endif
06725 
06726         #ifdef BUILD_AESGCM
06727             case wolfssl_aes_gcm:
06728             {
06729                 byte additional[AEAD_AUTH_DATA_SZ];
06730                 byte nonce[AESGCM_NONCE_SZ];
06731 
06732                 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
06733 
06734                 /* sequence number field is 64-bits, we only use 32-bits */
06735                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
06736 
06737                 #ifdef WOLFSSL_DTLS
06738                     if (ssl->options.dtls)
06739                         c16toa(ssl->keys.dtls_state.curEpoch, additional);
06740                 #endif
06741 
06742                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
06743                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
06744                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
06745 
06746                 c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06747                                         additional + AEAD_LEN_OFFSET);
06748                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ);
06749                 XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ);
06750                 if (wc_AesGcmDecrypt(ssl->decrypt.aes,
06751                             plain + AESGCM_EXP_IV_SZ,
06752                             input + AESGCM_EXP_IV_SZ,
06753                                sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06754                             nonce, AESGCM_NONCE_SZ,
06755                             input + sz - ssl->specs.aead_mac_size,
06756                             ssl->specs.aead_mac_size,
06757                             additional, AEAD_AUTH_DATA_SZ) < 0) {
06758                     SendAlert(ssl, alert_fatal, bad_record_mac);
06759                     ret = VERIFY_MAC_ERROR;
06760                 }
06761                 ForceZero(nonce, AESGCM_NONCE_SZ);
06762             }
06763             break;
06764         #endif
06765 
06766         #ifdef HAVE_AESCCM
06767             /* AESGCM AEAD macros use same size as AESCCM */
06768             case wolfssl_aes_ccm:
06769             {
06770                 byte additional[AEAD_AUTH_DATA_SZ];
06771                 byte nonce[AESGCM_NONCE_SZ];
06772 
06773                 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
06774 
06775                 /* sequence number field is 64-bits, we only use 32-bits */
06776                 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
06777 
06778                 #ifdef WOLFSSL_DTLS
06779                     if (ssl->options.dtls)
06780                         c16toa(ssl->keys.dtls_state.curEpoch, additional);
06781                 #endif
06782 
06783                 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
06784                 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
06785                 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
06786 
06787                 c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06788                                         additional + AEAD_LEN_OFFSET);
06789                 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ);
06790                 XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ);
06791                 if (wc_AesCcmDecrypt(ssl->decrypt.aes,
06792                             plain + AESGCM_EXP_IV_SZ,
06793                             input + AESGCM_EXP_IV_SZ,
06794                                sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
06795                             nonce, AESGCM_NONCE_SZ,
06796                             input + sz - ssl->specs.aead_mac_size,
06797                             ssl->specs.aead_mac_size,
06798                             additional, AEAD_AUTH_DATA_SZ) < 0) {
06799                     SendAlert(ssl, alert_fatal, bad_record_mac);
06800                     ret = VERIFY_MAC_ERROR;
06801                 }
06802                 ForceZero(nonce, AESGCM_NONCE_SZ);
06803             }
06804             break;
06805         #endif
06806 
06807         #ifdef HAVE_CAMELLIA
06808             case wolfssl_camellia:
06809                 wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
06810                 break;
06811         #endif
06812 
06813         #ifdef HAVE_HC128
06814             case wolfssl_hc128:
06815                 ret = wc_Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
06816                 break;
06817         #endif
06818 
06819         #ifdef BUILD_RABBIT
06820             case wolfssl_rabbit:
06821                 ret = wc_RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
06822                 break;
06823         #endif
06824 
06825         #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
06826             case wolfssl_chacha:
06827                 ret = ChachaAEADDecrypt(ssl, plain, input, sz);
06828                 break;
06829         #endif
06830 
06831         #ifdef HAVE_NULL_CIPHER
06832             case wolfssl_cipher_null:
06833                 if (input != plain) {
06834                     XMEMMOVE(plain, input, sz);
06835                 }
06836                 break;
06837         #endif
06838 
06839         #ifdef HAVE_IDEA
06840             case wolfssl_idea:
06841                 ret = wc_IdeaCbcDecrypt(ssl->decrypt.idea, plain, input, sz);
06842                 break;
06843         #endif
06844 
06845             default:
06846                 WOLFSSL_MSG("wolfSSL Decrypt programming error");
06847                 ret = DECRYPT_ERROR;
06848     }
06849 
06850     return ret;
06851 }
06852 
06853 
06854 /* check cipher text size for sanity */
06855 static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
06856 {
06857 #ifdef HAVE_TRUNCATED_HMAC
06858     word32 minLength = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
06859                                            : ssl->specs.hash_size;
06860 #else
06861     word32 minLength = ssl->specs.hash_size; /* covers stream */
06862 #endif
06863 
06864     if (ssl->specs.cipher_type == block) {
06865         if (encryptSz % ssl->specs.block_size) {
06866             WOLFSSL_MSG("Block ciphertext not block size");
06867             return SANITY_CIPHER_E;
06868         }
06869 
06870         minLength++;  /* pad byte */
06871 
06872         if (ssl->specs.block_size > minLength)
06873             minLength = ssl->specs.block_size;
06874 
06875         if (ssl->options.tls1_1)
06876             minLength += ssl->specs.block_size;  /* explicit IV */
06877     }
06878     else if (ssl->specs.cipher_type == aead) {
06879         minLength = ssl->specs.aead_mac_size;    /* authTag size */
06880         if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
06881            minLength += AESGCM_EXP_IV_SZ;          /* explicit IV  */
06882     }
06883 
06884     if (encryptSz < minLength) {
06885         WOLFSSL_MSG("Ciphertext not minimum size");
06886         return SANITY_CIPHER_E;
06887     }
06888 
06889     return 0;
06890 }
06891 
06892 
06893 #ifndef NO_OLD_TLS
06894 
06895 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
06896 {
06897     Md5 md5;
06898     int i;
06899 
06900     wc_InitMd5(&md5);
06901 
06902     for (i = 0; i < rounds; i++)
06903         wc_Md5Update(&md5, data, sz);
06904     wc_Md5Free(&md5) ; /* in case needed to release resources */
06905 }
06906 
06907 
06908 
06909 /* do a dummy sha round */
06910 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
06911 {
06912     Sha sha;
06913     int i;
06914 
06915     wc_InitSha(&sha);  /* no error check on purpose, dummy round */
06916 
06917     for (i = 0; i < rounds; i++)
06918         wc_ShaUpdate(&sha, data, sz);
06919     wc_ShaFree(&sha) ; /* in case needed to release resources */
06920 }
06921 #endif
06922 
06923 
06924 #ifndef NO_SHA256
06925 
06926 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
06927 {
06928     Sha256 sha256;
06929     int i;
06930 
06931     wc_InitSha256(&sha256);  /* no error check on purpose, dummy round */
06932 
06933     for (i = 0; i < rounds; i++) {
06934         wc_Sha256Update(&sha256, data, sz);
06935         /* no error check on purpose, dummy round */
06936     }
06937     wc_Sha256Free(&sha256) ; /* in case needed to release resources */
06938 }
06939 
06940 #endif
06941 
06942 
06943 #ifdef WOLFSSL_SHA384
06944 
06945 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
06946 {
06947     Sha384 sha384;
06948     int i;
06949 
06950     wc_InitSha384(&sha384);  /* no error check on purpose, dummy round */
06951 
06952     for (i = 0; i < rounds; i++) {
06953         wc_Sha384Update(&sha384, data, sz);
06954         /* no error check on purpose, dummy round */
06955     }
06956     wc_Sha384Free(&sha384) ; /* in case needed to release resources */
06957 }
06958 
06959 #endif
06960 
06961 
06962 #ifdef WOLFSSL_SHA512
06963 
06964 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
06965 {
06966     Sha512 sha512;
06967     int i;
06968 
06969     wc_InitSha512(&sha512);  /* no error check on purpose, dummy round */
06970 
06971     for (i = 0; i < rounds; i++) {
06972         wc_Sha512Update(&sha512, data, sz);
06973         /* no error check on purpose, dummy round */
06974     }
06975     wc_Sha512Free(&sha512) ; /* in case needed to release resources */
06976 }
06977 
06978 #endif
06979 
06980 
06981 #ifdef WOLFSSL_RIPEMD
06982 
06983 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
06984 {
06985     RipeMd ripemd;
06986     int i;
06987 
06988     wc_InitRipeMd(&ripemd);
06989 
06990     for (i = 0; i < rounds; i++)
06991         wc_RipeMdUpdate(&ripemd, data, sz);
06992 }
06993 
06994 #endif
06995 
06996 
06997 /* Do dummy rounds */
06998 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
06999 {
07000     switch (type) {
07001 
07002         case no_mac :
07003             break;
07004 
07005 #ifndef NO_OLD_TLS
07006 #ifndef NO_MD5
07007         case md5_mac :
07008             Md5Rounds(rounds, data, sz);
07009             break;
07010 #endif
07011 
07012 #ifndef NO_SHA
07013         case sha_mac :
07014             ShaRounds(rounds, data, sz);
07015             break;
07016 #endif
07017 #endif
07018 
07019 #ifndef NO_SHA256
07020         case sha256_mac :
07021             Sha256Rounds(rounds, data, sz);
07022             break;
07023 #endif
07024 
07025 #ifdef WOLFSSL_SHA384
07026         case sha384_mac :
07027             Sha384Rounds(rounds, data, sz);
07028             break;
07029 #endif
07030 
07031 #ifdef WOLFSSL_SHA512
07032         case sha512_mac :
07033             Sha512Rounds(rounds, data, sz);
07034             break;
07035 #endif
07036 
07037 #ifdef WOLFSSL_RIPEMD
07038         case rmd_mac :
07039             RmdRounds(rounds, data, sz);
07040             break;
07041 #endif
07042 
07043         default:
07044             WOLFSSL_MSG("Bad round type");
07045             break;
07046     }
07047 }
07048 
07049 
07050 /* do number of compression rounds on dummy data */
07051 static INLINE void CompressRounds(WOLFSSL* ssl, int rounds, const byte* dummy)
07052 {
07053     if (rounds)
07054         DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
07055 }
07056 
07057 
07058 /* check all length bytes for the pad value, return 0 on success */
07059 static int PadCheck(const byte* a, byte pad, int length)
07060 {
07061     int i;
07062     int compareSum = 0;
07063 
07064     for (i = 0; i < length; i++) {
07065         compareSum |= a[i] ^ pad;
07066     }
07067 
07068     return compareSum;
07069 }
07070 
07071 
07072 /* get compression extra rounds */
07073 static INLINE int GetRounds(int pLen, int padLen, int t)
07074 {
07075     int  roundL1 = 1;  /* round up flags */
07076     int  roundL2 = 1;
07077 
07078     int L1 = COMPRESS_CONSTANT + pLen - t;
07079     int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
07080 
07081     L1 -= COMPRESS_UPPER;
07082     L2 -= COMPRESS_UPPER;
07083 
07084     if ( (L1 % COMPRESS_LOWER) == 0)
07085         roundL1 = 0;
07086     if ( (L2 % COMPRESS_LOWER) == 0)
07087         roundL2 = 0;
07088 
07089     L1 /= COMPRESS_LOWER;
07090     L2 /= COMPRESS_LOWER;
07091 
07092     L1 += roundL1;
07093     L2 += roundL2;
07094 
07095     return L1 - L2;
07096 }
07097 
07098 
07099 /* timing resistant pad/verify check, return 0 on success */
07100 static int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
07101                            int pLen, int content)
07102 {
07103     byte verify[MAX_DIGEST_SIZE];
07104     byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
07105     byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
07106     int  ret = 0;
07107 
07108     (void)dmy;
07109 
07110     if ( (t + padLen + 1) > pLen) {
07111         WOLFSSL_MSG("Plain Len not long enough for pad/mac");
07112         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
07113         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
07114         ConstantCompare(verify, input + pLen - t, t);
07115 
07116         return VERIFY_MAC_ERROR;
07117     }
07118 
07119     if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
07120         WOLFSSL_MSG("PadCheck failed");
07121         PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
07122         ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
07123         ConstantCompare(verify, input + pLen - t, t);
07124 
07125         return VERIFY_MAC_ERROR;
07126     }
07127 
07128     PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
07129     ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
07130 
07131     CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
07132 
07133     if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
07134         WOLFSSL_MSG("Verify MAC compare failed");
07135         return VERIFY_MAC_ERROR;
07136     }
07137 
07138     if (ret != 0)
07139         return VERIFY_MAC_ERROR;
07140     return 0;
07141 }
07142 
07143 
07144 int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
07145 {
07146     word32 msgSz   = ssl->keys.encryptSz;
07147     word32 idx     = *inOutIdx;
07148     int    dataSz;
07149     int    ivExtra = 0;
07150     byte*  rawData = input + idx;  /* keep current  for hmac */
07151 #ifdef HAVE_LIBZ
07152     byte   decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
07153 #endif
07154 
07155     if (ssl->options.handShakeDone == 0) {
07156         WOLFSSL_MSG("Received App data before a handshake completed");
07157         SendAlert(ssl, alert_fatal, unexpected_message);
07158         return OUT_OF_ORDER_E;
07159     }
07160 
07161     if (ssl->specs.cipher_type == block) {
07162         if (ssl->options.tls1_1)
07163             ivExtra = ssl->specs.block_size;
07164     }
07165     else if (ssl->specs.cipher_type == aead) {
07166         if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
07167             ivExtra = AESGCM_EXP_IV_SZ;
07168     }
07169 
07170     dataSz = msgSz - ivExtra - ssl->keys.padSz;
07171     if (dataSz < 0) {
07172         WOLFSSL_MSG("App data buffer error, malicious input?");
07173         return BUFFER_ERROR;
07174     }
07175 
07176     /* read data */
07177     if (dataSz) {
07178         int rawSz = dataSz;       /* keep raw size for idx adjustment */
07179 
07180 #ifdef HAVE_LIBZ
07181         if (ssl->options.usingCompression) {
07182             dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
07183             if (dataSz < 0) return dataSz;
07184         }
07185 #endif
07186         idx += rawSz;
07187 
07188         ssl->buffers.clearOutputBuffer.buffer = rawData;
07189         ssl->buffers.clearOutputBuffer.length = dataSz;
07190     }
07191 
07192     idx += ssl->keys.padSz;
07193 
07194 #ifdef HAVE_LIBZ
07195     /* decompress could be bigger, overwrite after verify */
07196     if (ssl->options.usingCompression)
07197         XMEMMOVE(rawData, decomp, dataSz);
07198 #endif
07199 
07200     *inOutIdx = idx;
07201     return 0;
07202 }
07203 
07204 
07205 /* process alert, return level */
07206 static int DoAlert(WOLFSSL* ssl, byte* input, word32* inOutIdx, int* type,
07207                    word32 totalSz)
07208 {
07209     byte level;
07210     byte code;
07211 
07212     #ifdef WOLFSSL_CALLBACKS
07213         if (ssl->hsInfoOn)
07214             AddPacketName("Alert", &ssl->handShakeInfo);
07215         if (ssl->toInfoOn)
07216             /* add record header back on to info + 2 byte level, data */
07217             AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
07218                           RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
07219     #endif
07220 
07221     /* make sure can read the message */
07222     if (*inOutIdx + ALERT_SIZE > totalSz)
07223         return BUFFER_E;
07224 
07225     level = input[(*inOutIdx)++];
07226     code  = input[(*inOutIdx)++];
07227     ssl->alert_history.last_rx.code = code;
07228     ssl->alert_history.last_rx.level = level;
07229     *type = code;
07230     if (level == alert_fatal) {
07231         ssl->options.isClosed = 1;  /* Don't send close_notify */
07232     }
07233 
07234     WOLFSSL_MSG("Got alert");
07235     if (*type == close_notify) {
07236         WOLFSSL_MSG("    close notify");
07237         ssl->options.closeNotify = 1;
07238     }
07239     WOLFSSL_ERROR(*type);
07240     if (IsEncryptionOn(ssl, 0)) {
07241         if (*inOutIdx + ssl->keys.padSz > totalSz)
07242             return BUFFER_E;
07243         *inOutIdx += ssl->keys.padSz;
07244     }
07245 
07246     return level;
07247 }
07248 
07249 static int GetInputData(WOLFSSL *ssl, word32 size)
07250 {
07251     int in;
07252     int inSz;
07253     int maxLength;
07254     int usedLength;
07255     int dtlsExtra = 0;
07256 
07257 
07258     /* check max input length */
07259     usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
07260     maxLength  = ssl->buffers.inputBuffer.bufferSize - usedLength;
07261     inSz       = (int)(size - usedLength);      /* from last partial read */
07262 
07263 #ifdef WOLFSSL_DTLS
07264     if (ssl->options.dtls) {
07265         if (size < ssl->dtls_expected_rx)
07266             dtlsExtra = (int)(ssl->dtls_expected_rx - size);
07267         inSz = ssl->dtls_expected_rx;
07268     }
07269 #endif
07270 
07271     if (inSz > maxLength) {
07272         if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
07273             return MEMORY_E;
07274     }
07275 
07276     if (inSz <= 0)
07277         return BUFFER_ERROR;
07278 
07279     /* Put buffer data at start if not there */
07280     if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
07281         XMEMMOVE(ssl->buffers.inputBuffer.buffer,
07282                 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
07283                 usedLength);
07284 
07285     /* remove processed data */
07286     ssl->buffers.inputBuffer.idx    = 0;
07287     ssl->buffers.inputBuffer.length = usedLength;
07288 
07289     /* read data from network */
07290     do {
07291         in = Receive(ssl,
07292                      ssl->buffers.inputBuffer.buffer +
07293                      ssl->buffers.inputBuffer.length,
07294                      inSz);
07295         if (in == -1)
07296             return SOCKET_ERROR_E;
07297 
07298         if (in == WANT_READ)
07299             return WANT_READ;
07300 
07301         if (in > inSz)
07302             return RECV_OVERFLOW_E;
07303 
07304         ssl->buffers.inputBuffer.length += in;
07305         inSz -= in;
07306 
07307     } while (ssl->buffers.inputBuffer.length < size);
07308 
07309     return 0;
07310 }
07311 
07312 
07313 static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
07314                             int content, word32* padSz)
07315 {
07316     int    ivExtra = 0;
07317     int    ret;
07318     word32 pad     = 0;
07319     word32 padByte = 0;
07320 #ifdef HAVE_TRUNCATED_HMAC
07321     word32 digestSz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
07322                                           : ssl->specs.hash_size;
07323 #else
07324     word32 digestSz = ssl->specs.hash_size;
07325 #endif
07326     byte   verify[MAX_DIGEST_SIZE];
07327 
07328     if (ssl->specs.cipher_type == block) {
07329         if (ssl->options.tls1_1)
07330             ivExtra = ssl->specs.block_size;
07331         pad = *(input + msgSz - ivExtra - 1);
07332         padByte = 1;
07333 
07334         if (ssl->options.tls) {
07335             ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
07336                                   content);
07337             if (ret != 0)
07338                 return ret;
07339         }
07340         else {  /* sslv3, some implementations have bad padding, but don't
07341                  * allow bad read */
07342             int  badPadLen = 0;
07343             byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
07344             byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
07345 
07346             (void)dmy;
07347 
07348             if (pad > (msgSz - digestSz - 1)) {
07349                 WOLFSSL_MSG("Plain Len not long enough for pad/mac");
07350                 pad       = 0;  /* no bad read */
07351                 badPadLen = 1;
07352             }
07353             PadCheck(dummy, (byte)pad, MAX_PAD_SIZE);  /* timing only */
07354             ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
07355                             content, 1);
07356             if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
07357                                 digestSz) != 0)
07358                 return VERIFY_MAC_ERROR;
07359             if (ret != 0 || badPadLen)
07360                 return VERIFY_MAC_ERROR;
07361         }
07362     }
07363     else if (ssl->specs.cipher_type == stream) {
07364         ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
07365         if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
07366             return VERIFY_MAC_ERROR;
07367         }
07368         if (ret != 0)
07369             return VERIFY_MAC_ERROR;
07370     }
07371 
07372     if (ssl->specs.cipher_type == aead) {
07373         *padSz = ssl->specs.aead_mac_size;
07374     }
07375     else {
07376         *padSz = digestSz + pad + padByte;
07377     }
07378 
07379     return 0;
07380 }
07381 
07382 
07383 /* process input requests, return 0 is done, 1 is call again to complete, and
07384    negative number is error */
07385 int ProcessReply(WOLFSSL* ssl)
07386 {
07387     int    ret = 0, type, readSz;
07388     int    atomicUser = 0;
07389     word32 startIdx = 0;
07390 #ifdef WOLFSSL_DTLS
07391     int    used;
07392 #endif
07393 
07394 #ifdef ATOMIC_USER
07395     if (ssl->ctx->DecryptVerifyCb)
07396         atomicUser = 1;
07397 #endif
07398 
07399     if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE){
07400         WOLFSSL_MSG("ProcessReply retry in error state, not allowed");
07401         return ssl->error;
07402     }
07403 
07404     for (;;) {
07405         switch (ssl->options.processReply) {
07406 
07407         /* in the WOLFSSL_SERVER case, get the first byte for detecting
07408          * old client hello */
07409         case doProcessInit:
07410 
07411             readSz = RECORD_HEADER_SZ;
07412 
07413             #ifdef WOLFSSL_DTLS
07414                 if (ssl->options.dtls)
07415                     readSz = DTLS_RECORD_HEADER_SZ;
07416             #endif
07417 
07418             /* get header or return error */
07419             if (!ssl->options.dtls) {
07420                 if ((ret = GetInputData(ssl, readSz)) < 0)
07421                     return ret;
07422             } else {
07423             #ifdef WOLFSSL_DTLS
07424                 /* read ahead may already have header */
07425                 used = ssl->buffers.inputBuffer.length -
07426                        ssl->buffers.inputBuffer.idx;
07427                 if (used < readSz)
07428                     if ((ret = GetInputData(ssl, readSz)) < 0)
07429                         return ret;
07430             #endif
07431             }
07432 
07433 #ifdef OLD_HELLO_ALLOWED
07434 
07435             /* see if sending SSLv2 client hello */
07436             if ( ssl->options.side == WOLFSSL_SERVER_END &&
07437                  ssl->options.clientState == NULL_STATE &&
07438                  ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
07439                          != handshake) {
07440                 byte b0, b1;
07441 
07442                 ssl->options.processReply = runProcessOldClientHello;
07443 
07444                 /* sanity checks before getting size at front */
07445                 if (ssl->buffers.inputBuffer.buffer[
07446                           ssl->buffers.inputBuffer.idx + 2] != OLD_HELLO_ID) {
07447                     WOLFSSL_MSG("Not a valid old client hello");
07448                     return PARSE_ERROR;
07449                 }
07450 
07451                 if (ssl->buffers.inputBuffer.buffer[
07452                           ssl->buffers.inputBuffer.idx + 3] != SSLv3_MAJOR &&
07453                     ssl->buffers.inputBuffer.buffer[
07454                           ssl->buffers.inputBuffer.idx + 3] != DTLS_MAJOR) {
07455                     WOLFSSL_MSG("Not a valid version in old client hello");
07456                     return PARSE_ERROR;
07457                 }
07458 
07459                 /* how many bytes need ProcessOldClientHello */
07460                 b0 =
07461                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
07462                 b1 =
07463                 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
07464                 ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
07465             }
07466             else {
07467                 ssl->options.processReply = getRecordLayerHeader;
07468                 continue;
07469             }
07470 
07471         /* in the WOLFSSL_SERVER case, run the old client hello */
07472         case runProcessOldClientHello:
07473 
07474             /* get sz bytes or return error */
07475             if (!ssl->options.dtls) {
07476                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
07477                     return ret;
07478             } else {
07479             #ifdef WOLFSSL_DTLS
07480                 /* read ahead may already have */
07481                 used = ssl->buffers.inputBuffer.length -
07482                        ssl->buffers.inputBuffer.idx;
07483                 if (used < ssl->curSize)
07484                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
07485                         return ret;
07486             #endif  /* WOLFSSL_DTLS */
07487             }
07488 
07489             ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
07490                                         &ssl->buffers.inputBuffer.idx,
07491                                         ssl->buffers.inputBuffer.length -
07492                                         ssl->buffers.inputBuffer.idx,
07493                                         ssl->curSize);
07494             if (ret < 0)
07495                 return ret;
07496 
07497             else if (ssl->buffers.inputBuffer.idx ==
07498                      ssl->buffers.inputBuffer.length) {
07499                 ssl->options.processReply = doProcessInit;
07500                 return 0;
07501             }
07502 
07503 #endif  /* OLD_HELLO_ALLOWED */
07504 
07505         /* get the record layer header */
07506         case getRecordLayerHeader:
07507 
07508             ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
07509                                        &ssl->buffers.inputBuffer.idx,
07510                                        &ssl->curRL, &ssl->curSize);
07511 #ifdef WOLFSSL_DTLS
07512             if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
07513                 WOLFSSL_MSG("Silently dropping out of order DTLS message");
07514                 ssl->options.processReply = doProcessInit;
07515                 ssl->buffers.inputBuffer.length = 0;
07516                 ssl->buffers.inputBuffer.idx = 0;
07517                 continue;
07518             }
07519 #endif
07520             if (ret != 0)
07521                 return ret;
07522 
07523             ssl->options.processReply = getData;
07524 
07525         /* retrieve record layer data */
07526         case getData:
07527 
07528             /* get sz bytes or return error */
07529             if (!ssl->options.dtls) {
07530                 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
07531                     return ret;
07532             } else {
07533 #ifdef WOLFSSL_DTLS
07534                 /* read ahead may already have */
07535                 used = ssl->buffers.inputBuffer.length -
07536                        ssl->buffers.inputBuffer.idx;
07537                 if (used < ssl->curSize)
07538                     if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
07539                         return ret;
07540 #endif
07541             }
07542 
07543             ssl->options.processReply = runProcessingOneMessage;
07544             startIdx = ssl->buffers.inputBuffer.idx;  /* in case > 1 msg per */
07545 
07546         /* the record layer is here */
07547         case runProcessingOneMessage:
07548 
07549             if (IsEncryptionOn(ssl, 0) && ssl->keys.decryptedCur == 0)
07550             {
07551                 ret = SanityCheckCipherText(ssl, ssl->curSize);
07552                 if (ret < 0)
07553                     return ret;
07554 
07555                 if (atomicUser) {
07556                 #ifdef ATOMIC_USER
07557                     ret = ssl->ctx->DecryptVerifyCb(ssl,
07558                                   ssl->buffers.inputBuffer.buffer +
07559                                   ssl->buffers.inputBuffer.idx,
07560                                   ssl->buffers.inputBuffer.buffer +
07561                                   ssl->buffers.inputBuffer.idx,
07562                                   ssl->curSize, ssl->curRL.type, 1,
07563                                   &ssl->keys.padSz, ssl->DecryptVerifyCtx);
07564                     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
07565                         ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
07566                         /* go past TLSv1.1 IV */
07567                     if (ssl->specs.cipher_type == aead &&
07568                             ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
07569                         ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ;
07570                 #endif /* ATOMIC_USER */
07571                 }
07572                 else {
07573                     ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
07574                                   ssl->buffers.inputBuffer.idx,
07575                                   ssl->buffers.inputBuffer.buffer +
07576                                   ssl->buffers.inputBuffer.idx,
07577                                   ssl->curSize);
07578                     if (ret < 0) {
07579                         WOLFSSL_MSG("Decrypt failed");
07580                         WOLFSSL_ERROR(ret);
07581                         return DECRYPT_ERROR;
07582                     }
07583                     if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
07584                         ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
07585                         /* go past TLSv1.1 IV */
07586                     if (ssl->specs.cipher_type == aead &&
07587                             ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
07588                         ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ;
07589 
07590                     ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
07591                                     ssl->buffers.inputBuffer.idx,
07592                                     ssl->curSize, ssl->curRL.type,
07593                                     &ssl->keys.padSz);
07594                 }
07595                 if (ret < 0) {
07596                     WOLFSSL_MSG("VerifyMac failed");
07597                     WOLFSSL_ERROR(ret);
07598                     return DECRYPT_ERROR;
07599                 }
07600                 ssl->keys.encryptSz    = ssl->curSize;
07601                 ssl->keys.decryptedCur = 1;
07602             }
07603 
07604             if (ssl->options.dtls) {
07605             #ifdef WOLFSSL_DTLS
07606                 DtlsUpdateWindow(&ssl->keys.dtls_state);
07607             #endif /* WOLFSSL_DTLS */
07608             }
07609 
07610             WOLFSSL_MSG("received record layer msg");
07611 
07612             switch (ssl->curRL.type) {
07613                 case handshake :
07614                     /* debugging in DoHandShakeMsg */
07615                     if (!ssl->options.dtls) {
07616                         ret = DoHandShakeMsg(ssl,
07617                                             ssl->buffers.inputBuffer.buffer,
07618                                             &ssl->buffers.inputBuffer.idx,
07619                                             ssl->buffers.inputBuffer.length);
07620                     }
07621                     else {
07622 #ifdef WOLFSSL_DTLS
07623                         ret = DoDtlsHandShakeMsg(ssl,
07624                                             ssl->buffers.inputBuffer.buffer,
07625                                             &ssl->buffers.inputBuffer.idx,
07626                                             ssl->buffers.inputBuffer.length);
07627 #endif
07628                     }
07629                     if (ret != 0)
07630                         return ret;
07631                     break;
07632 
07633                 case change_cipher_spec:
07634                     WOLFSSL_MSG("got CHANGE CIPHER SPEC");
07635                     #ifdef WOLFSSL_CALLBACKS
07636                         if (ssl->hsInfoOn)
07637                             AddPacketName("ChangeCipher", &ssl->handShakeInfo);
07638                         /* add record header back on info */
07639                         if (ssl->toInfoOn) {
07640                             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
07641                                 ssl->buffers.inputBuffer.buffer +
07642                                 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
07643                                 1 + RECORD_HEADER_SZ, ssl->heap);
07644                             AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
07645                         }
07646                     #endif
07647 
07648 #ifdef WOLFSSL_DTLS
07649                     /* Check for duplicate CCS message in DTLS mode.
07650                      * DTLS allows for duplicate messages, and it should be
07651                      * skipped. */
07652                     if (ssl->options.dtls &&
07653                         ssl->msgsReceived.got_change_cipher) {
07654 
07655                         WOLFSSL_MSG("Duplicate ChangeCipher msg");
07656                         ret = DtlsPoolSend(ssl);
07657                         if (ret != 0)
07658                             return ret;
07659 
07660                         if (ssl->curSize != 1) {
07661                             WOLFSSL_MSG("Malicious or corrupted"
07662                                         " duplicate ChangeCipher msg");
07663                             return LENGTH_ERROR;
07664                         }
07665                         ssl->buffers.inputBuffer.idx++;
07666                         break;
07667                     }
07668 #endif
07669 
07670                     ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
07671                     if (ret != 0)
07672                         return ret;
07673 
07674 #ifdef HAVE_SESSION_TICKET
07675                     if (ssl->options.side == WOLFSSL_CLIENT_END &&
07676                                                   ssl->expect_session_ticket) {
07677                         WOLFSSL_MSG("Expected session ticket missing");
07678                         return SESSION_TICKET_EXPECT_E;
07679                     }
07680 #endif
07681 
07682                     if (IsEncryptionOn(ssl, 0) && ssl->options.handShakeDone) {
07683                         ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
07684                         ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx;
07685                     }
07686 
07687                     if (ssl->curSize != 1) {
07688                         WOLFSSL_MSG("Malicious or corrupted ChangeCipher msg");
07689                         return LENGTH_ERROR;
07690                     }
07691                     #ifndef NO_CERTS
07692                         if (ssl->options.side == WOLFSSL_SERVER_END &&
07693                                  ssl->options.verifyPeer &&
07694                                  ssl->options.havePeerCert)
07695                             if (!ssl->options.havePeerVerify) {
07696                                 WOLFSSL_MSG("client didn't send cert verify");
07697                                 return NO_PEER_VERIFY;
07698                             }
07699                     #endif
07700 
07701 
07702                     ssl->buffers.inputBuffer.idx++;
07703                     ssl->keys.encryptionOn = 1;
07704 
07705                     /* setup decrypt keys for following messages */
07706                     if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
07707                         return ret;
07708 
07709                     #ifdef WOLFSSL_DTLS
07710                         if (ssl->options.dtls) {
07711                             DtlsPoolReset(ssl);
07712                             ssl->keys.dtls_state.nextEpoch++;
07713                             ssl->keys.dtls_state.nextSeq = 0;
07714                         }
07715                     #endif
07716 
07717                     #ifdef HAVE_LIBZ
07718                         if (ssl->options.usingCompression)
07719                             if ( (ret = InitStreams(ssl)) != 0)
07720                                 return ret;
07721                     #endif
07722                     ret = BuildFinished(ssl, &ssl->hsHashes->verifyHashes,
07723                                        ssl->options.side == WOLFSSL_CLIENT_END ?
07724                                        server : client);
07725                     if (ret != 0)
07726                         return ret;
07727                     break;
07728 
07729                 case application_data:
07730                     WOLFSSL_MSG("got app DATA");
07731                     #ifdef WOLFSSL_DTLS
07732                         if (ssl->options.dtls && ssl->options.dtlsHsRetain) {
07733                             FreeHandshakeResources(ssl);
07734                             ssl->options.dtlsHsRetain = 0;
07735                         }
07736                     #endif
07737                     if ((ret = DoApplicationData(ssl,
07738                                                 ssl->buffers.inputBuffer.buffer,
07739                                                &ssl->buffers.inputBuffer.idx))
07740                                                                          != 0) {
07741                         WOLFSSL_ERROR(ret);
07742                         return ret;
07743                     }
07744                     break;
07745 
07746                 case alert:
07747                     WOLFSSL_MSG("got ALERT!");
07748                     ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
07749                                   &ssl->buffers.inputBuffer.idx, &type,
07750                                    ssl->buffers.inputBuffer.length);
07751                     if (ret == alert_fatal)
07752                         return FATAL_ERROR;
07753                     else if (ret < 0)
07754                         return ret;
07755 
07756                     /* catch warnings that are handled as errors */
07757                     if (type == close_notify)
07758                         return ssl->error = ZERO_RETURN;
07759 
07760                     if (type == decrypt_error)
07761                         return FATAL_ERROR;
07762                     break;
07763 
07764                 default:
07765                     WOLFSSL_ERROR(UNKNOWN_RECORD_TYPE);
07766                     return UNKNOWN_RECORD_TYPE;
07767             }
07768 
07769             ssl->options.processReply = doProcessInit;
07770 
07771             /* input exhausted? */
07772             if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
07773                 return 0;
07774 
07775             /* more messages per record */
07776             else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
07777                 WOLFSSL_MSG("More messages in record");
07778                 #ifdef WOLFSSL_DTLS
07779                     /* read-ahead but dtls doesn't bundle messages per record */
07780                     if (ssl->options.dtls) {
07781                         ssl->options.processReply = doProcessInit;
07782                         continue;
07783                     }
07784                 #endif
07785                 ssl->options.processReply = runProcessingOneMessage;
07786 
07787                 if (IsEncryptionOn(ssl, 0)) {
07788                     WOLFSSL_MSG("Bundled encrypted messages, remove middle pad");
07789                     ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
07790                 }
07791 
07792                 continue;
07793             }
07794             /* more records */
07795             else {
07796                 WOLFSSL_MSG("More records in input");
07797                 ssl->options.processReply = doProcessInit;
07798                 continue;
07799             }
07800 
07801         default:
07802             WOLFSSL_MSG("Bad process input state, programming error");
07803             return INPUT_CASE_ERROR;
07804         }
07805     }
07806 }
07807 
07808 
07809 int SendChangeCipher(WOLFSSL* ssl)
07810 {
07811     byte              *output;
07812     int                sendSz = RECORD_HEADER_SZ + ENUM_LEN;
07813     int                idx    = RECORD_HEADER_SZ;
07814     int                ret;
07815 
07816     #ifdef WOLFSSL_DTLS
07817         if (ssl->options.dtls) {
07818             sendSz += DTLS_RECORD_EXTRA;
07819             idx    += DTLS_RECORD_EXTRA;
07820         }
07821     #endif
07822 
07823     /* are we in scr */
07824     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
07825         sendSz += MAX_MSG_EXTRA;
07826     }
07827 
07828     /* check for avalaible size */
07829     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
07830         return ret;
07831 
07832     /* get output buffer */
07833     output = ssl->buffers.outputBuffer.buffer +
07834              ssl->buffers.outputBuffer.length;
07835 
07836     AddRecordHeader(output, 1, change_cipher_spec, ssl);
07837 
07838     output[idx] = 1;             /* turn it on */
07839 
07840     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) {
07841         byte input[ENUM_LEN];
07842         int  inputSz = ENUM_LEN;
07843 
07844         input[0] = 1;  /* turn it on */
07845         sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
07846                               change_cipher_spec, 0);
07847         if (sendSz < 0)
07848             return sendSz;
07849     }
07850 
07851     #ifdef WOLFSSL_DTLS
07852         if (ssl->options.dtls) {
07853             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
07854                 return ret;
07855         }
07856     #endif
07857     #ifdef WOLFSSL_CALLBACKS
07858         if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
07859         if (ssl->toInfoOn)
07860             AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
07861                            ssl->heap);
07862     #endif
07863     ssl->buffers.outputBuffer.length += sendSz;
07864 
07865     if (ssl->options.groupMessages)
07866         return 0;
07867     #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DEBUG_DTLS)
07868     else if (ssl->options.dtls) {
07869         /* If using DTLS, force the ChangeCipherSpec message to be in the
07870          * same datagram as the finished message. */
07871         return 0;
07872     }
07873     #endif
07874     else
07875         return SendBuffered(ssl);
07876 }
07877 
07878 
07879 #ifndef NO_OLD_TLS
07880 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
07881                  int content, int verify)
07882 {
07883     byte   result[MAX_DIGEST_SIZE];
07884     word32 digestSz = ssl->specs.hash_size;            /* actual sizes */
07885     word32 padSz    = ssl->specs.pad_size;
07886     int    ret      = 0;
07887 
07888     Md5 md5;
07889     Sha sha;
07890 
07891     /* data */
07892     byte seq[SEQ_SZ];
07893     byte conLen[ENUM_LEN + LENGTH_SZ];     /* content & length */
07894     const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
07895 
07896 #ifdef HAVE_FUZZER
07897     if (ssl->fuzzerCb)
07898         ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
07899 #endif
07900 
07901     XMEMSET(seq, 0, SEQ_SZ);
07902     conLen[0] = (byte)content;
07903     c16toa((word16)sz, &conLen[ENUM_LEN]);
07904     c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
07905 
07906     if (ssl->specs.mac_algorithm == md5_mac) {
07907         wc_InitMd5(&md5);
07908         /* inner */
07909         wc_Md5Update(&md5, macSecret, digestSz);
07910         wc_Md5Update(&md5, PAD1, padSz);
07911         wc_Md5Update(&md5, seq, SEQ_SZ);
07912         wc_Md5Update(&md5, conLen, sizeof(conLen));
07913         /* in buffer */
07914         wc_Md5Update(&md5, in, sz);
07915         wc_Md5Final(&md5, result);
07916         /* outer */
07917         wc_Md5Update(&md5, macSecret, digestSz);
07918         wc_Md5Update(&md5, PAD2, padSz);
07919         wc_Md5Update(&md5, result, digestSz);
07920         wc_Md5Final(&md5, digest);
07921     }
07922     else {
07923         ret = wc_InitSha(&sha);
07924         if (ret != 0)
07925             return ret;
07926         /* inner */
07927         wc_ShaUpdate(&sha, macSecret, digestSz);
07928         wc_ShaUpdate(&sha, PAD1, padSz);
07929         wc_ShaUpdate(&sha, seq, SEQ_SZ);
07930         wc_ShaUpdate(&sha, conLen, sizeof(conLen));
07931         /* in buffer */
07932         wc_ShaUpdate(&sha, in, sz);
07933         wc_ShaFinal(&sha, result);
07934         /* outer */
07935         wc_ShaUpdate(&sha, macSecret, digestSz);
07936         wc_ShaUpdate(&sha, PAD2, padSz);
07937         wc_ShaUpdate(&sha, result, digestSz);
07938         wc_ShaFinal(&sha, digest);
07939     }
07940     return 0;
07941 }
07942 
07943 #ifndef NO_CERTS
07944 static void BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
07945 {
07946     byte md5_result[MD5_DIGEST_SIZE];
07947 
07948 #ifdef WOLFSSL_SMALL_STACK
07949         Md5* md5   = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
07950         Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
07951 #else
07952         Md5 md5[1];
07953         Md5 md5_2[1];
07954 #endif
07955 
07956     /* make md5 inner */
07957     md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
07958     wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
07959     wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
07960     wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
07961     wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
07962 
07963     /* make md5 outer */
07964     wc_InitMd5(md5_2) ;
07965     wc_Md5Update(md5_2, ssl->arrays->masterSecret, SECRET_LEN);
07966     wc_Md5Update(md5_2, PAD2, PAD_MD5);
07967     wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
07968 
07969     wc_Md5Final(md5_2, digest);
07970 
07971 #ifdef WOLFSSL_SMALL_STACK
07972     XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07973     XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
07974 #endif
07975 }
07976 
07977 
07978 static void BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
07979 {
07980     byte sha_result[SHA_DIGEST_SIZE];
07981 
07982 #ifdef WOLFSSL_SMALL_STACK
07983         Sha* sha   = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
07984         Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
07985 #else
07986         Sha sha[1];
07987         Sha sha2[1];
07988 #endif
07989 
07990     /* make sha inner */
07991     sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
07992     wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
07993     wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
07994     wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
07995     wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
07996 
07997     /* make sha outer */
07998     wc_InitSha(sha2) ;
07999     wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
08000     wc_ShaUpdate(sha2, PAD2, PAD_SHA);
08001     wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
08002 
08003     wc_ShaFinal(sha2, digest);
08004 
08005 #ifdef WOLFSSL_SMALL_STACK
08006     XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08007     XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08008 #endif
08009 
08010 }
08011 #endif /* NO_CERTS */
08012 #endif /* NO_OLD_TLS */
08013 
08014 
08015 #ifndef NO_CERTS
08016 
08017 static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
08018 {
08019     /* store current states, building requires get_digest which resets state */
08020     #ifdef WOLFSSL_SHA384
08021         Sha384 sha384 = ssl->hsHashes->hashSha384;
08022     #endif
08023     #ifdef WOLFSSL_SHA512
08024         Sha512 sha512 = ssl->hsHashes->hashSha512;
08025     #endif
08026 
08027     if (ssl->options.tls) {
08028 #if ! defined( NO_OLD_TLS )
08029         wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
08030         wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
08031 #endif
08032         if (IsAtLeastTLSv1_2(ssl)) {
08033             int ret;
08034 
08035             #ifndef NO_SHA256
08036                 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,hashes->sha256);
08037                 if (ret != 0)
08038                     return ret;
08039             #endif
08040             #ifdef WOLFSSL_SHA384
08041                 ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,hashes->sha384);
08042                 if (ret != 0)
08043                     return ret;
08044             #endif
08045             #ifdef WOLFSSL_SHA512
08046                 ret = wc_Sha512Final(&ssl->hsHashes->hashSha512,hashes->sha512);
08047                 if (ret != 0)
08048                     return ret;
08049             #endif
08050         }
08051     }
08052 #if ! defined( NO_OLD_TLS )
08053     else {
08054         BuildMD5_CertVerify(ssl, hashes->md5);
08055         BuildSHA_CertVerify(ssl, hashes->sha);
08056     }
08057 
08058     /* restore */
08059 #endif
08060     if (IsAtLeastTLSv1_2(ssl)) {
08061         #ifdef WOLFSSL_SHA384
08062             ssl->hsHashes->hashSha384 = sha384;
08063         #endif
08064         #ifdef WOLFSSL_SHA512
08065             ssl->hsHashes->hashSha512 = sha512;
08066         #endif
08067     }
08068 
08069     return 0;
08070 }
08071 
08072 #endif /* WOLFSSL_LEANPSK */
08073 
08074 /* Build SSL Message, encrypted */
08075 static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
08076                         const byte* input, int inSz, int type, int hashOutput)
08077 {
08078 #ifdef HAVE_TRUNCATED_HMAC
08079     word32 digestSz = min(ssl->specs.hash_size,
08080                 ssl->truncated_hmac ? TRUNCATED_HMAC_SZ : ssl->specs.hash_size);
08081 #else
08082     word32 digestSz = ssl->specs.hash_size;
08083 #endif
08084     word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
08085     word32 pad  = 0, i;
08086     word32 idx  = RECORD_HEADER_SZ;
08087     word32 ivSz = 0;      /* TLSv1.1  IV */
08088     word32 headerSz = RECORD_HEADER_SZ;
08089     word16 size;
08090     byte               iv[AES_BLOCK_SIZE];                  /* max size */
08091     int ret        = 0;
08092     int atomicUser = 0;
08093 
08094 #ifdef WOLFSSL_DTLS
08095     if (ssl->options.dtls) {
08096         sz       += DTLS_RECORD_EXTRA;
08097         idx      += DTLS_RECORD_EXTRA;
08098         headerSz += DTLS_RECORD_EXTRA;
08099     }
08100 #endif
08101 
08102 #ifdef ATOMIC_USER
08103     if (ssl->ctx->MacEncryptCb)
08104         atomicUser = 1;
08105 #endif
08106 
08107     if (ssl->specs.cipher_type == block) {
08108         word32 blockSz = ssl->specs.block_size;
08109         if (ssl->options.tls1_1) {
08110             ivSz = blockSz;
08111             sz  += ivSz;
08112 
08113             if (ivSz > (word32)sizeof(iv))
08114                 return BUFFER_E;
08115 
08116             ret = wc_RNG_GenerateBlock(ssl->rng, iv, ivSz);
08117             if (ret != 0)
08118                 return ret;
08119 
08120         }
08121         sz += 1;       /* pad byte */
08122         pad = (sz - headerSz) % blockSz;
08123         pad = blockSz - pad;
08124         sz += pad;
08125     }
08126 
08127 #ifdef HAVE_AEAD
08128     if (ssl->specs.cipher_type == aead) {
08129         if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
08130             ivSz = AESGCM_EXP_IV_SZ;
08131 
08132         sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
08133         XMEMCPY(iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
08134     }
08135 #endif
08136     if (sz > (word32)outSz) {
08137         WOLFSSL_MSG("Oops, want to write past output buffer size");
08138         return BUFFER_E;
08139     }
08140     size = (word16)(sz - headerSz);    /* include mac and digest */
08141     AddRecordHeader(output, size, (byte)type, ssl);
08142 
08143     /* write to output */
08144     if (ivSz) {
08145         XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
08146         idx += ivSz;
08147     }
08148     XMEMCPY(output + idx, input, inSz);
08149     idx += inSz;
08150 
08151     if (type == handshake && hashOutput) {
08152         ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
08153         if (ret != 0)
08154             return ret;
08155     }
08156 
08157     if (ssl->specs.cipher_type == block) {
08158         word32 tmpIdx = idx + digestSz;
08159 
08160         for (i = 0; i <= pad; i++)
08161             output[tmpIdx++] = (byte)pad; /* pad byte gets pad value too */
08162     }
08163 
08164     if (atomicUser) {   /* User Record Layer Callback handling */
08165 #ifdef ATOMIC_USER
08166         if ( (ret = ssl->ctx->MacEncryptCb(ssl, output + idx,
08167                         output + headerSz + ivSz, inSz, type, 0,
08168                         output + headerSz, output + headerSz, size,
08169                         ssl->MacEncryptCtx)) != 0)
08170             return ret;
08171 #endif
08172     }
08173     else {
08174         if (ssl->specs.cipher_type != aead) {
08175 #ifdef HAVE_TRUNCATED_HMAC
08176             if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) {
08177             #ifdef WOLFSSL_SMALL_STACK
08178                 byte* hmac = NULL;
08179             #else
08180                 byte  hmac[MAX_DIGEST_SIZE];
08181             #endif
08182 
08183             #ifdef WOLFSSL_SMALL_STACK
08184                 hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL,
08185                                                        DYNAMIC_TYPE_TMP_BUFFER);
08186                 if (hmac == NULL)
08187                     return MEMORY_E;
08188             #endif
08189 
08190                 ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz,
08191                                                                        type, 0);
08192                 XMEMCPY(output + idx, hmac, digestSz);
08193 
08194             #ifdef WOLFSSL_SMALL_STACK
08195                 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08196             #endif
08197             } else
08198 #endif
08199                 ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
08200                                                                        type, 0);
08201         }
08202         if (ret != 0)
08203             return ret;
08204 
08205         if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0)
08206             return ret;
08207     }
08208 
08209     return sz;
08210 }
08211 
08212 
08213 int SendFinished(WOLFSSL* ssl)
08214 {
08215     int              sendSz,
08216                      finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
08217                                                      FINISHED_SZ;
08218     byte             input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ];  /* max */
08219     byte            *output;
08220     Hashes*          hashes;
08221     int              ret;
08222     int              headerSz = HANDSHAKE_HEADER_SZ;
08223     int              outputSz;
08224 
08225     /* setup encrypt keys */
08226     if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
08227         return ret;
08228 
08229     /* check for available size */
08230     outputSz = sizeof(input) + MAX_MSG_EXTRA;
08231     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
08232         return ret;
08233 
08234     #ifdef WOLFSSL_DTLS
08235         if (ssl->options.dtls) {
08236             headerSz += DTLS_HANDSHAKE_EXTRA;
08237             ssl->keys.dtls_epoch++;
08238             ssl->keys.dtls_prev_sequence_number =
08239                     ssl->keys.dtls_sequence_number;
08240             ssl->keys.dtls_sequence_number = 0;
08241         }
08242     #endif
08243 
08244     /* get output buffer */
08245     output = ssl->buffers.outputBuffer.buffer +
08246              ssl->buffers.outputBuffer.length;
08247 
08248     AddHandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
08249 
08250     /* make finished hashes */
08251     hashes = (Hashes*)&input[headerSz];
08252     ret = BuildFinished(ssl, hashes,
08253                      ssl->options.side == WOLFSSL_CLIENT_END ? client : server);
08254     if (ret != 0) return ret;
08255 
08256 #ifdef HAVE_SECURE_RENEGOTIATION
08257     if (ssl->secure_renegotiation) {
08258         if (ssl->options.side == WOLFSSL_CLIENT_END)
08259             XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
08260                     TLS_FINISHED_SZ);
08261         else
08262             XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
08263                     TLS_FINISHED_SZ);
08264     }
08265 #endif
08266 
08267     #ifdef WOLFSSL_DTLS
08268         if (ssl->options.dtls) {
08269             if ((ret = DtlsPoolSave(ssl, input, headerSz + finishedSz)) != 0)
08270                 return ret;
08271         }
08272     #endif
08273 
08274     sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
08275                           handshake, 1);
08276     if (sendSz < 0)
08277         return BUILD_MSG_ERROR;
08278 
08279     if (!ssl->options.resuming) {
08280 #ifndef NO_SESSION_CACHE
08281         AddSession(ssl);    /* just try */
08282 #endif
08283         if (ssl->options.side == WOLFSSL_SERVER_END) {
08284             ssl->options.handShakeState = HANDSHAKE_DONE;
08285             ssl->options.handShakeDone  = 1;
08286         }
08287     }
08288     else {
08289         if (ssl->options.side == WOLFSSL_CLIENT_END) {
08290             ssl->options.handShakeState = HANDSHAKE_DONE;
08291             ssl->options.handShakeDone  = 1;
08292         }
08293     }
08294 
08295     #ifdef WOLFSSL_CALLBACKS
08296         if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
08297         if (ssl->toInfoOn)
08298             AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
08299                           ssl->heap);
08300     #endif
08301 
08302     ssl->buffers.outputBuffer.length += sendSz;
08303 
08304     return SendBuffered(ssl);
08305 }
08306 
08307 
08308 #ifndef NO_CERTS
08309 int SendCertificate(WOLFSSL* ssl)
08310 {
08311     int    ret = 0;
08312     word32 certSz, certChainSz, headerSz, listSz, payloadSz;
08313     word32 length, maxFragment;
08314 
08315     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
08316         return 0;  /* not needed */
08317 
08318     if (ssl->options.sendVerify == SEND_BLANK_CERT) {
08319         certSz = 0;
08320         certChainSz = 0;
08321         headerSz = CERT_HEADER_SZ;
08322         length = CERT_HEADER_SZ;
08323         listSz = 0;
08324     }
08325     else {
08326         if (!ssl->buffers.certificate) {
08327             WOLFSSL_MSG("Send Cert missing certificate buffer");
08328             return BUFFER_ERROR;
08329         }
08330         certSz = ssl->buffers.certificate->length;
08331         headerSz = 2 * CERT_HEADER_SZ;
08332         /* list + cert size */
08333         length = certSz + headerSz;
08334         listSz = certSz + CERT_HEADER_SZ;
08335 
08336         /* may need to send rest of chain, already has leading size(s) */
08337         if (certSz && ssl->buffers.certChain) {
08338             certChainSz = ssl->buffers.certChain->length;
08339             length += certChainSz;
08340             listSz += certChainSz;
08341         }
08342         else
08343             certChainSz = 0;
08344     }
08345 
08346     payloadSz = length;
08347 
08348     if (ssl->fragOffset != 0)
08349         length -= (ssl->fragOffset + headerSz);
08350 
08351     maxFragment = MAX_RECORD_SIZE;
08352     if (ssl->options.dtls) {
08353     #ifdef WOLFSSL_DTLS
08354         maxFragment = MAX_MTU - DTLS_RECORD_HEADER_SZ
08355                       - DTLS_HANDSHAKE_HEADER_SZ - 100;
08356     #endif /* WOLFSSL_DTLS */
08357     }
08358 
08359     #ifdef HAVE_MAX_FRAGMENT
08360     if (ssl->max_fragment != 0 && maxFragment >= ssl->max_fragment)
08361         maxFragment = ssl->max_fragment;
08362     #endif /* HAVE_MAX_FRAGMENT */
08363 
08364     while (length > 0 && ret == 0) {
08365         byte*  output = NULL;
08366         word32 fragSz = 0;
08367         word32 i = RECORD_HEADER_SZ;
08368         int    sendSz = RECORD_HEADER_SZ;
08369 
08370         if (!ssl->options.dtls) {
08371             if (ssl->fragOffset == 0)  {
08372                 if (headerSz + certSz + certChainSz <=
08373                     maxFragment - HANDSHAKE_HEADER_SZ) {
08374 
08375                     fragSz = headerSz + certSz + certChainSz;
08376                 }
08377                 else {
08378                     fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
08379                 }
08380                 sendSz += fragSz + HANDSHAKE_HEADER_SZ;
08381                 i += HANDSHAKE_HEADER_SZ;
08382             }
08383             else {
08384                 fragSz = min(length, maxFragment);
08385                 sendSz += fragSz;
08386             }
08387 
08388             if (IsEncryptionOn(ssl, 1))
08389                 sendSz += MAX_MSG_EXTRA;
08390         }
08391         else {
08392         #ifdef WOLFSSL_DTLS
08393             fragSz = min(length, maxFragment);
08394             sendSz += fragSz + DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
08395                       + HANDSHAKE_HEADER_SZ;
08396             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA
08397                       + HANDSHAKE_HEADER_SZ;
08398         #endif
08399         }
08400 
08401         /* check for available size */
08402         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
08403             return ret;
08404 
08405         /* get output buffer */
08406         output = ssl->buffers.outputBuffer.buffer +
08407                  ssl->buffers.outputBuffer.length;
08408 
08409         if (ssl->fragOffset == 0) {
08410             if (!ssl->options.dtls) {
08411                 AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
08412                 if (!IsEncryptionOn(ssl, 1))
08413                     HashOutputRaw(ssl, output + RECORD_HEADER_SZ,
08414                                   HANDSHAKE_HEADER_SZ);
08415             }
08416             else {
08417             #ifdef WOLFSSL_DTLS
08418                 AddHeaders(output, payloadSz, certificate, ssl);
08419                 if (!IsEncryptionOn(ssl, 1))
08420                     HashOutputRaw(ssl,
08421                                   output + RECORD_HEADER_SZ + DTLS_RECORD_EXTRA,
08422                                   HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA);
08423                 /* Adding the headers increments these, decrement them for
08424                  * actual message header. */
08425                 ssl->keys.dtls_sequence_number--;
08426                 ssl->keys.dtls_handshake_number--;
08427                 AddFragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
08428                 ssl->keys.dtls_handshake_number--;
08429             #endif /* WOLFSSL_DTLS */
08430             }
08431 
08432             /* list total */
08433             c32to24(listSz, output + i);
08434             if (!IsEncryptionOn(ssl, 1))
08435                 HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
08436             i += CERT_HEADER_SZ;
08437             length -= CERT_HEADER_SZ;
08438             fragSz -= CERT_HEADER_SZ;
08439             if (certSz) {
08440                 c32to24(certSz, output + i);
08441                 if (!IsEncryptionOn(ssl, 1))
08442                     HashOutputRaw(ssl, output + i, CERT_HEADER_SZ);
08443                 i += CERT_HEADER_SZ;
08444                 length -= CERT_HEADER_SZ;
08445                 fragSz -= CERT_HEADER_SZ;
08446 
08447                 if (!IsEncryptionOn(ssl, 1)) {
08448                     HashOutputRaw(ssl, ssl->buffers.certificate->buffer, certSz);
08449                     if (certChainSz)
08450                         HashOutputRaw(ssl, ssl->buffers.certChain->buffer,
08451                                       certChainSz);
08452                 }
08453             }
08454         }
08455         else {
08456             if (!ssl->options.dtls) {
08457                 AddRecordHeader(output, fragSz, handshake, ssl);
08458             }
08459             else {
08460             #ifdef WOLFSSL_DTLS
08461                 AddFragHeaders(output, fragSz, ssl->fragOffset + headerSz,
08462                                payloadSz, certificate, ssl);
08463                 ssl->keys.dtls_handshake_number--;
08464             #endif /* WOLFSSL_DTLS */
08465             }
08466         }
08467 
08468         /* member */
08469         if (certSz && ssl->fragOffset < certSz) {
08470             word32 copySz = min(certSz - ssl->fragOffset, fragSz);
08471             XMEMCPY(output + i,
08472                     ssl->buffers.certificate->buffer + ssl->fragOffset, copySz);
08473             i += copySz;
08474             ssl->fragOffset += copySz;
08475             length -= copySz;
08476             fragSz -= copySz;
08477         }
08478         if (certChainSz && fragSz) {
08479             word32 copySz = min(certChainSz + certSz - ssl->fragOffset, fragSz);
08480             XMEMCPY(output + i,
08481                     ssl->buffers.certChain->buffer + ssl->fragOffset - certSz,
08482                     copySz);
08483             i += copySz;
08484             ssl->fragOffset += copySz;
08485             length -= copySz;
08486         }
08487 
08488         if (IsEncryptionOn(ssl, 1)) {
08489             byte* input = NULL;
08490             int   inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
08491 
08492             if (inputSz < 0) {
08493                 WOLFSSL_MSG("Send Cert bad inputSz");
08494                 return BUFFER_E;
08495             }
08496 
08497             if (inputSz > 0) {  /* clang thinks could be zero, let's help */
08498                 input = (byte*)XMALLOC(inputSz, ssl->heap,
08499                                        DYNAMIC_TYPE_TMP_BUFFER);
08500                 if (input == NULL)
08501                     return MEMORY_E;
08502                 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
08503             }
08504 
08505             sendSz = BuildMessage(ssl, output,sendSz,input,inputSz,handshake,1);
08506             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
08507 
08508             if (sendSz < 0)
08509                 return sendSz;
08510         }
08511 
08512         #ifdef WOLFSSL_DTLS
08513             if (ssl->options.dtls) {
08514                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
08515                     return ret;
08516             }
08517         #endif
08518 
08519         #ifdef WOLFSSL_CALLBACKS
08520             if (ssl->hsInfoOn)
08521                 AddPacketName("Certificate", &ssl->handShakeInfo);
08522             if (ssl->toInfoOn)
08523                 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
08524                                ssl->heap);
08525         #endif
08526 
08527         ssl->buffers.outputBuffer.length += sendSz;
08528         if (!ssl->options.groupMessages)
08529             ret = SendBuffered(ssl);
08530     }
08531 
08532     if (ret != WANT_WRITE) {
08533         /* Clean up the fragment offset. */
08534         ssl->fragOffset = 0;
08535         #ifdef WOLFSSL_DTLS
08536         if (ssl->options.dtls)
08537             ssl->keys.dtls_handshake_number++;
08538         #endif
08539         if (ssl->options.side == WOLFSSL_SERVER_END)
08540             ssl->options.serverState = SERVER_CERT_COMPLETE;
08541     }
08542 
08543     return ret;
08544 }
08545 
08546 
08547 int SendCertificateRequest(WOLFSSL* ssl)
08548 {
08549     byte   *output;
08550     int    ret;
08551     int    sendSz;
08552     word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08553 
08554     int  typeTotal = 1;  /* only 1 for now */
08555     int  reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ;  /* add auth later */
08556 
08557     if (IsAtLeastTLSv1_2(ssl))
08558         reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
08559 
08560     if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
08561         return 0;  /* not needed */
08562 
08563     sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
08564 
08565     #ifdef WOLFSSL_DTLS
08566         if (ssl->options.dtls) {
08567             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08568             i      += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
08569         }
08570     #endif
08571     /* check for available size */
08572     if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
08573         return ret;
08574 
08575     /* get output buffer */
08576     output = ssl->buffers.outputBuffer.buffer +
08577              ssl->buffers.outputBuffer.length;
08578 
08579     AddHeaders(output, reqSz, certificate_request, ssl);
08580 
08581     /* write to output */
08582     output[i++] = (byte)typeTotal;  /* # of types */
08583 #ifdef HAVE_ECC
08584     if (ssl->options.cipherSuite0 == ECC_BYTE &&
08585                      ssl->specs.sig_algo == ecc_dsa_sa_algo) {
08586         output[i++] = ecdsa_sign;
08587     } else
08588 #endif /* HAVE_ECC */
08589     {
08590         output[i++] = rsa_sign;
08591     }
08592 
08593     /* supported hash/sig */
08594     if (IsAtLeastTLSv1_2(ssl)) {
08595         c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
08596         i += LENGTH_SZ;
08597 
08598         XMEMCPY(&output[i],
08599                          ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
08600         i += ssl->suites->hashSigAlgoSz;
08601     }
08602 
08603     c16toa(0, &output[i]);  /* auth's */
08604     /* if add more to output, adjust i
08605     i += REQ_HEADER_SZ; */
08606 
08607     #ifdef WOLFSSL_DTLS
08608         if (ssl->options.dtls) {
08609             if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
08610                 return ret;
08611         }
08612     #endif
08613 
08614     ret = HashOutput(ssl, output, sendSz, 0);
08615     if (ret != 0)
08616         return ret;
08617 
08618     #ifdef WOLFSSL_CALLBACKS
08619         if (ssl->hsInfoOn)
08620             AddPacketName("CertificateRequest", &ssl->handShakeInfo);
08621         if (ssl->toInfoOn)
08622             AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
08623                           sendSz, ssl->heap);
08624     #endif
08625     ssl->buffers.outputBuffer.length += sendSz;
08626     if (ssl->options.groupMessages)
08627         return 0;
08628     else
08629         return SendBuffered(ssl);
08630 }
08631 
08632 
08633 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
08634  || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
08635 static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
08636                                                                      byte count)
08637 {
08638     byte*  output  = NULL;
08639     word32 idx     = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
08640     word32 length  = ENUM_LEN;
08641     int    sendSz  = 0;
08642     int    ret     = 0;
08643     int    i       = 0;
08644 
08645     WOLFSSL_ENTER("BuildCertificateStatus");
08646 
08647     switch (type) {
08648         case WOLFSSL_CSR2_OCSP_MULTI:
08649             length += OPAQUE24_LEN;
08650             /* followed by */
08651 
08652         case WOLFSSL_CSR2_OCSP:
08653             for (i = 0; i < count; i++)
08654                 length += OPAQUE24_LEN + status[i].length;
08655         break;
08656 
08657         default:
08658             return 0;
08659     }
08660 
08661     sendSz = idx + length;
08662 
08663     if (ssl->keys.encryptionOn)
08664         sendSz += MAX_MSG_EXTRA;
08665 
08666     if ((ret = CheckAvailableSize(ssl, sendSz)) == 0) {
08667         output = ssl->buffers.outputBuffer.buffer +
08668                  ssl->buffers.outputBuffer.length;
08669 
08670         AddHeaders(output, length, certificate_status, ssl);
08671 
08672         output[idx++] = type;
08673 
08674         if (type == WOLFSSL_CSR2_OCSP_MULTI) {
08675             c32to24(length - (ENUM_LEN + OPAQUE24_LEN), output + idx);
08676             idx += OPAQUE24_LEN;
08677         }
08678 
08679         for (i = 0; i < count; i++) {
08680             c32to24(status[i].length, output + idx);
08681             idx += OPAQUE24_LEN;
08682 
08683             XMEMCPY(output + idx, status[i].buffer, status[i].length);
08684             idx += status[i].length;
08685         }
08686 
08687         if (IsEncryptionOn(ssl, 1)) {
08688             byte* input;
08689             int   inputSz = idx - RECORD_HEADER_SZ;
08690 
08691             input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
08692             if (input == NULL)
08693                 return MEMORY_E;
08694 
08695             XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
08696             sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
08697                                                                   handshake, 1);
08698             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
08699 
08700             if (sendSz < 0)
08701                 ret = sendSz;
08702         }
08703         else
08704             ret = HashOutput(ssl, output, sendSz, 0);
08705 
08706     #ifdef WOLFSSL_DTLS
08707         if (ret == 0 && ssl->options.dtls)
08708             ret = DtlsPoolSave(ssl, output, sendSz);
08709     #endif
08710 
08711     #ifdef WOLFSSL_CALLBACKS
08712         if (ret == 0 && ssl->hsInfoOn)
08713             AddPacketName("CertificateStatus", &ssl->handShakeInfo);
08714         if (ret == 0 && ssl->toInfoOn)
08715             AddPacketInfo("CertificateStatus", &ssl->timeoutInfo, output,
08716                                                              sendSz, ssl->heap);
08717     #endif
08718 
08719         if (ret == 0) {
08720             ssl->buffers.outputBuffer.length += sendSz;
08721             if (!ssl->options.groupMessages)
08722                 ret = SendBuffered(ssl);
08723         }
08724     }
08725 
08726     WOLFSSL_LEAVE("BuildCertificateStatus", ret);
08727     return ret;
08728 }
08729 #endif
08730 
08731 
08732 int SendCertificateStatus(WOLFSSL* ssl)
08733 {
08734     int ret = 0;
08735     byte status_type = 0;
08736 
08737     WOLFSSL_ENTER("SendCertificateStatus");
08738 
08739     (void) ssl;
08740 
08741     #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
08742         status_type = ssl->status_request;
08743     #endif
08744 
08745     #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
08746         status_type = status_type ? status_type : ssl->status_request_v2;
08747     #endif
08748 
08749     switch (status_type) {
08750 
08751     #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
08752      || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
08753         /* case WOLFSSL_CSR_OCSP: */
08754         case WOLFSSL_CSR2_OCSP: {
08755             OcspRequest* request = ssl->ctx->certOcspRequest;
08756             buffer response;
08757 
08758             XMEMSET(&response, 0, sizeof(response));
08759 
08760             /* unable to fetch status. skip. */
08761             if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
08762                 return 0;
08763 
08764             if (!request || ssl->buffers.weOwnCert) {
08765                 DerBuffer* der = ssl->buffers.certificate;
08766                 #ifdef WOLFSSL_SMALL_STACK
08767                     DecodedCert* cert = NULL;
08768                 #else
08769                     DecodedCert  cert[1];
08770                 #endif
08771 
08772                 /* unable to fetch status. skip. */
08773                 if (der->buffer == NULL || der->length == 0)
08774                     return 0;
08775 
08776                 #ifdef WOLFSSL_SMALL_STACK
08777                     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
08778                                                        DYNAMIC_TYPE_TMP_BUFFER);
08779                     if (cert == NULL)
08780                         return MEMORY_E;
08781                 #endif
08782 
08783                 InitDecodedCert(cert, der->buffer, der->length, NULL);
08784 
08785                 if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
08786                                                           ssl->ctx->cm)) != 0) {
08787                     WOLFSSL_MSG("ParseCert failed");
08788                 }
08789                 else {
08790                     request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
08791                                                      DYNAMIC_TYPE_OCSP_REQUEST);
08792                     if (request == NULL) {
08793                         FreeDecodedCert(cert);
08794 
08795                         #ifdef WOLFSSL_SMALL_STACK
08796                             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08797                         #endif
08798 
08799                         return MEMORY_E;
08800                     }
08801 
08802                     ret = InitOcspRequest(request, cert, 0);
08803                     if (ret != 0) {
08804                         XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08805                     }
08806                     else if (!ssl->buffers.weOwnCert && 0 == LockMutex(
08807                                       &ssl->ctx->cm->ocsp_stapling->ocspLock)) {
08808                         if (!ssl->ctx->certOcspRequest)
08809                             ssl->ctx->certOcspRequest = request;
08810                         UnLockMutex(&ssl->ctx->cm->ocsp_stapling->ocspLock);
08811                     }
08812                 }
08813 
08814                 FreeDecodedCert(cert);
08815 
08816                 #ifdef WOLFSSL_SMALL_STACK
08817                     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08818                 #endif
08819             }
08820 
08821             if (ret == 0) {
08822                 ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
08823                                                                      &response);
08824 
08825                 /* Suppressing, not critical */
08826                 if (ret == OCSP_CERT_REVOKED
08827                 ||  ret == OCSP_CERT_UNKNOWN
08828                 ||  ret == OCSP_LOOKUP_FAIL)
08829                     ret = 0;
08830 
08831                 if (response.buffer) {
08832                     if (ret == 0)
08833                         ret = BuildCertificateStatus(ssl, status_type,
08834                                                                   &response, 1);
08835 
08836                     XFREE(response.buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08837                 }
08838 
08839             }
08840 
08841             if (request != ssl->ctx->certOcspRequest)
08842                 XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08843         }
08844         break;
08845 
08846     #endif /* HAVE_CERTIFICATE_STATUS_REQUEST    */
08847            /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
08848 
08849     #if defined HAVE_CERTIFICATE_STATUS_REQUEST_V2
08850         case WOLFSSL_CSR2_OCSP_MULTI: {
08851             OcspRequest* request = ssl->ctx->certOcspRequest;
08852             buffer responses[1 + MAX_CHAIN_DEPTH];
08853             int i = 0;
08854 
08855             XMEMSET(responses, 0, sizeof(responses));
08856 
08857             /* unable to fetch status. skip. */
08858             if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
08859                 return 0;
08860 
08861             if (!request || ssl->buffers.weOwnCert) {
08862                 DerBuffer* der = ssl->buffers.certificate;
08863                 #ifdef WOLFSSL_SMALL_STACK
08864                     DecodedCert* cert = NULL;
08865                 #else
08866                     DecodedCert  cert[1];
08867                 #endif
08868 
08869                 /* unable to fetch status. skip. */
08870                 if (der->buffer == NULL || der->length == 0)
08871                     return 0;
08872 
08873                 #ifdef WOLFSSL_SMALL_STACK
08874                     cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
08875                                                    DYNAMIC_TYPE_TMP_BUFFER);
08876                     if (cert == NULL)
08877                         return MEMORY_E;
08878                 #endif
08879 
08880                 InitDecodedCert(cert, der->buffer, der->length, NULL);
08881 
08882                 if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
08883                                                           ssl->ctx->cm)) != 0) {
08884                     WOLFSSL_MSG("ParseCert failed");
08885                 }
08886                 else {
08887                     request = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
08888                                                      DYNAMIC_TYPE_OCSP_REQUEST);
08889                     if (request == NULL) {
08890                         FreeDecodedCert(cert);
08891 
08892                         #ifdef WOLFSSL_SMALL_STACK
08893                             XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08894                         #endif
08895 
08896                         return MEMORY_E;
08897                     }
08898 
08899                     ret = InitOcspRequest(request, cert, 0);
08900                     if (ret != 0) {
08901                         XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08902                     }
08903                     else if (!ssl->buffers.weOwnCert && 0 == LockMutex(
08904                                       &ssl->ctx->cm->ocsp_stapling->ocspLock)) {
08905                         if (!ssl->ctx->certOcspRequest)
08906                             ssl->ctx->certOcspRequest = request;
08907 
08908                         UnLockMutex(&ssl->ctx->cm->ocsp_stapling->ocspLock);
08909                     }
08910                 }
08911 
08912                 FreeDecodedCert(cert);
08913 
08914                 #ifdef WOLFSSL_SMALL_STACK
08915                     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
08916                 #endif
08917             }
08918 
08919             if (ret == 0) {
08920                 ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling, request,
08921                                                                  &responses[0]);
08922 
08923                 /* Suppressing, not critical */
08924                 if (ret == OCSP_CERT_REVOKED
08925                 ||  ret == OCSP_CERT_UNKNOWN
08926                 ||  ret == OCSP_LOOKUP_FAIL)
08927                     ret = 0;
08928             }
08929 
08930             if (request != ssl->ctx->certOcspRequest)
08931                 XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08932 
08933             if (ret == 0 && (!ssl->ctx->chainOcspRequest[0]
08934                                               || ssl->buffers.weOwnCertChain)) {
08935                 buffer der;
08936                 word32 idx = 0;
08937                 #ifdef WOLFSSL_SMALL_STACK
08938                     DecodedCert* cert = NULL;
08939                 #else
08940                     DecodedCert  cert[1];
08941                 #endif
08942 
08943                 XMEMSET(&der, 0, sizeof(buffer));
08944 
08945             #ifdef WOLFSSL_SMALL_STACK
08946                 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
08947                                                DYNAMIC_TYPE_TMP_BUFFER);
08948                 if (cert == NULL)
08949                     return MEMORY_E;
08950             #endif
08951 
08952                 while (idx + OPAQUE24_LEN < ssl->buffers.certChain->length) {
08953                     c24to32(ssl->buffers.certChain->buffer + idx, &der.length);
08954                     idx += OPAQUE24_LEN;
08955 
08956                     der.buffer = ssl->buffers.certChain->buffer + idx;
08957                     idx += der.length;
08958 
08959                     if (idx > ssl->buffers.certChain->length)
08960                         break;
08961 
08962                     InitDecodedCert(cert, der.buffer, der.length, NULL);
08963 
08964                     if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY,
08965                                                       ssl->ctx->cm)) != 0) {
08966                         WOLFSSL_MSG("ParseCert failed");
08967                         break;
08968                     }
08969                     else {
08970                         request = (OcspRequest*)XMALLOC(sizeof(OcspRequest),
08971                                            NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08972                         if (request == NULL) {
08973                             ret = MEMORY_E;
08974                             break;
08975                         }
08976 
08977                         ret = InitOcspRequest(request, cert, 0);
08978                         if (ret != 0) {
08979                             XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
08980                             break;
08981                         }
08982                         else if (!ssl->buffers.weOwnCertChain && 0 ==
08983                                  LockMutex(
08984                                   &ssl->ctx->cm->ocsp_stapling->ocspLock)) {
08985                             if (!ssl->ctx->chainOcspRequest[i])
08986                                 ssl->ctx->chainOcspRequest[i] = request;
08987 
08988                             UnLockMutex(
08989                                     &ssl->ctx->cm->ocsp_stapling->ocspLock);
08990                         }
08991 
08992                         ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
08993                                                     request, &responses[i + 1]);
08994 
08995                         /* Suppressing, not critical */
08996                         if (ret == OCSP_CERT_REVOKED
08997                         ||  ret == OCSP_CERT_UNKNOWN
08998                         ||  ret == OCSP_LOOKUP_FAIL)
08999                             ret = 0;
09000 
09001                         if (request != ssl->ctx->chainOcspRequest[i])
09002                             XFREE(request, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
09003 
09004                         i++;
09005                     }
09006 
09007                     FreeDecodedCert(cert);
09008                 }
09009 
09010                 #ifdef WOLFSSL_SMALL_STACK
09011                     XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
09012                 #endif
09013             }
09014             else {
09015                 while (ret == 0 &&
09016                             NULL != (request = ssl->ctx->chainOcspRequest[i])) {
09017                     ret = CheckOcspRequest(ssl->ctx->cm->ocsp_stapling,
09018                                                 request, &responses[++i]);
09019 
09020                     /* Suppressing, not critical */
09021                     if (ret == OCSP_CERT_REVOKED
09022                     ||  ret == OCSP_CERT_UNKNOWN
09023                     ||  ret == OCSP_LOOKUP_FAIL)
09024                         ret = 0;
09025                 }
09026             }
09027 
09028             if (responses[0].buffer) {
09029                 if (ret == 0)
09030                     ret = BuildCertificateStatus(ssl, status_type,
09031                                                               responses, i + 1);
09032 
09033                 for (i = 0; i < 1 + MAX_CHAIN_DEPTH; i++)
09034                     if (responses[i].buffer)
09035                         XFREE(responses[i].buffer, NULL,
09036                                                        DYNAMIC_TYPE_TMP_BUFFER);
09037             }
09038         }
09039         break;
09040 
09041     #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
09042 
09043         default:
09044         break;
09045     }
09046 
09047     return ret;
09048 }
09049 
09050 #endif /* !NO_CERTS */
09051 
09052 
09053 int SendData(WOLFSSL* ssl, const void* data, int sz)
09054 {
09055     int sent = 0,  /* plainText size */
09056         sendSz,
09057         ret,
09058         dtlsExtra = 0;
09059 
09060     if (ssl->error == WANT_WRITE)
09061         ssl->error = 0;
09062 
09063     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
09064         int err;
09065         WOLFSSL_MSG("handshake not complete, trying to finish");
09066         if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
09067             return  err;
09068     }
09069 
09070     /* last time system socket output buffer was full, try again to send */
09071     if (ssl->buffers.outputBuffer.length > 0) {
09072         WOLFSSL_MSG("output buffer was full, trying to send again");
09073         if ( (ssl->error = SendBuffered(ssl)) < 0) {
09074             WOLFSSL_ERROR(ssl->error);
09075             if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
09076                 return 0;     /* peer reset */
09077             return ssl->error;
09078         }
09079         else {
09080             /* advance sent to previous sent + plain size just sent */
09081             sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
09082             WOLFSSL_MSG("sent write buffered data");
09083 
09084             if (sent > sz) {
09085                 WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
09086                 return ssl->error = BAD_FUNC_ARG;
09087             }
09088         }
09089     }
09090 
09091 #ifdef WOLFSSL_DTLS
09092     if (ssl->options.dtls) {
09093         dtlsExtra = DTLS_RECORD_EXTRA;
09094     }
09095 #endif
09096 
09097     for (;;) {
09098 #ifdef HAVE_MAX_FRAGMENT
09099         int   len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
09100 #else
09101         int   len = min(sz - sent, OUTPUT_RECORD_SIZE);
09102 #endif
09103         byte* out;
09104         byte* sendBuffer = (byte*)data + sent;  /* may switch on comp */
09105         int   buffSz = len;                     /* may switch on comp */
09106         int   outputSz;
09107 #ifdef HAVE_LIBZ
09108         byte  comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
09109 #endif
09110 
09111         if (sent == sz) break;
09112 
09113 #ifdef WOLFSSL_DTLS
09114         if (ssl->options.dtls) {
09115             len    = min(len, MAX_UDP_SIZE);
09116             buffSz = len;
09117         }
09118 #endif
09119 
09120         /* check for available size */
09121         outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
09122         if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
09123             return ssl->error = ret;
09124 
09125         /* get output buffer */
09126         out = ssl->buffers.outputBuffer.buffer +
09127               ssl->buffers.outputBuffer.length;
09128 
09129 #ifdef HAVE_LIBZ
09130         if (ssl->options.usingCompression) {
09131             buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
09132             if (buffSz < 0) {
09133                 return buffSz;
09134             }
09135             sendBuffer = comp;
09136         }
09137 #endif
09138         sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
09139                               application_data, 0);
09140         if (sendSz < 0)
09141             return BUILD_MSG_ERROR;
09142 
09143         ssl->buffers.outputBuffer.length += sendSz;
09144 
09145         if ( (ret = SendBuffered(ssl)) < 0) {
09146             WOLFSSL_ERROR(ret);
09147             /* store for next call if WANT_WRITE or user embedSend() that
09148                doesn't present like WANT_WRITE */
09149             ssl->buffers.plainSz  = len;
09150             ssl->buffers.prevSent = sent;
09151             if (ret == SOCKET_ERROR_E && ssl->options.connReset)
09152                 return 0;  /* peer reset */
09153             return ssl->error = ret;
09154         }
09155 
09156         sent += len;
09157 
09158         /* only one message per attempt */
09159         if (ssl->options.partialWrite == 1) {
09160             WOLFSSL_MSG("Paritial Write on, only sending one record");
09161             break;
09162         }
09163     }
09164 
09165     return sent;
09166 }
09167 
09168 /* process input data */
09169 int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
09170 {
09171     int size;
09172 
09173     WOLFSSL_ENTER("ReceiveData()");
09174 
09175     if (ssl->error == WANT_READ)
09176         ssl->error = 0;
09177 
09178     if (ssl->error != 0 && ssl->error != WANT_WRITE) {
09179         WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
09180         return ssl->error;
09181     }
09182 
09183     if (ssl->options.handShakeState != HANDSHAKE_DONE) {
09184         int err;
09185         WOLFSSL_MSG("Handshake not complete, trying to finish");
09186         if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
09187             return  err;
09188     }
09189 
09190 #ifdef HAVE_SECURE_RENEGOTIATION
09191 startScr:
09192     if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
09193         int err;
09194         ssl->secure_renegotiation->startScr = 0;  /* only start once */
09195         WOLFSSL_MSG("Need to start scr, server requested");
09196         if ( (err = wolfSSL_Rehandshake(ssl)) != SSL_SUCCESS)
09197             return  err;
09198     }
09199 #endif
09200 
09201     while (ssl->buffers.clearOutputBuffer.length == 0) {
09202         if ( (ssl->error = ProcessReply(ssl)) < 0) {
09203             WOLFSSL_ERROR(ssl->error);
09204             if (ssl->error == ZERO_RETURN) {
09205                 WOLFSSL_MSG("Zero return, no more data coming");
09206                 return 0;         /* no more data coming */
09207             }
09208             if (ssl->error == SOCKET_ERROR_E) {
09209                 if (ssl->options.connReset || ssl->options.isClosed) {
09210                     WOLFSSL_MSG("Peer reset or closed, connection done");
09211                     ssl->error = SOCKET_PEER_CLOSED_E;
09212                     WOLFSSL_ERROR(ssl->error);
09213                     return 0;     /* peer reset or closed */
09214                 }
09215             }
09216             return ssl->error;
09217         }
09218         #ifdef HAVE_SECURE_RENEGOTIATION
09219             if (ssl->secure_renegotiation &&
09220                 ssl->secure_renegotiation->startScr) {
09221                 goto startScr;
09222             }
09223         #endif
09224     }
09225 
09226     if (sz < (int)ssl->buffers.clearOutputBuffer.length)
09227         size = sz;
09228     else
09229         size = ssl->buffers.clearOutputBuffer.length;
09230 
09231     XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
09232 
09233     if (peek == 0) {
09234         ssl->buffers.clearOutputBuffer.length -= size;
09235         ssl->buffers.clearOutputBuffer.buffer += size;
09236     }
09237 
09238     if (ssl->buffers.clearOutputBuffer.length == 0 &&
09239                                            ssl->buffers.inputBuffer.dynamicFlag)
09240        ShrinkInputBuffer(ssl, NO_FORCED_FREE);
09241 
09242     WOLFSSL_LEAVE("ReceiveData()", size);
09243     return size;
09244 }
09245 
09246 
09247 /* send alert message */
09248 int SendAlert(WOLFSSL* ssl, int severity, int type)
09249 {
09250     byte input[ALERT_SIZE];
09251     byte *output;
09252     int  sendSz;
09253     int  ret;
09254     int  outputSz;
09255     int  dtlsExtra = 0;
09256 
09257     /* if sendalert is called again for nonblocking */
09258     if (ssl->options.sendAlertState != 0) {
09259         ret = SendBuffered(ssl);
09260         if (ret == 0)
09261             ssl->options.sendAlertState = 0;
09262         return ret;
09263     }
09264 
09265    #ifdef WOLFSSL_DTLS
09266         if (ssl->options.dtls)
09267            dtlsExtra = DTLS_RECORD_EXTRA;
09268    #endif
09269 
09270     /* check for available size */
09271     outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
09272     if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
09273         return ret;
09274 
09275     /* get output buffer */
09276     output = ssl->buffers.outputBuffer.buffer +
09277              ssl->buffers.outputBuffer.length;
09278 
09279     input[0] = (byte)severity;
09280     input[1] = (byte)type;
09281     ssl->alert_history.last_tx.code = type;
09282     ssl->alert_history.last_tx.level = severity;
09283     if (severity == alert_fatal) {
09284         ssl->options.isClosed = 1;  /* Don't send close_notify */
09285     }
09286 
09287     /* only send encrypted alert if handshake actually complete, otherwise
09288        other side may not be able to handle it */
09289     if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
09290         sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE,alert,0);
09291     else {
09292 
09293         AddRecordHeader(output, ALERT_SIZE, alert, ssl);
09294         output += RECORD_HEADER_SZ;
09295         #ifdef WOLFSSL_DTLS
09296             if (ssl->options.dtls)
09297                 output += DTLS_RECORD_EXTRA;
09298         #endif
09299         XMEMCPY(output, input, ALERT_SIZE);
09300 
09301         sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
09302         #ifdef WOLFSSL_DTLS
09303             if (ssl->options.dtls)
09304                 sendSz += DTLS_RECORD_EXTRA;
09305         #endif
09306     }
09307     if (sendSz < 0)
09308         return BUILD_MSG_ERROR;
09309 
09310     #ifdef WOLFSSL_CALLBACKS
09311         if (ssl->hsInfoOn)
09312             AddPacketName("Alert", &ssl->handShakeInfo);
09313         if (ssl->toInfoOn)
09314             AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
09315     #endif
09316 
09317     ssl->buffers.outputBuffer.length += sendSz;
09318     ssl->options.sendAlertState = 1;
09319 
09320     return SendBuffered(ssl);
09321 }
09322 
09323 const char* wolfSSL_ERR_reason_error_string(unsigned long e)
09324 {
09325 #ifdef NO_ERROR_STRINGS
09326 
09327     (void)e;
09328     return "no support for error strings built in";
09329 
09330 #else
09331 
09332     int error = (int)e;
09333 
09334     /* pass to wolfCrypt */
09335     if (error < MAX_CODE_E && error > MIN_CODE_E) {
09336         return wc_GetErrorString(error);
09337     }
09338 
09339     switch (error) {
09340 
09341     case UNSUPPORTED_SUITE :
09342         return "unsupported cipher suite";
09343 
09344     case INPUT_CASE_ERROR :
09345         return "input state error";
09346 
09347     case PREFIX_ERROR :
09348         return "bad index to key rounds";
09349 
09350     case MEMORY_ERROR :
09351         return "out of memory";
09352 
09353     case VERIFY_FINISHED_ERROR :
09354         return "verify problem on finished";
09355 
09356     case VERIFY_MAC_ERROR :
09357         return "verify mac problem";
09358 
09359     case PARSE_ERROR :
09360         return "parse error on header";
09361 
09362     case SIDE_ERROR :
09363         return "wrong client/server type";
09364 
09365     case NO_PEER_CERT :
09366         return "peer didn't send cert";
09367 
09368     case UNKNOWN_HANDSHAKE_TYPE :
09369         return "weird handshake type";
09370 
09371     case SOCKET_ERROR_E :
09372         return "error state on socket";
09373 
09374     case SOCKET_NODATA :
09375         return "expected data, not there";
09376 
09377     case INCOMPLETE_DATA :
09378         return "don't have enough data to complete task";
09379 
09380     case UNKNOWN_RECORD_TYPE :
09381         return "unknown type in record hdr";
09382 
09383     case DECRYPT_ERROR :
09384         return "error during decryption";
09385 
09386     case FATAL_ERROR :
09387         return "revcd alert fatal error";
09388 
09389     case ENCRYPT_ERROR :
09390         return "error during encryption";
09391 
09392     case FREAD_ERROR :
09393         return "fread problem";
09394 
09395     case NO_PEER_KEY :
09396         return "need peer's key";
09397 
09398     case NO_PRIVATE_KEY :
09399         return "need the private key";
09400 
09401     case NO_DH_PARAMS :
09402         return "server missing DH params";
09403 
09404     case RSA_PRIVATE_ERROR :
09405         return "error during rsa priv op";
09406 
09407     case MATCH_SUITE_ERROR :
09408         return "can't match cipher suite";
09409 
09410     case BUILD_MSG_ERROR :
09411         return "build message failure";
09412 
09413     case BAD_HELLO :
09414         return "client hello malformed";
09415 
09416     case DOMAIN_NAME_MISMATCH :
09417         return "peer subject name mismatch";
09418 
09419     case WANT_READ :
09420     case SSL_ERROR_WANT_READ :
09421         return "non-blocking socket wants data to be read";
09422 
09423     case NOT_READY_ERROR :
09424         return "handshake layer not ready yet, complete first";
09425 
09426     case PMS_VERSION_ERROR :
09427         return "premaster secret version mismatch error";
09428 
09429     case VERSION_ERROR :
09430         return "record layer version error";
09431 
09432     case WANT_WRITE :
09433     case SSL_ERROR_WANT_WRITE :
09434         return "non-blocking socket write buffer full";
09435 
09436     case BUFFER_ERROR :
09437         return "malformed buffer input error";
09438 
09439     case VERIFY_CERT_ERROR :
09440         return "verify problem on certificate";
09441 
09442     case VERIFY_SIGN_ERROR :
09443         return "verify problem based on signature";
09444 
09445     case CLIENT_ID_ERROR :
09446         return "psk client identity error";
09447 
09448     case SERVER_HINT_ERROR:
09449         return "psk server hint error";
09450 
09451     case PSK_KEY_ERROR:
09452         return "psk key callback error";
09453 
09454     case NTRU_KEY_ERROR:
09455         return "NTRU key error";
09456 
09457     case NTRU_DRBG_ERROR:
09458         return "NTRU drbg error";
09459 
09460     case NTRU_ENCRYPT_ERROR:
09461         return "NTRU encrypt error";
09462 
09463     case NTRU_DECRYPT_ERROR:
09464         return "NTRU decrypt error";
09465 
09466     case ZLIB_INIT_ERROR:
09467         return "zlib init error";
09468 
09469     case ZLIB_COMPRESS_ERROR:
09470         return "zlib compress error";
09471 
09472     case ZLIB_DECOMPRESS_ERROR:
09473         return "zlib decompress error";
09474 
09475     case GETTIME_ERROR:
09476         return "gettimeofday() error";
09477 
09478     case GETITIMER_ERROR:
09479         return "getitimer() error";
09480 
09481     case SIGACT_ERROR:
09482         return "sigaction() error";
09483 
09484     case SETITIMER_ERROR:
09485         return "setitimer() error";
09486 
09487     case LENGTH_ERROR:
09488         return "record layer length error";
09489 
09490     case PEER_KEY_ERROR:
09491         return "cant decode peer key";
09492 
09493     case ZERO_RETURN:
09494     case SSL_ERROR_ZERO_RETURN:
09495         return "peer sent close notify alert";
09496 
09497     case ECC_CURVETYPE_ERROR:
09498         return "Bad ECC Curve Type or unsupported";
09499 
09500     case ECC_CURVE_ERROR:
09501         return "Bad ECC Curve or unsupported";
09502 
09503     case ECC_PEERKEY_ERROR:
09504         return "Bad ECC Peer Key";
09505 
09506     case ECC_MAKEKEY_ERROR:
09507         return "ECC Make Key failure";
09508 
09509     case ECC_EXPORT_ERROR:
09510         return "ECC Export Key failure";
09511 
09512     case ECC_SHARED_ERROR:
09513         return "ECC DHE shared failure";
09514 
09515     case NOT_CA_ERROR:
09516         return "Not a CA by basic constraint error";
09517 
09518     case BAD_PATH_ERROR:
09519         return "Bad path for opendir error";
09520 
09521     case BAD_CERT_MANAGER_ERROR:
09522         return "Bad Cert Manager error";
09523 
09524     case OCSP_CERT_REVOKED:
09525         return "OCSP Cert revoked";
09526 
09527     case CRL_CERT_REVOKED:
09528         return "CRL Cert revoked";
09529 
09530     case CRL_MISSING:
09531         return "CRL missing, not loaded";
09532 
09533     case MONITOR_SETUP_E:
09534         return "CRL monitor setup error";
09535 
09536     case THREAD_CREATE_E:
09537         return "Thread creation problem";
09538 
09539     case OCSP_NEED_URL:
09540         return "OCSP need URL";
09541 
09542     case OCSP_CERT_UNKNOWN:
09543         return "OCSP Cert unknown";
09544 
09545     case OCSP_LOOKUP_FAIL:
09546         return "OCSP Responder lookup fail";
09547 
09548     case MAX_CHAIN_ERROR:
09549         return "Maximum Chain Depth Exceeded";
09550 
09551     case COOKIE_ERROR:
09552         return "DTLS Cookie Error";
09553 
09554     case SEQUENCE_ERROR:
09555         return "DTLS Sequence Error";
09556 
09557     case SUITES_ERROR:
09558         return "Suites Pointer Error";
09559 
09560     case SSL_NO_PEM_HEADER:
09561         return "No PEM Header Error";
09562 
09563     case OUT_OF_ORDER_E:
09564         return "Out of order message, fatal";
09565 
09566     case BAD_KEA_TYPE_E:
09567         return "Bad KEA type found";
09568 
09569     case SANITY_CIPHER_E:
09570         return "Sanity check on ciphertext failed";
09571 
09572     case RECV_OVERFLOW_E:
09573         return "Receive callback returned more than requested";
09574 
09575     case GEN_COOKIE_E:
09576         return "Generate Cookie Error";
09577 
09578     case NO_PEER_VERIFY:
09579         return "Need peer certificate verify Error";
09580 
09581     case FWRITE_ERROR:
09582         return "fwrite Error";
09583 
09584     case CACHE_MATCH_ERROR:
09585         return "Cache restore header match Error";
09586 
09587     case UNKNOWN_SNI_HOST_NAME_E:
09588         return "Unrecognized host name Error";
09589 
09590     case UNKNOWN_MAX_FRAG_LEN_E:
09591         return "Unrecognized max frag len Error";
09592 
09593     case KEYUSE_SIGNATURE_E:
09594         return "Key Use digitalSignature not set Error";
09595 
09596     case KEYUSE_ENCIPHER_E:
09597         return "Key Use keyEncipherment not set Error";
09598 
09599     case EXTKEYUSE_AUTH_E:
09600         return "Ext Key Use server/client auth not set Error";
09601 
09602     case SEND_OOB_READ_E:
09603         return "Send Callback Out of Bounds Read Error";
09604 
09605     case SECURE_RENEGOTIATION_E:
09606         return "Invalid Renegotiation Error";
09607 
09608     case SESSION_TICKET_LEN_E:
09609         return "Session Ticket Too Long Error";
09610 
09611     case SESSION_TICKET_EXPECT_E:
09612         return "Session Ticket Error";
09613 
09614     case SCR_DIFFERENT_CERT_E:
09615         return "Peer sent different cert during SCR";
09616 
09617     case SESSION_SECRET_CB_E:
09618         return "Session Secret Callback Error";
09619 
09620     case NO_CHANGE_CIPHER_E:
09621         return "Finished received from peer before Change Cipher Error";
09622 
09623     case SANITY_MSG_E:
09624         return "Sanity Check on message order Error";
09625 
09626     case DUPLICATE_MSG_E:
09627         return "Duplicate HandShake message Error";
09628 
09629     case SNI_UNSUPPORTED:
09630         return "Protocol version does not support SNI Error";
09631 
09632     case SOCKET_PEER_CLOSED_E:
09633         return "Peer closed underlying transport Error";
09634 
09635     case BAD_TICKET_KEY_CB_SZ:
09636         return "Bad user session ticket key callback Size Error";
09637 
09638     case BAD_TICKET_MSG_SZ:
09639         return "Bad session ticket message Size Error";
09640 
09641     case BAD_TICKET_ENCRYPT:
09642         return "Bad user ticket callback encrypt Error";
09643 
09644     case DH_KEY_SIZE_E:
09645         return "DH key too small Error";
09646 
09647     case SNI_ABSENT_ERROR:
09648         return "No Server Name Indication extension Error";
09649 
09650     case RSA_SIGN_FAULT:
09651         return "RSA Signature Fault Error";
09652 
09653     case HANDSHAKE_SIZE_ERROR:
09654         return "Handshake message too large Error";
09655 
09656     case UNKNOWN_ALPN_PROTOCOL_NAME_E:
09657         return "Unrecognized protocol name Error";
09658 
09659     case BAD_CERTIFICATE_STATUS_ERROR:
09660         return "Bad Certificate Status Message Error";
09661 
09662     case OCSP_INVALID_STATUS:
09663         return "Invalid OCSP Status Error";
09664 
09665     default :
09666         return "unknown error number";
09667     }
09668 
09669 #endif /* NO_ERROR_STRINGS */
09670 }
09671 
09672 void SetErrorString(int error, char* str)
09673 {
09674     XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ);
09675 }
09676 
09677 
09678 /* be sure to add to cipher_name_idx too !!!! */
09679 static const char* const cipher_names[] =
09680 {
09681 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
09682     "RC4-SHA",
09683 #endif
09684 
09685 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
09686     "RC4-MD5",
09687 #endif
09688 
09689 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
09690     "DES-CBC3-SHA",
09691 #endif
09692 
09693 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
09694     "AES128-SHA",
09695 #endif
09696 
09697 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
09698     "AES256-SHA",
09699 #endif
09700 
09701 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
09702     "NULL-SHA",
09703 #endif
09704 
09705 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
09706     "NULL-SHA256",
09707 #endif
09708 
09709 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
09710     "DHE-RSA-AES128-SHA",
09711 #endif
09712 
09713 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
09714     "DHE-RSA-AES256-SHA",
09715 #endif
09716 
09717 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
09718     "DHE-PSK-AES256-GCM-SHA384",
09719 #endif
09720 
09721 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
09722     "DHE-PSK-AES128-GCM-SHA256",
09723 #endif
09724 
09725 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
09726     "PSK-AES256-GCM-SHA384",
09727 #endif
09728 
09729 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
09730     "PSK-AES128-GCM-SHA256",
09731 #endif
09732 
09733 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
09734     "DHE-PSK-AES256-CBC-SHA384",
09735 #endif
09736 
09737 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
09738     "DHE-PSK-AES128-CBC-SHA256",
09739 #endif
09740 
09741 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
09742     "PSK-AES256-CBC-SHA384",
09743 #endif
09744 
09745 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
09746     "PSK-AES128-CBC-SHA256",
09747 #endif
09748 
09749 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
09750     "PSK-AES128-CBC-SHA",
09751 #endif
09752 
09753 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
09754     "PSK-AES256-CBC-SHA",
09755 #endif
09756 
09757 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
09758     "DHE-PSK-AES128-CCM",
09759 #endif
09760 
09761 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
09762     "DHE-PSK-AES256-CCM",
09763 #endif
09764 
09765 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
09766     "PSK-AES128-CCM",
09767 #endif
09768 
09769 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
09770     "PSK-AES256-CCM",
09771 #endif
09772 
09773 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
09774     "PSK-AES128-CCM-8",
09775 #endif
09776 
09777 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
09778     "PSK-AES256-CCM-8",
09779 #endif
09780 
09781 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
09782     "DHE-PSK-NULL-SHA384",
09783 #endif
09784 
09785 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
09786     "DHE-PSK-NULL-SHA256",
09787 #endif
09788 
09789 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
09790     "PSK-NULL-SHA384",
09791 #endif
09792 
09793 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
09794     "PSK-NULL-SHA256",
09795 #endif
09796 
09797 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
09798     "PSK-NULL-SHA",
09799 #endif
09800 
09801 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
09802     "HC128-MD5",
09803 #endif
09804 
09805 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
09806     "HC128-SHA",
09807 #endif
09808 
09809 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
09810     "HC128-B2B256",
09811 #endif
09812 
09813 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
09814     "AES128-B2B256",
09815 #endif
09816 
09817 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
09818     "AES256-B2B256",
09819 #endif
09820 
09821 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
09822     "RABBIT-SHA",
09823 #endif
09824 
09825 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
09826     "NTRU-RC4-SHA",
09827 #endif
09828 
09829 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
09830     "NTRU-DES-CBC3-SHA",
09831 #endif
09832 
09833 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
09834     "NTRU-AES128-SHA",
09835 #endif
09836 
09837 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
09838     "NTRU-AES256-SHA",
09839 #endif
09840 
09841 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
09842     "AES128-CCM-8",
09843 #endif
09844 
09845 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
09846     "AES256-CCM-8",
09847 #endif
09848 
09849 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
09850     "ECDHE-ECDSA-AES128-CCM-8",
09851 #endif
09852 
09853 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
09854     "ECDHE-ECDSA-AES256-CCM-8",
09855 #endif
09856 
09857 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
09858     "ECDHE-RSA-AES128-SHA",
09859 #endif
09860 
09861 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
09862     "ECDHE-RSA-AES256-SHA",
09863 #endif
09864 
09865 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
09866     "ECDHE-ECDSA-AES128-SHA",
09867 #endif
09868 
09869 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
09870     "ECDHE-ECDSA-AES256-SHA",
09871 #endif
09872 
09873 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
09874     "ECDHE-RSA-RC4-SHA",
09875 #endif
09876 
09877 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
09878     "ECDHE-RSA-DES-CBC3-SHA",
09879 #endif
09880 
09881 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
09882     "ECDHE-ECDSA-RC4-SHA",
09883 #endif
09884 
09885 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
09886     "ECDHE-ECDSA-DES-CBC3-SHA",
09887 #endif
09888 
09889 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
09890     "AES128-SHA256",
09891 #endif
09892 
09893 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
09894     "AES256-SHA256",
09895 #endif
09896 
09897 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
09898     "DHE-RSA-AES128-SHA256",
09899 #endif
09900 
09901 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
09902     "DHE-RSA-AES256-SHA256",
09903 #endif
09904 
09905 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
09906     "ECDH-RSA-AES128-SHA",
09907 #endif
09908 
09909 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
09910     "ECDH-RSA-AES256-SHA",
09911 #endif
09912 
09913 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
09914     "ECDH-ECDSA-AES128-SHA",
09915 #endif
09916 
09917 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
09918     "ECDH-ECDSA-AES256-SHA",
09919 #endif
09920 
09921 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
09922     "ECDH-RSA-RC4-SHA",
09923 #endif
09924 
09925 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
09926     "ECDH-RSA-DES-CBC3-SHA",
09927 #endif
09928 
09929 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
09930     "ECDH-ECDSA-RC4-SHA",
09931 #endif
09932 
09933 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
09934     "ECDH-ECDSA-DES-CBC3-SHA",
09935 #endif
09936 
09937 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
09938     "AES128-GCM-SHA256",
09939 #endif
09940 
09941 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
09942     "AES256-GCM-SHA384",
09943 #endif
09944 
09945 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
09946     "DHE-RSA-AES128-GCM-SHA256",
09947 #endif
09948 
09949 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
09950     "DHE-RSA-AES256-GCM-SHA384",
09951 #endif
09952 
09953 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
09954     "ECDHE-RSA-AES128-GCM-SHA256",
09955 #endif
09956 
09957 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
09958     "ECDHE-RSA-AES256-GCM-SHA384",
09959 #endif
09960 
09961 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
09962     "ECDHE-ECDSA-AES128-GCM-SHA256",
09963 #endif
09964 
09965 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
09966     "ECDHE-ECDSA-AES256-GCM-SHA384",
09967 #endif
09968 
09969 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
09970     "ECDH-RSA-AES128-GCM-SHA256",
09971 #endif
09972 
09973 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
09974     "ECDH-RSA-AES256-GCM-SHA384",
09975 #endif
09976 
09977 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
09978     "ECDH-ECDSA-AES128-GCM-SHA256",
09979 #endif
09980 
09981 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
09982     "ECDH-ECDSA-AES256-GCM-SHA384",
09983 #endif
09984 
09985 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
09986     "CAMELLIA128-SHA",
09987 #endif
09988 
09989 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
09990     "DHE-RSA-CAMELLIA128-SHA",
09991 #endif
09992 
09993 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
09994     "CAMELLIA256-SHA",
09995 #endif
09996 
09997 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
09998     "DHE-RSA-CAMELLIA256-SHA",
09999 #endif
10000 
10001 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
10002     "CAMELLIA128-SHA256",
10003 #endif
10004 
10005 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
10006     "DHE-RSA-CAMELLIA128-SHA256",
10007 #endif
10008 
10009 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
10010     "CAMELLIA256-SHA256",
10011 #endif
10012 
10013 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
10014     "DHE-RSA-CAMELLIA256-SHA256",
10015 #endif
10016 
10017 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
10018     "ECDHE-RSA-AES128-SHA256",
10019 #endif
10020 
10021 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
10022     "ECDHE-ECDSA-AES128-SHA256",
10023 #endif
10024 
10025 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
10026     "ECDH-RSA-AES128-SHA256",
10027 #endif
10028 
10029 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
10030     "ECDH-ECDSA-AES128-SHA256",
10031 #endif
10032 
10033 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
10034     "ECDHE-RSA-AES256-SHA384",
10035 #endif
10036 
10037 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
10038     "ECDHE-ECDSA-AES256-SHA384",
10039 #endif
10040 
10041 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
10042     "ECDH-RSA-AES256-SHA384",
10043 #endif
10044 
10045 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
10046     "ECDH-ECDSA-AES256-SHA384",
10047 #endif
10048 
10049 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
10050     "ECDHE-RSA-CHACHA20-POLY1305",
10051 #endif
10052 
10053 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
10054     "ECDHE-ECDSA-CHACHA20-POLY1305",
10055 #endif
10056 
10057 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
10058     "DHE-RSA-CHACHA20-POLY1305",
10059 #endif
10060 
10061 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10062     "ECDHE-RSA-CHACHA20-POLY1305-OLD",
10063 #endif
10064 
10065 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10066     "ECDHE-ECDSA-CHACHA20-POLY1305-OLD",
10067 #endif
10068 
10069 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10070     "DHE-RSA-CHACHA20-POLY1305-OLD",
10071 #endif
10072 
10073 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
10074     "ADH-AES128-SHA",
10075 #endif
10076 
10077 #ifdef BUILD_TLS_QSH
10078     "QSH",
10079 #endif
10080 
10081 #ifdef HAVE_RENEGOTIATION_INDICATION
10082     "RENEGOTIATION-INFO",
10083 #endif
10084 
10085 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
10086     "IDEA-CBC-SHA",
10087 #endif
10088 
10089 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
10090     "ECDHE-ECDSA-NULL-SHA",
10091 #endif
10092 
10093 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
10094     "ECDHE-PSK-NULL-SHA256",
10095 #endif
10096 
10097 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
10098     "ECDHE-PSK-AES128-CBC-SHA256",
10099 #endif
10100 
10101 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
10102     "PSK-CHACHA20-POLY1305",
10103 #endif
10104 
10105 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
10106     "ECDHE-PSK-CHACHA20-POLY1305",
10107 #endif
10108 
10109 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
10110     "DHE-PSK-CHACHA20-POLY1305",
10111 #endif
10112 };
10113 
10114 
10115 /* cipher suite number that matches above name table */
10116 static int cipher_name_idx[] =
10117 {
10118 
10119 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
10120     SSL_RSA_WITH_RC4_128_SHA,
10121 #endif
10122 
10123 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
10124     SSL_RSA_WITH_RC4_128_MD5,
10125 #endif
10126 
10127 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
10128     SSL_RSA_WITH_3DES_EDE_CBC_SHA,
10129 #endif
10130 
10131 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
10132     TLS_RSA_WITH_AES_128_CBC_SHA,
10133 #endif
10134 
10135 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
10136     TLS_RSA_WITH_AES_256_CBC_SHA,
10137 #endif
10138 
10139 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
10140     TLS_RSA_WITH_NULL_SHA,
10141 #endif
10142 
10143 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
10144     TLS_RSA_WITH_NULL_SHA256,
10145 #endif
10146 
10147 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
10148     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
10149 #endif
10150 
10151 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
10152     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
10153 #endif
10154 
10155 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
10156     TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
10157 #endif
10158 
10159 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
10160     TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
10161 #endif
10162 
10163 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
10164     TLS_PSK_WITH_AES_256_GCM_SHA384,
10165 #endif
10166 
10167 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
10168     TLS_PSK_WITH_AES_128_GCM_SHA256,
10169 #endif
10170 
10171 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
10172     TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
10173 #endif
10174 
10175 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
10176     TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
10177 #endif
10178 
10179 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
10180     TLS_PSK_WITH_AES_256_CBC_SHA384,
10181 #endif
10182 
10183 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
10184     TLS_PSK_WITH_AES_128_CBC_SHA256,
10185 #endif
10186 
10187 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
10188     TLS_PSK_WITH_AES_128_CBC_SHA,
10189 #endif
10190 
10191 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
10192     TLS_PSK_WITH_AES_256_CBC_SHA,
10193 #endif
10194 
10195 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
10196     TLS_DHE_PSK_WITH_AES_128_CCM,
10197 #endif
10198 
10199 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
10200     TLS_DHE_PSK_WITH_AES_256_CCM,
10201 #endif
10202 
10203 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
10204     TLS_PSK_WITH_AES_128_CCM,
10205 #endif
10206 
10207 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
10208     TLS_PSK_WITH_AES_256_CCM,
10209 #endif
10210 
10211 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
10212     TLS_PSK_WITH_AES_128_CCM_8,
10213 #endif
10214 
10215 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
10216     TLS_PSK_WITH_AES_256_CCM_8,
10217 #endif
10218 
10219 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
10220     TLS_DHE_PSK_WITH_NULL_SHA384,
10221 #endif
10222 
10223 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
10224     TLS_DHE_PSK_WITH_NULL_SHA256,
10225 #endif
10226 
10227 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
10228     TLS_PSK_WITH_NULL_SHA384,
10229 #endif
10230 
10231 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
10232     TLS_PSK_WITH_NULL_SHA256,
10233 #endif
10234 
10235 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
10236     TLS_PSK_WITH_NULL_SHA,
10237 #endif
10238 
10239 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
10240     TLS_RSA_WITH_HC_128_MD5,
10241 #endif
10242 
10243 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
10244     TLS_RSA_WITH_HC_128_SHA,
10245 #endif
10246 
10247 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
10248     TLS_RSA_WITH_HC_128_B2B256,
10249 #endif
10250 
10251 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
10252     TLS_RSA_WITH_AES_128_CBC_B2B256,
10253 #endif
10254 
10255 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
10256     TLS_RSA_WITH_AES_256_CBC_B2B256,
10257 #endif
10258 
10259 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
10260     TLS_RSA_WITH_RABBIT_SHA,
10261 #endif
10262 
10263 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
10264     TLS_NTRU_RSA_WITH_RC4_128_SHA,
10265 #endif
10266 
10267 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
10268     TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
10269 #endif
10270 
10271 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
10272     TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
10273 #endif
10274 
10275 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
10276     TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
10277 #endif
10278 
10279 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
10280     TLS_RSA_WITH_AES_128_CCM_8,
10281 #endif
10282 
10283 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
10284     TLS_RSA_WITH_AES_256_CCM_8,
10285 #endif
10286 
10287 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
10288     TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
10289 #endif
10290 
10291 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
10292     TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
10293 #endif
10294 
10295 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
10296     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
10297 #endif
10298 
10299 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
10300     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
10301 #endif
10302 
10303 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
10304     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
10305 #endif
10306 
10307 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
10308     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
10309 #endif
10310 
10311 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
10312     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
10313 #endif
10314 
10315 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
10316     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
10317 #endif
10318 
10319 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
10320     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
10321 #endif
10322 
10323 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
10324     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
10325 #endif
10326 
10327 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
10328     TLS_RSA_WITH_AES_128_CBC_SHA256,
10329 #endif
10330 
10331 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
10332     TLS_RSA_WITH_AES_256_CBC_SHA256,
10333 #endif
10334 
10335 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
10336     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
10337 #endif
10338 
10339 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
10340     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
10341 #endif
10342 
10343 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
10344     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
10345 #endif
10346 
10347 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
10348     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
10349 #endif
10350 
10351 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
10352     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
10353 #endif
10354 
10355 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
10356     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
10357 #endif
10358 
10359 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
10360     TLS_ECDH_RSA_WITH_RC4_128_SHA,
10361 #endif
10362 
10363 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
10364     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
10365 #endif
10366 
10367 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
10368     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
10369 #endif
10370 
10371 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
10372     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
10373 #endif
10374 
10375 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
10376     TLS_RSA_WITH_AES_128_GCM_SHA256,
10377 #endif
10378 
10379 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
10380     TLS_RSA_WITH_AES_256_GCM_SHA384,
10381 #endif
10382 
10383 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
10384     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
10385 #endif
10386 
10387 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
10388     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
10389 #endif
10390 
10391 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
10392     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
10393 #endif
10394 
10395 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
10396     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
10397 #endif
10398 
10399 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
10400     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
10401 #endif
10402 
10403 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
10404     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
10405 #endif
10406 
10407 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
10408     TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
10409 #endif
10410 
10411 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
10412     TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
10413 #endif
10414 
10415 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
10416     TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
10417 #endif
10418 
10419 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
10420     TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
10421 #endif
10422 
10423 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
10424     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
10425 #endif
10426 
10427 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
10428     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
10429 #endif
10430 
10431 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
10432     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
10433 #endif
10434 
10435 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
10436     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
10437 #endif
10438 
10439 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
10440     TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
10441 #endif
10442 
10443 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
10444     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
10445 #endif
10446 
10447 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
10448     TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
10449 #endif
10450 
10451 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
10452     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
10453 #endif
10454 
10455 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
10456     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
10457 #endif
10458 
10459 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
10460     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
10461 #endif
10462 
10463 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
10464     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
10465 #endif
10466 
10467 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
10468     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
10469 #endif
10470 
10471 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
10472     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
10473 #endif
10474 
10475 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
10476     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
10477 #endif
10478 
10479 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
10480     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
10481 #endif
10482 
10483 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
10484     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
10485 #endif
10486 
10487 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
10488     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
10489 #endif
10490 
10491 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
10492     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
10493 #endif
10494 
10495 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
10496     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
10497 #endif
10498 
10499 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10500     TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
10501 #endif
10502 
10503 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10504     TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
10505 #endif
10506 
10507 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256
10508     TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256,
10509 #endif
10510 
10511 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
10512     TLS_DH_anon_WITH_AES_128_CBC_SHA,
10513 #endif
10514 
10515 #ifdef BUILD_TLS_QSH
10516     TLS_QSH,
10517 #endif
10518 
10519 #ifdef HAVE_RENEGOTIATION_INDICATION
10520     TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
10521 #endif
10522 
10523 #ifdef BUILD_SSL_RSA_WITH_IDEA_CBC_SHA
10524     SSL_RSA_WITH_IDEA_CBC_SHA,
10525 #endif
10526 
10527 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA
10528     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
10529 #endif
10530 
10531 #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256
10532     TLS_ECDHE_PSK_WITH_NULL_SHA256,
10533 #endif
10534 
10535 #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
10536     TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
10537 #endif
10538 
10539 #ifdef BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256
10540     TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
10541 #endif
10542 
10543 #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
10544     TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
10545 #endif
10546 
10547 #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
10548     TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
10549 #endif
10550 };
10551 
10552 
10553 /* returns the cipher_names array */
10554 const char* const* GetCipherNames(void)
10555 {
10556     return cipher_names;
10557 }
10558 
10559 
10560 /* returns the size of the cipher_names array */
10561 int GetCipherNamesSize(void)
10562 {
10563     return (int)(sizeof(cipher_names) / sizeof(char*));
10564 }
10565 
10566 
10567 /**
10568 Set the enabled cipher suites.
10569 
10570 @param [out] suites Suites structure.
10571 @param [in]  list   List of cipher suites, only supports full name from
10572                     cipher_name[] delimited by ':'.
10573 
10574 @return true on success, else false.
10575 */
10576 int SetCipherList(Suites* suites, const char* list)
10577 {
10578     int       ret          = 0;
10579     int       idx          = 0;
10580     int       haveRSAsig   = 0;
10581     int       haveECDSAsig = 0;
10582     int       haveAnon     = 0;
10583     const int suiteSz      = GetCipherNamesSize();
10584     char*     next         = (char*)list;
10585 
10586     if (suites == NULL || list == NULL) {
10587         WOLFSSL_MSG("SetCipherList parameter error");
10588         return 0;
10589     }
10590 
10591     if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
10592         return 1; /* wolfSSL defualt */
10593 
10594     do {
10595         char*  current = next;
10596         char   name[MAX_SUITE_NAME + 1];
10597         int    i;
10598         word32 length;
10599 
10600         next   = XSTRSTR(next, ":");
10601         length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
10602                                          : (word32)(next - current));
10603 
10604         XSTRNCPY(name, current, length);
10605         name[(length == sizeof(name)) ? length - 1 : length] = 0;
10606 
10607         for (i = 0; i < suiteSz; i++) {
10608             if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
10609                 suites->suites[idx++] = (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
10610                                       : (XSTRSTR(name, "QSH"))    ? QSH_BYTE
10611                                       : (XSTRSTR(name, "EC"))     ? ECC_BYTE
10612                                       : (XSTRSTR(name, "CCM"))    ? ECC_BYTE
10613                                       : 0x00; /* normal */
10614 
10615                 suites->suites[idx++] = (byte)cipher_name_idx[i];
10616 
10617                 /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
10618                  * suites don't necessarily have RSA in the name. */
10619                 if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
10620                     haveECDSAsig = 1;
10621                 else if (XSTRSTR(name, "ADH"))
10622                     haveAnon = 1;
10623                 else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
10624                     haveRSAsig = 1;
10625 
10626                 ret = 1; /* found at least one */
10627                 break;
10628             }
10629         }
10630     }
10631     while (next++); /* ++ needed to skip ':' */
10632 
10633     if (ret) {
10634         suites->setSuites = 1;
10635         suites->suiteSz   = (word16)idx;
10636         InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
10637     }
10638 
10639     return ret;
10640 }
10641 
10642 #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS)
10643 static void PickHashSigAlgo(WOLFSSL* ssl,
10644                              const byte* hashSigAlgo, word32 hashSigAlgoSz)
10645 {
10646     word32 i;
10647 
10648     ssl->suites->sigAlgo = ssl->specs.sig_algo;
10649     ssl->suites->hashAlgo = sha_mac;
10650 
10651     /* i+1 since peek a byte ahead for type */
10652     for (i = 0; (i+1) < hashSigAlgoSz; i += 2) {
10653         if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
10654             if (hashSigAlgo[i] == sha_mac) {
10655                 break;
10656             }
10657             #ifndef NO_SHA256
10658             else if (hashSigAlgo[i] == sha256_mac) {
10659                 ssl->suites->hashAlgo = sha256_mac;
10660                 break;
10661             }
10662             #endif
10663             #ifdef WOLFSSL_SHA384
10664             else if (hashSigAlgo[i] == sha384_mac) {
10665                 ssl->suites->hashAlgo = sha384_mac;
10666                 break;
10667             }
10668             #endif
10669             #ifdef WOLFSSL_SHA512
10670             else if (hashSigAlgo[i] == sha512_mac) {
10671                 ssl->suites->hashAlgo = sha512_mac;
10672                 break;
10673             }
10674             #endif
10675         }
10676     }
10677 }
10678 #endif /* !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) */
10679 
10680 #ifdef WOLFSSL_CALLBACKS
10681 
10682     /* Initialisze HandShakeInfo */
10683     void InitHandShakeInfo(HandShakeInfo* info)
10684     {
10685         int i;
10686 
10687         info->cipherName[0] = 0;
10688         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
10689             info->packetNames[i][0] = 0;
10690         info->numberPackets = 0;
10691         info->negotiationError = 0;
10692     }
10693 
10694     /* Set Final HandShakeInfo parameters */
10695     void FinishHandShakeInfo(HandShakeInfo* info, const WOLFSSL* ssl)
10696     {
10697         int i;
10698         int sz = sizeof(cipher_name_idx)/sizeof(int);
10699 
10700         for (i = 0; i < sz; i++)
10701             if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
10702                 if (ssl->options.cipherSuite0 == ECC_BYTE)
10703                     continue;   /* ECC suites at end */
10704                 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
10705                 break;
10706             }
10707 
10708         /* error max and min are negative numbers */
10709         if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
10710             info->negotiationError = ssl->error;
10711     }
10712 
10713 
10714     /* Add name to info packet names, increase packet name count */
10715     void AddPacketName(const char* name, HandShakeInfo* info)
10716     {
10717         if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
10718             XSTRNCPY(info->packetNames[info->numberPackets++], name,
10719                     MAX_PACKETNAME_SZ);
10720         }
10721     }
10722 
10723 
10724     /* Initialisze TimeoutInfo */
10725     void InitTimeoutInfo(TimeoutInfo* info)
10726     {
10727         int i;
10728 
10729         info->timeoutName[0] = 0;
10730         info->flags          = 0;
10731 
10732         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
10733             info->packets[i].packetName[0]     = 0;
10734             info->packets[i].timestamp.tv_sec  = 0;
10735             info->packets[i].timestamp.tv_usec = 0;
10736             info->packets[i].bufferValue       = 0;
10737             info->packets[i].valueSz           = 0;
10738         }
10739         info->numberPackets        = 0;
10740         info->timeoutValue.tv_sec  = 0;
10741         info->timeoutValue.tv_usec = 0;
10742     }
10743 
10744 
10745     /* Free TimeoutInfo */
10746     void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
10747     {
10748         int i;
10749         (void)heap;
10750         for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
10751             if (info->packets[i].bufferValue) {
10752                 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
10753                 info->packets[i].bufferValue = 0;
10754             }
10755 
10756     }
10757 
10758 
10759     /* Add PacketInfo to TimeoutInfo */
10760     void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
10761                        int sz, void* heap)
10762     {
10763         if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
10764             Timeval currTime;
10765 
10766             /* may add name after */
10767             if (name)
10768                 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
10769                         MAX_PACKETNAME_SZ);
10770 
10771             /* add data, put in buffer if bigger than static buffer */
10772             info->packets[info->numberPackets].valueSz = sz;
10773             if (sz < MAX_VALUE_SZ)
10774                 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
10775             else {
10776                 info->packets[info->numberPackets].bufferValue =
10777                            XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
10778                 if (!info->packets[info->numberPackets].bufferValue)
10779                     /* let next alloc catch, just don't fill, not fatal here  */
10780                     info->packets[info->numberPackets].valueSz = 0;
10781                 else
10782                     XMEMCPY(info->packets[info->numberPackets].bufferValue,
10783                            data, sz);
10784             }
10785             gettimeofday(&currTime, 0);
10786             info->packets[info->numberPackets].timestamp.tv_sec  =
10787                                                              currTime.tv_sec;
10788             info->packets[info->numberPackets].timestamp.tv_usec =
10789                                                              currTime.tv_usec;
10790             info->numberPackets++;
10791         }
10792     }
10793 
10794 
10795     /* Add packet name to previsouly added packet info */
10796     void AddLateName(const char* name, TimeoutInfo* info)
10797     {
10798         /* make sure we have a valid previous one */
10799         if (info->numberPackets > 0 && info->numberPackets <
10800                                                         MAX_PACKETS_HANDSHAKE) {
10801             XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
10802                     MAX_PACKETNAME_SZ);
10803         }
10804     }
10805 
10806     /* Add record header to previsouly added packet info */
10807     void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
10808     {
10809         /* make sure we have a valid previous one */
10810         if (info->numberPackets > 0 && info->numberPackets <
10811                                                         MAX_PACKETS_HANDSHAKE) {
10812             if (info->packets[info->numberPackets - 1].bufferValue)
10813                 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
10814                        RECORD_HEADER_SZ);
10815             else
10816                 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
10817                        RECORD_HEADER_SZ);
10818         }
10819     }
10820 
10821 #endif /* WOLFSSL_CALLBACKS */
10822 
10823 
10824 
10825 /* client only parts */
10826 #ifndef NO_WOLFSSL_CLIENT
10827 
10828     int SendClientHello(WOLFSSL* ssl)
10829     {
10830         byte              *output;
10831         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
10832         int                sendSz;
10833         int                idSz = ssl->options.resuming
10834                                 ? ssl->session.sessionIDSz
10835                                 : 0;
10836         int                ret;
10837 
10838         if (ssl->suites == NULL) {
10839             WOLFSSL_MSG("Bad suites pointer in SendClientHello");
10840             return SUITES_ERROR;
10841         }
10842 
10843 #ifdef HAVE_SESSION_TICKET
10844         if (ssl->options.resuming && ssl->session.ticketLen > 0) {
10845             SessionTicket* ticket;
10846 
10847             ticket = TLSX_SessionTicket_Create(0,
10848                                    ssl->session.ticket, ssl->session.ticketLen);
10849             if (ticket == NULL) return MEMORY_E;
10850 
10851             ret = TLSX_UseSessionTicket(&ssl->extensions, ticket);
10852             if (ret != SSL_SUCCESS) return ret;
10853 
10854             idSz = 0;
10855         }
10856 #endif
10857         length = VERSION_SZ + RAN_LEN
10858                + idSz + ENUM_LEN
10859                + ssl->suites->suiteSz + SUITE_LEN
10860                + COMP_LEN + ENUM_LEN;
10861 
10862 #ifdef HAVE_TLS_EXTENSIONS
10863         /* auto populate extensions supported unless user defined */
10864         if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
10865             return ret;
10866     #ifdef HAVE_QSH
10867         if (QSH_Init(ssl) != 0)
10868             return MEMORY_E;
10869     #endif
10870         length += TLSX_GetRequestSize(ssl);
10871 #else
10872         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
10873             length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
10874         }
10875 #endif
10876         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
10877 
10878 #ifdef WOLFSSL_DTLS
10879         if (ssl->options.dtls) {
10880             length += ENUM_LEN;   /* cookie */
10881             if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
10882             sendSz  = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
10883             idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
10884         }
10885 #endif
10886 
10887         if (IsEncryptionOn(ssl, 1))
10888             sendSz += MAX_MSG_EXTRA;
10889 
10890         /* check for available size */
10891         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
10892             return ret;
10893 
10894         /* get output buffer */
10895         output = ssl->buffers.outputBuffer.buffer +
10896                  ssl->buffers.outputBuffer.length;
10897 
10898         AddHeaders(output, length, client_hello, ssl);
10899 #ifdef WOLFSSL_DTLS
10900         if (ssl->options.dtls) {
10901             DtlsRecordLayerHeader* rh = (DtlsRecordLayerHeader*)output;
10902             rh->pvMajor = DTLS_MAJOR;
10903             rh->pvMinor = DTLS_MINOR;
10904         }
10905 #endif /* WOLFSSL_DTLS */
10906 
10907             /* client hello, first version */
10908         output[idx++] = ssl->version.major;
10909         output[idx++] = ssl->version.minor;
10910         ssl->chVersion = ssl->version;  /* store in case changed */
10911 
10912             /* then random */
10913         if (ssl->options.connectState == CONNECT_BEGIN) {
10914             ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
10915             if (ret != 0)
10916                 return ret;
10917 
10918                 /* store random */
10919             XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
10920         } else {
10921 #ifdef WOLFSSL_DTLS
10922                 /* send same random on hello again */
10923             XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
10924 #endif
10925         }
10926         idx += RAN_LEN;
10927 
10928             /* then session id */
10929         output[idx++] = (byte)idSz;
10930         if (idSz) {
10931             XMEMCPY(output + idx, ssl->session.sessionID,
10932                                                       ssl->session.sessionIDSz);
10933             idx += ssl->session.sessionIDSz;
10934         }
10935 
10936             /* then DTLS cookie */
10937 #ifdef WOLFSSL_DTLS
10938         if (ssl->options.dtls) {
10939             byte cookieSz = ssl->arrays->cookieSz;
10940 
10941             output[idx++] = cookieSz;
10942             if (cookieSz) {
10943                 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
10944                 idx += cookieSz;
10945             }
10946         }
10947 #endif
10948             /* then cipher suites */
10949         c16toa(ssl->suites->suiteSz, output + idx);
10950         idx += 2;
10951         XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
10952         idx += ssl->suites->suiteSz;
10953 
10954             /* last, compression */
10955         output[idx++] = COMP_LEN;
10956         if (ssl->options.usingCompression)
10957             output[idx++] = ZLIB_COMPRESSION;
10958         else
10959             output[idx++] = NO_COMPRESSION;
10960 
10961 #ifdef HAVE_TLS_EXTENSIONS
10962         idx += TLSX_WriteRequest(ssl, output + idx);
10963 
10964         (void)idx; /* suppress analyzer warning, keep idx current */
10965 #else
10966         if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
10967         {
10968             int i;
10969             /* add in the extensions length */
10970             c16toa((word16)(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz),
10971                     output + idx);
10972             idx += 2;
10973 
10974             c16toa(HELLO_EXT_SIG_ALGO, output + idx);
10975             idx += 2;
10976             c16toa((word16)(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz),
10977                     output+idx);
10978             idx += 2;
10979             c16toa(ssl->suites->hashSigAlgoSz, output + idx);
10980             idx += 2;
10981             for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
10982                 output[idx] = ssl->suites->hashSigAlgo[i];
10983             }
10984         }
10985 #endif
10986 
10987         if (IsEncryptionOn(ssl, 1)) {
10988             byte* input;
10989             int   inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
10990 
10991             input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
10992             if (input == NULL)
10993                 return MEMORY_E;
10994 
10995             XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
10996             sendSz = BuildMessage(ssl, output,sendSz,input,inputSz,handshake,1);
10997             XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
10998 
10999             if (sendSz < 0)
11000                 return sendSz;
11001         } else {
11002             ret = HashOutput(ssl, output, sendSz, 0);
11003             if (ret != 0)
11004                 return ret;
11005         }
11006 
11007         #ifdef WOLFSSL_DTLS
11008             if (ssl->options.dtls) {
11009                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
11010                     return ret;
11011             }
11012         #endif
11013 
11014         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
11015 
11016 #ifdef WOLFSSL_CALLBACKS
11017         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
11018         if (ssl->toInfoOn)
11019             AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
11020                           ssl->heap);
11021 #endif
11022 
11023         ssl->buffers.outputBuffer.length += sendSz;
11024 
11025         return SendBuffered(ssl);
11026     }
11027 
11028 
11029     static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
11030                                     word32* inOutIdx, word32 size)
11031     {
11032         ProtocolVersion pv;
11033         byte            cookieSz;
11034         word32          begin = *inOutIdx;
11035 
11036 #ifdef WOLFSSL_CALLBACKS
11037         if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
11038                                          &ssl->handShakeInfo);
11039         if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
11040 #endif
11041 
11042 #ifdef WOLFSSL_DTLS
11043         if (ssl->options.dtls) {
11044             DtlsPoolReset(ssl);
11045         }
11046 #endif
11047 
11048         if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
11049             return BUFFER_ERROR;
11050 
11051         XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
11052         *inOutIdx += OPAQUE16_LEN;
11053 
11054         if (pv.major != DTLS_MAJOR ||
11055                          (pv.minor != DTLS_MINOR && pv.minor != DTLSv1_2_MINOR))
11056             return VERSION_ERROR;
11057 
11058         cookieSz = input[(*inOutIdx)++];
11059 
11060         if (cookieSz) {
11061             if ((*inOutIdx - begin) + cookieSz > size)
11062                 return BUFFER_ERROR;
11063 
11064 #ifdef WOLFSSL_DTLS
11065             if (cookieSz <= MAX_COOKIE_LEN) {
11066                 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
11067                 ssl->arrays->cookieSz = cookieSz;
11068             }
11069 #endif
11070             *inOutIdx += cookieSz;
11071         }
11072 
11073         ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
11074         return 0;
11075     }
11076 
11077 
11078     static INLINE int DSH_CheckSessionId(WOLFSSL* ssl)
11079     {
11080         int ret = 0;
11081 
11082 #ifdef HAVE_SECRET_CALLBACK
11083         /* If a session secret callback exists, we are using that
11084          * key instead of the saved session key. */
11085         ret = ret || (ssl->sessionSecretCb != NULL);
11086 #endif
11087 
11088 #ifdef HAVE_SESSION_TICKET
11089         /* server may send blank ticket which may not be expected to indicate
11090          * existing one ok but will also be sending a new one */
11091         ret = ret || (ssl->session.ticketLen > 0);
11092 #endif
11093 
11094         ret = ret ||
11095               (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
11096                                           ssl->session.sessionID, ID_LEN) == 0);
11097 
11098         return ret;
11099     }
11100 
11101     static int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
11102                              word32 helloSz)
11103     {
11104         byte            cs0;   /* cipher suite bytes 0, 1 */
11105         byte            cs1;
11106         ProtocolVersion pv;
11107         byte            compression;
11108         word32          i = *inOutIdx;
11109         word32          begin = i;
11110 
11111 #ifdef WOLFSSL_CALLBACKS
11112         if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
11113         if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
11114 #endif
11115 
11116         /* protocol version, random and session id length check */
11117         if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
11118             return BUFFER_ERROR;
11119 
11120         /* protocol version */
11121         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
11122         i += OPAQUE16_LEN;
11123 
11124         if (pv.minor > ssl->version.minor) {
11125             WOLFSSL_MSG("Server using higher version, fatal error");
11126             return VERSION_ERROR;
11127         }
11128         else if (pv.minor < ssl->version.minor) {
11129             WOLFSSL_MSG("server using lower version");
11130 
11131             if (!ssl->options.downgrade) {
11132                 WOLFSSL_MSG("    no downgrade allowed, fatal error");
11133                 return VERSION_ERROR;
11134             }
11135             if (pv.minor < ssl->options.minDowngrade) {
11136                 WOLFSSL_MSG("    version below minimum allowed, fatal error");
11137                 return VERSION_ERROR;
11138             }
11139 
11140             #ifdef HAVE_SECURE_RENEGOTIATION
11141                 if (ssl->secure_renegotiation &&
11142                                          ssl->secure_renegotiation->enabled &&
11143                                          ssl->options.handShakeDone) {
11144                     WOLFSSL_MSG("Server changed version during scr");
11145                     return VERSION_ERROR;
11146                 }
11147             #endif
11148 
11149             if (pv.minor == SSLv3_MINOR) {
11150                 /* turn off tls */
11151                 WOLFSSL_MSG("    downgrading to SSLv3");
11152                 ssl->options.tls    = 0;
11153                 ssl->options.tls1_1 = 0;
11154                 ssl->version.minor  = SSLv3_MINOR;
11155             }
11156             else if (pv.minor == TLSv1_MINOR) {
11157                 /* turn off tls 1.1+ */
11158                 WOLFSSL_MSG("    downgrading to TLSv1");
11159                 ssl->options.tls1_1 = 0;
11160                 ssl->version.minor  = TLSv1_MINOR;
11161             }
11162             else if (pv.minor == TLSv1_1_MINOR) {
11163                 WOLFSSL_MSG("    downgrading to TLSv1.1");
11164                 ssl->version.minor  = TLSv1_1_MINOR;
11165             }
11166         }
11167 
11168         /* random */
11169         XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
11170         i += RAN_LEN;
11171 
11172         /* session id */
11173         ssl->arrays->sessionIDSz = input[i++];
11174 
11175         if (ssl->arrays->sessionIDSz > ID_LEN) {
11176             WOLFSSL_MSG("Invalid session ID size");
11177             ssl->arrays->sessionIDSz = 0;
11178             return BUFFER_ERROR;
11179         }
11180         else if (ssl->arrays->sessionIDSz) {
11181             if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
11182                 return BUFFER_ERROR;
11183 
11184             XMEMCPY(ssl->arrays->sessionID, input + i,
11185                                                       ssl->arrays->sessionIDSz);
11186             i += ssl->arrays->sessionIDSz;
11187             ssl->options.haveSessionId = 1;
11188         }
11189 
11190 
11191         /* suite and compression */
11192         if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
11193             return BUFFER_ERROR;
11194 
11195         cs0 = input[i++];
11196         cs1 = input[i++];
11197 
11198 #ifdef HAVE_SECURE_RENEGOTIATION
11199         if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
11200                                          ssl->options.handShakeDone) {
11201             if (ssl->options.cipherSuite0 != cs0 ||
11202                 ssl->options.cipherSuite  != cs1) {
11203                 WOLFSSL_MSG("Server changed cipher suite during scr");
11204                 return MATCH_SUITE_ERROR;
11205             }
11206         }
11207 #endif
11208 
11209         ssl->options.cipherSuite0 = cs0;
11210         ssl->options.cipherSuite  = cs1;
11211         compression = input[i++];
11212 
11213         if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
11214             WOLFSSL_MSG("Server refused compression, turning off");
11215             ssl->options.usingCompression = 0;  /* turn off if server refused */
11216         }
11217 
11218         *inOutIdx = i;
11219 
11220 
11221         if ( (i - begin) < helloSz) {
11222 #ifdef HAVE_TLS_EXTENSIONS
11223             if (TLSX_SupportExtensions(ssl)) {
11224                 int    ret = 0;
11225                 word16 totalExtSz;
11226 
11227                 if ((i - begin) + OPAQUE16_LEN > helloSz)
11228                     return BUFFER_ERROR;
11229 
11230                 ato16(&input[i], &totalExtSz);
11231                 i += OPAQUE16_LEN;
11232 
11233                 if ((i - begin) + totalExtSz > helloSz)
11234                     return BUFFER_ERROR;
11235 
11236                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
11237                                                           totalExtSz, 0, NULL)))
11238                     return ret;
11239 
11240                 i += totalExtSz;
11241                 *inOutIdx = i;
11242             }
11243             else
11244 #endif
11245                 *inOutIdx = begin + helloSz; /* skip extensions */
11246         }
11247 
11248         ssl->options.serverState = SERVER_HELLO_COMPLETE;
11249 
11250         if (IsEncryptionOn(ssl, 0)) {
11251             *inOutIdx += ssl->keys.padSz;
11252         }
11253 
11254 #ifdef HAVE_SECRET_CALLBACK
11255         if (ssl->sessionSecretCb != NULL) {
11256             int secretSz = SECRET_LEN, ret;
11257             ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
11258                                               &secretSz, ssl->sessionSecretCtx);
11259             if (ret != 0 || secretSz != SECRET_LEN)
11260                 return SESSION_SECRET_CB_E;
11261         }
11262 #endif /* HAVE_SECRET_CALLBACK */
11263 
11264         if (ssl->options.resuming) {
11265             if (DSH_CheckSessionId(ssl)) {
11266                 if (SetCipherSpecs(ssl) == 0) {
11267                     int ret = -1;
11268 
11269                     XMEMCPY(ssl->arrays->masterSecret,
11270                             ssl->session.masterSecret, SECRET_LEN);
11271                     #ifdef NO_OLD_TLS
11272                         ret = DeriveTlsKeys(ssl);
11273                     #else
11274                         #ifndef NO_TLS
11275                             if (ssl->options.tls)
11276                                 ret = DeriveTlsKeys(ssl);
11277                         #endif
11278                             if (!ssl->options.tls)
11279                                 ret = DeriveKeys(ssl);
11280                     #endif
11281                     ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
11282 
11283                     return ret;
11284                 }
11285                 else {
11286                     WOLFSSL_MSG("Unsupported cipher suite, DoServerHello");
11287                     return UNSUPPORTED_SUITE;
11288                 }
11289             }
11290             else {
11291                 WOLFSSL_MSG("Server denied resumption attempt");
11292                 ssl->options.resuming = 0; /* server denied resumption try */
11293             }
11294         }
11295         #ifdef WOLFSSL_DTLS
11296             if (ssl->options.dtls) {
11297                 DtlsPoolReset(ssl);
11298             }
11299         #endif
11300 
11301         return SetCipherSpecs(ssl);
11302     }
11303 
11304 
11305     /* Make sure client setup is valid for this suite, true on success */
11306     int VerifyClientSuite(WOLFSSL* ssl)
11307     {
11308         int  havePSK = 0;
11309         byte first   = ssl->options.cipherSuite0;
11310         byte second  = ssl->options.cipherSuite;
11311 
11312         WOLFSSL_ENTER("VerifyClientSuite");
11313 
11314         #ifndef NO_PSK
11315             havePSK = ssl->options.havePSK;
11316         #endif
11317 
11318         if (CipherRequires(first, second, REQUIRES_PSK)) {
11319             WOLFSSL_MSG("Requires PSK");
11320             if (havePSK == 0) {
11321                 WOLFSSL_MSG("Don't have PSK");
11322                 return 0;
11323             }
11324         }
11325 
11326         return 1;  /* success */
11327     }
11328 
11329 
11330 #ifndef NO_CERTS
11331     /* just read in and ignore for now TODO: */
11332     static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*
11333                                     inOutIdx, word32 size)
11334     {
11335         word16 len;
11336         word32 begin = *inOutIdx;
11337 
11338         #ifdef WOLFSSL_CALLBACKS
11339             if (ssl->hsInfoOn)
11340                 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
11341             if (ssl->toInfoOn)
11342                 AddLateName("CertificateRequest", &ssl->timeoutInfo);
11343         #endif
11344 
11345         if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
11346             return BUFFER_ERROR;
11347 
11348         len = input[(*inOutIdx)++];
11349 
11350         if ((*inOutIdx - begin) + len > size)
11351             return BUFFER_ERROR;
11352 
11353         /* types, read in here */
11354         *inOutIdx += len;
11355 
11356         /* signature and hash signature algorithm */
11357         if (IsAtLeastTLSv1_2(ssl)) {
11358             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
11359                 return BUFFER_ERROR;
11360 
11361             ato16(input + *inOutIdx, &len);
11362             *inOutIdx += OPAQUE16_LEN;
11363 
11364             if ((*inOutIdx - begin) + len > size)
11365                 return BUFFER_ERROR;
11366 
11367             PickHashSigAlgo(ssl, input + *inOutIdx, len);
11368             *inOutIdx += len;
11369         }
11370 
11371         /* authorities */
11372         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
11373             return BUFFER_ERROR;
11374 
11375         ato16(input + *inOutIdx, &len);
11376         *inOutIdx += OPAQUE16_LEN;
11377 
11378         if ((*inOutIdx - begin) + len > size)
11379             return BUFFER_ERROR;
11380 
11381         while (len) {
11382             word16 dnSz;
11383 
11384             if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
11385                 return BUFFER_ERROR;
11386 
11387             ato16(input + *inOutIdx, &dnSz);
11388             *inOutIdx += OPAQUE16_LEN;
11389 
11390             if ((*inOutIdx - begin) + dnSz > size)
11391                 return BUFFER_ERROR;
11392 
11393             *inOutIdx += dnSz;
11394             len -= OPAQUE16_LEN + dnSz;
11395         }
11396 
11397         /* don't send client cert or cert verify if user hasn't provided
11398            cert and private key */
11399         if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
11400             ssl->buffers.key && ssl->buffers.key->buffer)
11401             ssl->options.sendVerify = SEND_CERT;
11402         else if (IsTLS(ssl))
11403             ssl->options.sendVerify = SEND_BLANK_CERT;
11404 
11405         if (IsEncryptionOn(ssl, 0))
11406             *inOutIdx += ssl->keys.padSz;
11407 
11408         return 0;
11409     }
11410 #endif /* !NO_CERTS */
11411 
11412 
11413 #ifdef HAVE_ECC
11414 
11415     static int CheckCurveId(int oid)
11416     {
11417         int ret = 0;
11418 
11419         switch (oid) {
11420 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
11421             case WOLFSSL_ECC_SECP160R1:
11422 #endif
11423 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
11424             case WOLFSSL_ECC_SECP192R1:
11425 #endif
11426 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
11427             case WOLFSSL_ECC_SECP224R1:
11428 #endif
11429 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
11430             case WOLFSSL_ECC_SECP256R1:
11431 #endif
11432 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
11433             case WOLFSSL_ECC_SECP384R1:
11434 #endif
11435 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
11436             case WOLFSSL_ECC_SECP521R1:
11437 #endif
11438                 break;
11439 
11440             default:
11441                 ret = -1;
11442         }
11443 
11444         return ret;
11445     }
11446 
11447 #endif /* HAVE_ECC */
11448 
11449     static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
11450                                    word32* inOutIdx, word32 size)
11451     {
11452     #ifdef HAVE_QSH
11453         word16 name;
11454         int    qshSz;
11455     #endif
11456         word16 length = 0;
11457         word32 begin  = *inOutIdx;
11458         int    ret    = 0;
11459         #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
11460 
11461         (void)length; /* shut up compiler warnings */
11462         (void)begin;
11463         (void)ssl;
11464         (void)input;
11465         (void)size;
11466         (void)ret;
11467 
11468 
11469     #ifdef WOLFSSL_CALLBACKS
11470         if (ssl->hsInfoOn)
11471             AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
11472         if (ssl->toInfoOn)
11473             AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
11474     #endif
11475 
11476         switch (ssl->specs.kea)
11477         {
11478     #ifndef NO_PSK
11479         case psk_kea:
11480         {
11481             if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11482                 return BUFFER_ERROR;
11483             }
11484 
11485             ato16(input + *inOutIdx, &length);
11486             *inOutIdx += OPAQUE16_LEN;
11487 
11488             if ((*inOutIdx - begin) + length > size) {
11489                 return BUFFER_ERROR;
11490             }
11491 
11492             XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
11493                    min(length, MAX_PSK_ID_LEN));
11494 
11495             ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
11496             *inOutIdx += length;
11497 
11498             /* QSH extensions */
11499         #ifdef HAVE_QSH
11500             if (ssl->peerQSHKeyPresent) {
11501                 /* extension name */
11502                 ato16(input + *inOutIdx, &name);
11503                 *inOutIdx += OPAQUE16_LEN;
11504 
11505                 if (name == TLSX_QUANTUM_SAFE_HYBRID) {
11506                     /* if qshSz is larger than 0 it is the length of buffer
11507                        used */
11508                     if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
11509                                                                size, 0)) < 0) {
11510                         return qshSz;
11511                     }
11512                     *inOutIdx += qshSz;
11513                 }
11514                 else {
11515                     /* unknown extension sent server ignored
11516                        handshake */
11517                     return BUFFER_ERROR;
11518                 }
11519             }
11520         #endif
11521 
11522             return 0;
11523         }
11524     #endif
11525     #ifndef NO_DH
11526         case diffie_hellman_kea:
11527         {
11528             /* p */
11529             if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11530                 return BUFFER_ERROR;
11531             }
11532 
11533             ato16(input + *inOutIdx, &length);
11534             *inOutIdx += OPAQUE16_LEN;
11535 
11536             if ((*inOutIdx - begin) + length > size) {
11537                 return BUFFER_ERROR;
11538             }
11539 
11540             if (length < ssl->options.minDhKeySz) {
11541                 WOLFSSL_MSG("Server using a DH key that is too small");
11542                 SendAlert(ssl, alert_fatal, handshake_failure);
11543                 return DH_KEY_SIZE_E;
11544             }
11545 
11546             ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
11547                                                              DYNAMIC_TYPE_DH);
11548 
11549             if (ssl->buffers.serverDH_P.buffer) {
11550                 ssl->buffers.serverDH_P.length = length;
11551             }
11552             else {
11553                 return MEMORY_ERROR;
11554             }
11555 
11556             XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
11557             *inOutIdx += length;
11558 
11559             ssl->options.dhKeySz = length;
11560 
11561             /* g */
11562             if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11563                 return BUFFER_ERROR;
11564             }
11565 
11566             ato16(input + *inOutIdx, &length);
11567             *inOutIdx += OPAQUE16_LEN;
11568 
11569             if ((*inOutIdx - begin) + length > size) {
11570                 return BUFFER_ERROR;
11571             }
11572 
11573             ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
11574                                                              DYNAMIC_TYPE_DH);
11575 
11576             if (ssl->buffers.serverDH_G.buffer) {
11577                 ssl->buffers.serverDH_G.length = length;
11578             }
11579             else {
11580                 return MEMORY_ERROR;
11581             }
11582 
11583             XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
11584             *inOutIdx += length;
11585 
11586             /* pub */
11587             if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11588                 return BUFFER_ERROR;
11589             }
11590 
11591             ato16(input + *inOutIdx, &length);
11592             *inOutIdx += OPAQUE16_LEN;
11593 
11594             if ((*inOutIdx - begin) + length > size) {
11595                 return BUFFER_ERROR;
11596             }
11597 
11598             ssl->buffers.serverDH_Pub.buffer =
11599                 (byte*) XMALLOC(length, ssl->heap, DYNAMIC_TYPE_DH);
11600 
11601             if (ssl->buffers.serverDH_Pub.buffer) {
11602                 ssl->buffers.serverDH_Pub.length = length;
11603             }
11604             else {
11605                 return MEMORY_ERROR;
11606             }
11607 
11608             XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx,
11609                 length);
11610             *inOutIdx += length;
11611             break;
11612         }  /* dh_kea */
11613     #endif /* NO_DH */
11614 
11615     #ifdef HAVE_ECC
11616         case ecc_diffie_hellman_kea:
11617         {
11618             byte b;
11619 
11620             if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN +
11621                 OPAQUE8_LEN > size) {
11622                 return BUFFER_ERROR;
11623             }
11624 
11625             b = input[(*inOutIdx)++];
11626 
11627             if (b != named_curve) {
11628                 return ECC_CURVETYPE_ERROR;
11629             }
11630 
11631             *inOutIdx += 1;   /* curve type, eat leading 0 */
11632             b = input[(*inOutIdx)++];
11633 
11634             if (CheckCurveId(b) != 0) {
11635                 return ECC_CURVE_ERROR;
11636             }
11637 
11638             length = input[(*inOutIdx)++];
11639 
11640             if ((*inOutIdx - begin) + length > size) {
11641                 return BUFFER_ERROR;
11642             }
11643 
11644             if (ssl->peerEccKey == NULL) {
11645                 /* alloc/init on demand */
11646                 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
11647                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
11648                 if (ssl->peerEccKey == NULL) {
11649                     WOLFSSL_MSG("PeerEccKey Memory error");
11650                     return MEMORY_E;
11651                 }
11652                 wc_ecc_init(ssl->peerEccKey);
11653             } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
11654                 wc_ecc_free(ssl->peerEccKey);
11655                 ssl->peerEccKeyPresent = 0;
11656                 wc_ecc_init(ssl->peerEccKey);
11657             }
11658 
11659             if (wc_ecc_import_x963(input + *inOutIdx, length,
11660                 ssl->peerEccKey) != 0) {
11661                 return ECC_PEERKEY_ERROR;
11662             }
11663 
11664             *inOutIdx += length;
11665             ssl->peerEccKeyPresent = 1;
11666 
11667             break;
11668         }
11669     #endif /* HAVE_ECC */
11670 
11671     #if !defined(NO_DH) && !defined(NO_PSK)
11672     case dhe_psk_kea:
11673     {
11674         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11675             return BUFFER_ERROR;
11676         }
11677 
11678         ato16(input + *inOutIdx, &length);
11679         *inOutIdx += OPAQUE16_LEN;
11680 
11681         if ((*inOutIdx - begin) + length > size) {
11682             return BUFFER_ERROR;
11683         }
11684 
11685         XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
11686             min(length, MAX_PSK_ID_LEN));
11687 
11688         ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
11689         *inOutIdx += length;
11690 
11691         /* p */
11692         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11693             return BUFFER_ERROR;
11694         }
11695 
11696         ato16(input + *inOutIdx, &length);
11697         *inOutIdx += OPAQUE16_LEN;
11698 
11699         if ((*inOutIdx - begin) + length > size) {
11700             return BUFFER_ERROR;
11701         }
11702 
11703         if (length < ssl->options.minDhKeySz) {
11704             WOLFSSL_MSG("Server using a DH key that is too small");
11705             SendAlert(ssl, alert_fatal, handshake_failure);
11706             return DH_KEY_SIZE_E;
11707         }
11708 
11709         ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
11710                                                          DYNAMIC_TYPE_DH);
11711 
11712         if (ssl->buffers.serverDH_P.buffer) {
11713             ssl->buffers.serverDH_P.length = length;
11714         }
11715         else {
11716             return MEMORY_ERROR;
11717         }
11718 
11719         XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
11720         *inOutIdx += length;
11721 
11722         ssl->options.dhKeySz = length;
11723 
11724         /* g */
11725         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11726             return BUFFER_ERROR;
11727         }
11728 
11729         ato16(input + *inOutIdx, &length);
11730         *inOutIdx += OPAQUE16_LEN;
11731 
11732         if ((*inOutIdx - begin) + length > size) {
11733             return BUFFER_ERROR;
11734         }
11735 
11736         ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
11737                                                          DYNAMIC_TYPE_DH);
11738 
11739         if (ssl->buffers.serverDH_G.buffer) {
11740             ssl->buffers.serverDH_G.length = length;
11741         }
11742         else {
11743             return MEMORY_ERROR;
11744         }
11745 
11746         XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
11747         *inOutIdx += length;
11748 
11749         /* pub */
11750         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11751             return BUFFER_ERROR;
11752         }
11753 
11754         ato16(input + *inOutIdx, &length);
11755         *inOutIdx += OPAQUE16_LEN;
11756 
11757         if ((*inOutIdx - begin) + length > size) {
11758             return BUFFER_ERROR;
11759         }
11760 
11761         ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
11762                                                            DYNAMIC_TYPE_DH);
11763 
11764         if (ssl->buffers.serverDH_Pub.buffer) {
11765             ssl->buffers.serverDH_Pub.length = length;
11766         }
11767         else {
11768             return MEMORY_ERROR;
11769         }
11770 
11771         XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
11772         *inOutIdx += length;
11773 
11774         break;
11775     }
11776     #endif /* !NO_DH || !NO_PSK */
11777 
11778     #if defined(HAVE_ECC) && !defined(NO_PSK)
11779     case ecdhe_psk_kea:
11780     {
11781         byte b;
11782 
11783         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11784             return BUFFER_ERROR;
11785         }
11786 
11787         ato16(input + *inOutIdx, &length);
11788         *inOutIdx += OPAQUE16_LEN;
11789 
11790         if ((*inOutIdx - begin) + length > size) {
11791             return BUFFER_ERROR;
11792         }
11793 
11794         /* get PSK server hint from the wire */
11795         XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
11796             min(length, MAX_PSK_ID_LEN));
11797 
11798         ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
11799         *inOutIdx += length;
11800 
11801 
11802         if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN +
11803             OPAQUE8_LEN > size) {
11804             return BUFFER_ERROR;
11805         }
11806 
11807         /* Check curve name and ID */
11808         b = input[(*inOutIdx)++];
11809         if (b != named_curve) {
11810             return ECC_CURVETYPE_ERROR;
11811         }
11812 
11813         *inOutIdx += 1;   /* curve type, eat leading 0 */
11814         b = input[(*inOutIdx)++];
11815         if (CheckCurveId(b) != 0) {
11816             return ECC_CURVE_ERROR;
11817         }
11818 
11819         length = input[(*inOutIdx)++];
11820 
11821         if ((*inOutIdx - begin) + length > size) {
11822             return BUFFER_ERROR;
11823         }
11824 
11825         if (ssl->peerEccKey == NULL) {
11826             /* alloc/init on demand */
11827             ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
11828                                          ssl->ctx->heap, DYNAMIC_TYPE_ECC);
11829             if (ssl->peerEccKey == NULL) {
11830                 WOLFSSL_MSG("PeerEccKey Memory error");
11831                 return MEMORY_E;
11832             }
11833             wc_ecc_init(ssl->peerEccKey);
11834         } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
11835             wc_ecc_free(ssl->peerEccKey);
11836             ssl->peerEccKeyPresent = 0;
11837             wc_ecc_init(ssl->peerEccKey);
11838         }
11839 
11840         if (wc_ecc_import_x963(input + *inOutIdx, length,
11841             ssl->peerEccKey) != 0) {
11842             return ECC_PEERKEY_ERROR;
11843         }
11844 
11845         *inOutIdx += length;
11846         ssl->peerEccKeyPresent = 1;
11847 
11848         break;
11849     }
11850     #endif /* HAVE_ECC || !NO_PSK */
11851     } /* switch() */
11852 
11853     #if !defined(NO_DH) || defined(HAVE_ECC)
11854     if (!ssl->options.usingAnon_cipher &&
11855         (ssl->specs.kea == ecc_diffie_hellman_kea ||
11856          ssl->specs.kea == diffie_hellman_kea))
11857     {
11858 #ifndef NO_OLD_TLS
11859 #ifdef WOLFSSL_SMALL_STACK
11860         Md5*    md5 = NULL;
11861         Sha*    sha = NULL;
11862 #else
11863         Md5     md5[1];
11864         Sha     sha[1];
11865 #endif
11866 #endif
11867 #ifndef NO_SHA256
11868 #ifdef WOLFSSL_SMALL_STACK
11869         Sha256* sha256  = NULL;
11870         byte*   hash256 = NULL;
11871 #else
11872         Sha256  sha256[1];
11873         byte    hash256[SHA256_DIGEST_SIZE];
11874 #endif
11875 #endif
11876 #ifdef WOLFSSL_SHA384
11877 #ifdef WOLFSSL_SMALL_STACK
11878         Sha384* sha384  = NULL;
11879         byte*   hash384 = NULL;
11880 #else
11881         Sha384  sha384[1];
11882         byte    hash384[SHA384_DIGEST_SIZE];
11883 #endif
11884 #endif
11885 #ifdef WOLFSSL_SHA512
11886 #ifdef WOLFSSL_SMALL_STACK
11887         Sha512* sha512  = NULL;
11888         byte*   hash512 = NULL;
11889 #else
11890         Sha512  sha512[1];
11891         byte    hash512[SHA512_DIGEST_SIZE];
11892 #endif
11893 #endif
11894 #ifdef WOLFSSL_SMALL_STACK
11895         byte*   hash          = NULL;
11896         byte*   messageVerify = NULL;
11897 #else
11898         byte    hash[FINISHED_SZ];
11899         byte    messageVerify[MAX_DH_SZ];
11900 #endif
11901         byte    hashAlgo = sha_mac;
11902         byte    sigAlgo  = ssl->specs.sig_algo;
11903         word16  verifySz = (word16) (*inOutIdx - begin);
11904 
11905 #ifndef NO_OLD_TLS
11906         byte doMd5 = 0;
11907         byte doSha = 0;
11908 #endif
11909 #ifndef NO_SHA256
11910         byte doSha256 = 0;
11911 #endif
11912 #ifdef WOLFSSL_SHA384
11913         byte doSha384 = 0;
11914 #endif
11915 #ifdef WOLFSSL_SHA512
11916         byte doSha512 = 0;
11917 #endif
11918 
11919         (void)hash;
11920         (void)sigAlgo;
11921         (void)hashAlgo;
11922 
11923         /* save message for hash verify */
11924         if (verifySz > MAX_DH_SZ) {
11925             ERROR_OUT(BUFFER_ERROR, done);
11926         }
11927 
11928     #ifdef WOLFSSL_SMALL_STACK
11929         messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL,
11930                                                        DYNAMIC_TYPE_TMP_BUFFER);
11931         if (messageVerify == NULL) {
11932             ERROR_OUT(MEMORY_E, done);
11933         }
11934     #endif
11935 
11936         XMEMCPY(messageVerify, input + begin, verifySz);
11937 
11938         if (IsAtLeastTLSv1_2(ssl)) {
11939             byte setHash = 0;
11940             if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size) {
11941                 ERROR_OUT(BUFFER_ERROR, done);
11942             }
11943 
11944             hashAlgo = input[(*inOutIdx)++];
11945             sigAlgo  = input[(*inOutIdx)++];
11946 
11947             switch (hashAlgo) {
11948                 case sha512_mac:
11949                     #ifdef WOLFSSL_SHA512
11950                         doSha512 = 1;
11951                         setHash  = 1;
11952                     #endif
11953                     break;
11954 
11955                 case sha384_mac:
11956                     #ifdef WOLFSSL_SHA384
11957                         doSha384 = 1;
11958                         setHash  = 1;
11959                     #endif
11960                     break;
11961 
11962                 case sha256_mac:
11963                     #ifndef NO_SHA256
11964                         doSha256 = 1;
11965                         setHash  = 1;
11966                     #endif
11967                     break;
11968 
11969                 case sha_mac:
11970                     #ifndef NO_OLD_TLS
11971                         doSha = 1;
11972                         setHash  = 1;
11973                     #endif
11974                     break;
11975 
11976                 default:
11977                     ERROR_OUT(ALGO_ID_E, done);
11978             }
11979 
11980             if (setHash == 0) {
11981                 ERROR_OUT(ALGO_ID_E, done);
11982             }
11983 
11984         } else {
11985             /* only using sha and md5 for rsa */
11986             #ifndef NO_OLD_TLS
11987                 doSha = 1;
11988                 if (sigAlgo == rsa_sa_algo) {
11989                     doMd5 = 1;
11990                 }
11991             #else
11992                 ERROR_OUT(ALGO_ID_E, done);
11993             #endif
11994         }
11995 
11996         /* signature */
11997         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
11998             ERROR_OUT(BUFFER_ERROR, done);
11999         }
12000 
12001         ato16(input + *inOutIdx, &length);
12002         *inOutIdx += OPAQUE16_LEN;
12003 
12004         if ((*inOutIdx - begin) + length > size) {
12005             ERROR_OUT(BUFFER_ERROR, done);
12006         }
12007 
12008         /* inOutIdx updated at the end of the function */
12009 
12010         /* verify signature */
12011     #ifdef WOLFSSL_SMALL_STACK
12012         hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12013         if (hash == NULL) {
12014             ERROR_OUT(MEMORY_E, done);
12015         }
12016     #endif
12017 
12018 #ifndef NO_OLD_TLS
12019         /* md5 */
12020     #ifdef WOLFSSL_SMALL_STACK
12021         if (doMd5) {
12022             md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12023             if (md5 == NULL) {
12024                 ERROR_OUT(MEMORY_E, done);
12025             }
12026         }
12027     #endif
12028         if (doMd5) {
12029             wc_InitMd5(md5);
12030             wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
12031             wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
12032             wc_Md5Update(md5, messageVerify, verifySz);
12033             wc_Md5Final(md5, hash);
12034         }
12035         /* sha */
12036     #ifdef WOLFSSL_SMALL_STACK
12037         if (doSha) {
12038             sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
12039             if (sha == NULL) {
12040                 ERROR_OUT(MEMORY_E, done);
12041             }
12042         }
12043     #endif
12044         if (doSha) {
12045             ret = wc_InitSha(sha);
12046             if (ret != 0) {
12047                 goto done;
12048             }
12049             wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
12050             wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
12051             wc_ShaUpdate(sha, messageVerify, verifySz);
12052             wc_ShaFinal(sha, hash + MD5_DIGEST_SIZE);
12053         }
12054 #endif
12055 
12056 #ifndef NO_SHA256
12057     #ifdef WOLFSSL_SMALL_STACK
12058         if (doSha256) {
12059             sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
12060                                                        DYNAMIC_TYPE_TMP_BUFFER);
12061             hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
12062                                                        DYNAMIC_TYPE_TMP_BUFFER);
12063             if (sha256 == NULL || hash256 == NULL) {
12064                 ERROR_OUT(MEMORY_E, done);
12065             }
12066         }
12067     #endif
12068         if (doSha256) {
12069             if (!(ret = wc_InitSha256(sha256))
12070             &&  !(ret = wc_Sha256Update(sha256, ssl->arrays->clientRandom,
12071                                         RAN_LEN))
12072             &&  !(ret = wc_Sha256Update(sha256, ssl->arrays->serverRandom,
12073                                         RAN_LEN))
12074             &&  !(ret = wc_Sha256Update(sha256, messageVerify, verifySz))) {
12075                   ret = wc_Sha256Final(sha256, hash256);
12076             }
12077             if (ret != 0) {
12078                 goto done;
12079             }
12080         }
12081 #endif
12082 
12083 #ifdef WOLFSSL_SHA384
12084     #ifdef WOLFSSL_SMALL_STACK
12085         if (doSha384) {
12086             sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
12087                                                        DYNAMIC_TYPE_TMP_BUFFER);
12088             hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
12089                                                        DYNAMIC_TYPE_TMP_BUFFER);
12090             if (sha384 == NULL || hash384 == NULL) {
12091                 ERROR_OUT(MEMORY_E, done);
12092             }
12093         }
12094     #endif
12095         if (doSha384) {
12096             if (!(ret = wc_InitSha384(sha384))
12097             &&  !(ret = wc_Sha384Update(sha384, ssl->arrays->clientRandom,
12098                                         RAN_LEN))
12099             &&  !(ret = wc_Sha384Update(sha384, ssl->arrays->serverRandom,
12100                                         RAN_LEN))
12101             &&  !(ret = wc_Sha384Update(sha384, messageVerify, verifySz))) {
12102                   ret = wc_Sha384Final(sha384, hash384);
12103             }
12104             if (ret != 0) {
12105                 goto done;
12106             }
12107         }
12108 #endif
12109 
12110 #ifdef WOLFSSL_SHA512
12111     #ifdef WOLFSSL_SMALL_STACK
12112         if (doSha512) {
12113             sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
12114                                                        DYNAMIC_TYPE_TMP_BUFFER);
12115             hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
12116                                                        DYNAMIC_TYPE_TMP_BUFFER);
12117             if (sha512 == NULL || hash512 == NULL) {
12118                 ERROR_OUT(MEMORY_E, done);
12119             }
12120         }
12121     #endif
12122         if (doSha512) {
12123             if (!(ret = wc_InitSha512(sha512))
12124             &&  !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom,
12125                                         RAN_LEN))
12126             &&  !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom,
12127                                         RAN_LEN))
12128             &&  !(ret = wc_Sha512Update(sha512, messageVerify, verifySz))) {
12129                   ret = wc_Sha512Final(sha512, hash512);
12130             }
12131             if (ret != 0) {
12132                 goto done;
12133             }
12134         }
12135 #endif
12136 
12137         switch (sigAlgo)
12138         {
12139 #ifndef NO_RSA
12140         /* rsa */
12141         case rsa_sa_algo:
12142         {
12143             byte*  out        = NULL;
12144             byte   doUserRsa  = 0;
12145             word32 verifiedSz = 0;
12146 
12147             #ifdef HAVE_PK_CALLBACKS
12148                 if (ssl->ctx->RsaVerifyCb)
12149                     doUserRsa = 1;
12150             #endif /*HAVE_PK_CALLBACKS */
12151 
12152             if (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent) {
12153                 ERROR_OUT(NO_PEER_KEY, done);
12154             }
12155 
12156             if (doUserRsa) {
12157             #ifdef HAVE_PK_CALLBACKS
12158                 verifiedSz = ssl->ctx->RsaVerifyCb(ssl,
12159                                                  (byte *)input + *inOutIdx,
12160                                                  length, &out,
12161                                                  ssl->buffers.peerRsaKey.buffer,
12162                                                  ssl->buffers.peerRsaKey.length,
12163                                                  ssl->RsaVerifyCtx);
12164             #endif /*HAVE_PK_CALLBACKS */
12165             }
12166             else {
12167                 verifiedSz = wc_RsaSSL_VerifyInline((byte *)input + *inOutIdx,
12168                                                  length, &out, ssl->peerRsaKey);
12169             }
12170 
12171             if (IsAtLeastTLSv1_2(ssl)) {
12172                 word32 encSigSz;
12173 #ifndef NO_OLD_TLS
12174                 byte*  digest = &hash[MD5_DIGEST_SIZE];
12175                 int    typeH = SHAh;
12176                 int    digestSz = SHA_DIGEST_SIZE;
12177 #else
12178                 byte*  digest = hash256;
12179                 int    typeH =  SHA256h;
12180                 int    digestSz = SHA256_DIGEST_SIZE;
12181 #endif
12182 #ifdef WOLFSSL_SMALL_STACK
12183                 byte*  encodedSig = NULL;
12184 #else
12185                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
12186 #endif
12187 
12188                 if (hashAlgo == sha_mac) {
12189                     #ifndef NO_SHA
12190                         digest   = &hash[MD5_DIGEST_SIZE];
12191                         typeH    = SHAh;
12192                         digestSz = SHA_DIGEST_SIZE;
12193                     #endif
12194                 }
12195                 else if (hashAlgo == sha256_mac) {
12196                     #ifndef NO_SHA256
12197                         digest   = hash256;
12198                         typeH    = SHA256h;
12199                         digestSz = SHA256_DIGEST_SIZE;
12200                     #endif
12201                 }
12202                 else if (hashAlgo == sha384_mac) {
12203                     #ifdef WOLFSSL_SHA384
12204                         digest   = hash384;
12205                         typeH    = SHA384h;
12206                         digestSz = SHA384_DIGEST_SIZE;
12207                     #endif
12208                 }
12209                 else if (hashAlgo == sha512_mac) {
12210                     #ifdef WOLFSSL_SHA512
12211                         digest   = hash512;
12212                         typeH    = SHA512h;
12213                         digestSz = SHA512_DIGEST_SIZE;
12214                     #endif
12215                 }
12216 
12217             #ifdef WOLFSSL_SMALL_STACK
12218                 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
12219                                                        DYNAMIC_TYPE_TMP_BUFFER);
12220                 if (encodedSig == NULL) {
12221                     ERROR_OUT(MEMORY_E, done);
12222                 }
12223             #endif
12224 
12225                 if (digest == NULL) {
12226                     ERROR_OUT(ALGO_ID_E, done);
12227                 }
12228                 encSigSz = wc_EncodeSignature(encodedSig, digest, digestSz,
12229                                               typeH);
12230                 if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig,
12231                                         min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0) {
12232                     ret = VERIFY_SIGN_ERROR;
12233                 }
12234             #ifdef WOLFSSL_SMALL_STACK
12235                 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12236             #endif
12237                 if (ret != 0) {
12238                     goto done;
12239                 }
12240             }
12241             else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out,
12242                                                         hash, FINISHED_SZ) != 0) {
12243                 ERROR_OUT(VERIFY_SIGN_ERROR, done);
12244             }
12245             break;
12246         }
12247 #endif
12248 #ifdef HAVE_ECC
12249         /* ecdsa */
12250         case ecc_dsa_sa_algo:
12251         {
12252             int verify = 0;
12253 #ifndef NO_OLD_TLS
12254             byte* digest = &hash[MD5_DIGEST_SIZE];
12255             word32 digestSz = SHA_DIGEST_SIZE;
12256 #else
12257             byte* digest = hash256;
12258             word32 digestSz = SHA256_DIGEST_SIZE;
12259 #endif
12260             byte doUserEcc = 0;
12261 
12262             #ifdef HAVE_PK_CALLBACKS
12263                 if (ssl->ctx->EccVerifyCb) {
12264                     doUserEcc = 1;
12265                 }
12266             #endif
12267 
12268             if (!ssl->peerEccDsaKeyPresent)
12269                 ERROR_OUT(NO_PEER_KEY, done);
12270 
12271             if (IsAtLeastTLSv1_2(ssl)) {
12272                 if (hashAlgo == sha_mac) {
12273                     #ifndef NO_SHA
12274                         digest   = &hash[MD5_DIGEST_SIZE];
12275                         digestSz = SHA_DIGEST_SIZE;
12276                     #endif
12277                 }
12278                 else if (hashAlgo == sha256_mac) {
12279                     #ifndef NO_SHA256
12280                         digest   = hash256;
12281                         digestSz = SHA256_DIGEST_SIZE;
12282                     #endif
12283                 }
12284                 else if (hashAlgo == sha384_mac) {
12285                     #ifdef WOLFSSL_SHA384
12286                         digest   = hash384;
12287                         digestSz = SHA384_DIGEST_SIZE;
12288                     #endif
12289                 }
12290                 else if (hashAlgo == sha512_mac) {
12291                     #ifdef WOLFSSL_SHA512
12292                         digest   = hash512;
12293                         digestSz = SHA512_DIGEST_SIZE;
12294                     #endif
12295                 }
12296             }
12297             if (doUserEcc) {
12298             #ifdef HAVE_PK_CALLBACKS
12299                 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, length,
12300                                             digest, digestSz,
12301                                             ssl->buffers.peerEccDsaKey.buffer,
12302                                             ssl->buffers.peerEccDsaKey.length,
12303                                             &verify, ssl->EccVerifyCtx);
12304             #endif
12305             }
12306             else {
12307                 ret = wc_ecc_verify_hash(input + *inOutIdx, length,
12308                                  digest, digestSz, &verify, ssl->peerEccDsaKey);
12309             }
12310             if (ret != 0 || verify == 0) {
12311                 ERROR_OUT(VERIFY_SIGN_ERROR, done);
12312             }
12313             break;
12314         }
12315 #endif /* HAVE_ECC */
12316         default:
12317             ERROR_OUT(ALGO_ID_E, done);
12318         } /* switch (sigAlgo) */
12319 
12320         /* signature length */
12321         *inOutIdx += length;
12322 
12323         ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
12324 
12325     done:
12326 #ifdef WOLFSSL_SMALL_STACK
12327     #ifndef NO_OLD_TLS
12328         XFREE(md5,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
12329         XFREE(sha,           NULL, DYNAMIC_TYPE_TMP_BUFFER);
12330     #endif
12331     #ifndef NO_SHA256
12332         XFREE(sha256,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
12333         XFREE(hash256,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
12334     #endif
12335     #ifdef WOLFSSL_SHA384
12336         XFREE(sha384,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
12337         XFREE(hash384,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
12338     #endif
12339     #ifdef WOLFSSL_SHA512
12340         XFREE(sha512,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
12341         XFREE(hash512,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
12342     #endif
12343         XFREE(hash,          NULL, DYNAMIC_TYPE_TMP_BUFFER);
12344         XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12345 #endif
12346         if (ret != 0) {
12347             return ret;
12348         }
12349     }
12350 
12351     if (IsEncryptionOn(ssl, 0)) {
12352         *inOutIdx += ssl->keys.padSz;
12353     }
12354 
12355 
12356     /* QSH extensions */
12357 #ifdef HAVE_QSH
12358     if (ssl->peerQSHKeyPresent) {
12359         /* extension name */
12360         ato16(input + *inOutIdx, &name);
12361         *inOutIdx += OPAQUE16_LEN;
12362 
12363         if (name == TLSX_QUANTUM_SAFE_HYBRID) {
12364             /* if qshSz is larger than 0 it is the length of buffer used */
12365             if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
12366                                                             size, 0)) < 0) {
12367                 return qshSz;
12368             }
12369             *inOutIdx += qshSz;
12370         }
12371         else {
12372             /* unknown extension sent server ignored
12373                handshake */
12374             return BUFFER_ERROR;
12375         }
12376     }
12377 #endif
12378 
12379     return 0;
12380 #else  /* !NO_DH or HAVE_ECC */
12381         return NOT_COMPILED_IN;  /* not supported by build */
12382 #endif /* !NO_DH or HAVE_ECC */
12383 
12384         #undef ERROR_OUT
12385     }
12386 
12387 
12388 #ifdef HAVE_QSH
12389 
12390 #ifdef HAVE_NTRU
12391 /* Encrypt a byte array using ntru
12392    key    a struct containing the public key to use
12393    bufIn  array to be encrypted
12394    inSz   size of bufIn array
12395    bufOut cipher text out
12396    outSz  will be set to the new size of cipher text
12397  */
12398 static int NtruSecretEncrypt(QSHKey* key, byte* bufIn, word32 inSz,
12399         byte* bufOut, word16* outSz)
12400 {
12401     int    ret;
12402     DRBG_HANDLE drbg;
12403 
12404     /* sanity checks on input arguments */
12405     if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
12406         return BAD_FUNC_ARG;
12407 
12408     if (key->pub.buffer == NULL)
12409         return BAD_FUNC_ARG;
12410 
12411     switch (key->name) {
12412         case WOLFSSL_NTRU_EESS439:
12413         case WOLFSSL_NTRU_EESS593:
12414         case WOLFSSL_NTRU_EESS743:
12415             break;
12416         default:
12417             WOLFSSL_MSG("Unknown QSH encryption key!");
12418             return -1;
12419     }
12420 
12421     /* set up ntru drbg */
12422     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
12423     if (ret != DRBG_OK)
12424         return NTRU_DRBG_ERROR;
12425 
12426     /* encrypt the byte array */
12427     ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length, key->pub.buffer,
12428         inSz, bufIn, outSz, bufOut);
12429     ntru_crypto_drbg_uninstantiate(drbg);
12430     if (ret != NTRU_OK)
12431         return NTRU_ENCRYPT_ERROR;
12432 
12433     return ret;
12434 }
12435 
12436 /* Decrypt a byte array using ntru
12437    key    a struct containing the private key to use
12438    bufIn  array to be decrypted
12439    inSz   size of bufIn array
12440    bufOut plain text out
12441    outSz  will be set to the new size of plain text
12442  */
12443 
12444 static int NtruSecretDecrypt(QSHKey* key, byte* bufIn, word32 inSz,
12445         byte* bufOut, word16* outSz)
12446 {
12447     int    ret;
12448     DRBG_HANDLE drbg;
12449 
12450     /* sanity checks on input arguments */
12451     if (key == NULL || bufIn == NULL || bufOut == NULL || outSz == NULL)
12452         return BAD_FUNC_ARG;
12453 
12454     if (key->pri.buffer == NULL)
12455         return BAD_FUNC_ARG;
12456 
12457     switch (key->name) {
12458         case WOLFSSL_NTRU_EESS439:
12459         case WOLFSSL_NTRU_EESS593:
12460         case WOLFSSL_NTRU_EESS743:
12461             break;
12462         default:
12463             WOLFSSL_MSG("Unknown QSH decryption key!");
12464             return -1;
12465     }
12466 
12467 
12468     /* set up drbg */
12469     ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
12470     if (ret != DRBG_OK)
12471         return NTRU_DRBG_ERROR;
12472 
12473     /* decrypt cipher text */
12474     ret = ntru_crypto_ntru_decrypt(key->pri.length, key->pri.buffer,
12475         inSz, bufIn, outSz, bufOut);
12476     ntru_crypto_drbg_uninstantiate(drbg);
12477     if (ret != NTRU_OK)
12478         return NTRU_ENCRYPT_ERROR;
12479 
12480     return ret;
12481 }
12482 #endif /* HAVE_NTRU */
12483 
12484 int QSH_Init(WOLFSSL* ssl)
12485 {
12486     /* check so not initialising twice when running DTLS */
12487     if (ssl->QSH_secret != NULL)
12488         return 0;
12489 
12490     /* malloc memory for holding generated secret information */
12491     if ((ssl->QSH_secret = (QSHSecret*)XMALLOC(sizeof(QSHSecret), NULL,
12492                     DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
12493         return MEMORY_E;
12494 
12495     ssl->QSH_secret->CliSi = (buffer*)XMALLOC(sizeof(buffer), NULL,
12496             DYNAMIC_TYPE_TMP_BUFFER);
12497     if (ssl->QSH_secret->CliSi == NULL)
12498         return MEMORY_E;
12499 
12500     ssl->QSH_secret->SerSi = (buffer*)XMALLOC(sizeof(buffer), NULL,
12501             DYNAMIC_TYPE_TMP_BUFFER);
12502     if (ssl->QSH_secret->SerSi == NULL)
12503         return MEMORY_E;
12504 
12505     /* initialize variables */
12506     ssl->QSH_secret->list = NULL;
12507     ssl->QSH_secret->CliSi->length = 0;
12508     ssl->QSH_secret->CliSi->buffer = NULL;
12509     ssl->QSH_secret->SerSi->length = 0;
12510     ssl->QSH_secret->SerSi->buffer = NULL;
12511 
12512     return 0;
12513 }
12514 
12515 
12516 static int QSH_Encrypt(QSHKey* key, byte* in, word32 szIn,
12517                                                        byte* out, word32* szOut)
12518 {
12519     int ret = 0;
12520     word16 size = *szOut;
12521 
12522     WOLFSSL_MSG("Encrypting QSH key material");
12523 
12524     switch (key->name) {
12525     #ifdef HAVE_NTRU
12526         case WOLFSSL_NTRU_EESS439:
12527         case WOLFSSL_NTRU_EESS593:
12528         case WOLFSSL_NTRU_EESS743:
12529             ret = NtruSecretEncrypt(key, in, szIn, out, &size);
12530             break;
12531     #endif
12532         default:
12533             WOLFSSL_MSG("Unknown QSH encryption key!");
12534             return -1;
12535     }
12536 
12537     *szOut = size;
12538 
12539     return ret;
12540 }
12541 
12542 
12543 /* Decrypt using Quantum Safe Handshake algorithms */
12544 int QSH_Decrypt(QSHKey* key, byte* in, word32 szIn,
12545                                                        byte* out, word16* szOut)
12546 {
12547     int ret = 0;
12548     word16 size = *szOut;
12549 
12550     WOLFSSL_MSG("Decrypting QSH key material");
12551 
12552     switch (key->name) {
12553     #ifdef HAVE_NTRU
12554         case WOLFSSL_NTRU_EESS439:
12555         case WOLFSSL_NTRU_EESS593:
12556         case WOLFSSL_NTRU_EESS743:
12557             ret = NtruSecretDecrypt(key, in, szIn, out, &size);
12558             break;
12559     #endif
12560         default:
12561             WOLFSSL_MSG("Unknown QSH decryption key!");
12562             return -1;
12563     }
12564 
12565     *szOut = size;
12566 
12567     return ret;
12568 }
12569 
12570 
12571 /* Get the max cipher text for corresponding encryption scheme
12572    (encrypting  48 or max plain text whichever is smaller)
12573  */
12574 static word32 QSH_MaxSecret(QSHKey* key)
12575 {
12576     byte isNtru = 0;
12577     word16 inSz = 48;
12578     word16 outSz;
12579     DRBG_HANDLE drbg = 0;
12580     byte bufIn[48];
12581     int ret = 0;
12582 
12583     if (key == NULL || key->pub.length == 0)
12584         return 0;
12585 
12586     switch(key->name) {
12587 #ifdef HAVE_NTRU
12588             case WOLFSSL_NTRU_EESS439:
12589                 isNtru   = 1;
12590                 break;
12591             case WOLFSSL_NTRU_EESS593:
12592                 isNtru   = 1;
12593                 break;
12594             case WOLFSSL_NTRU_EESS743:
12595                 isNtru   = 1;
12596                 break;
12597 #endif
12598         default:
12599             WOLFSSL_MSG("Unknown QSH encryption scheme size!");
12600             return 0;
12601     }
12602 
12603     if (isNtru) {
12604         ret = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
12605         if (ret != DRBG_OK)
12606             return NTRU_DRBG_ERROR;
12607         ret = ntru_crypto_ntru_encrypt(drbg, key->pub.length,
12608                             key->pub.buffer, inSz, bufIn, &outSz, NULL);
12609         if (ret != NTRU_OK) {
12610             return NTRU_ENCRYPT_ERROR;
12611         }
12612         ntru_crypto_drbg_uninstantiate(drbg);
12613         return outSz;
12614     }
12615 
12616     return 0;
12617 }
12618 
12619 /* Generate the secret byte material for pms
12620    returns length on success and -1 on fail
12621  */
12622 static int QSH_GenerateSerCliSecret(WOLFSSL* ssl, byte isServer)
12623 {
12624     int sz       = 0;
12625     int plainSz  = 48; /* lesser of 48 and max plain text able to encrypt */
12626     int offset   = 0;
12627     word32 tmpSz = 0;
12628     buffer* buf;
12629     QSHKey* current = ssl->peerQSHKey;
12630     QSHScheme* schmPre = NULL;
12631     QSHScheme* schm    = NULL;
12632 
12633     if (ssl == NULL)
12634         return -1;
12635 
12636     WOLFSSL_MSG("Generating QSH secret key material");
12637 
12638     /* get size of buffer needed */
12639     while (current) {
12640         if (current->pub.length != 0) {
12641             sz += plainSz;
12642         }
12643         current = (QSHKey*)current->next;
12644     }
12645 
12646     /* allocate memory for buffer */
12647     if (isServer) {
12648         buf = ssl->QSH_secret->SerSi;
12649     }
12650     else {
12651         buf = ssl->QSH_secret->CliSi;
12652     }
12653     buf->length = sz;
12654     buf->buffer = (byte*)XMALLOC(sz, buf->buffer, DYNAMIC_TYPE_TMP_BUFFER);
12655     if (buf->buffer == NULL) {
12656         WOLFSSL_ERROR(MEMORY_E);
12657     }
12658 
12659     /* create secret information */
12660     sz = 0;
12661     current = ssl->peerQSHKey;
12662     while (current) {
12663         schm = (QSHScheme*)XMALLOC(sizeof(QSHScheme), NULL,
12664                                                        DYNAMIC_TYPE_TMP_BUFFER);
12665         if (schm == NULL)
12666             return MEMORY_E;
12667 
12668         /* initialize variables */
12669         schm->name  = 0;
12670         schm->PK    = NULL;
12671         schm->PKLen = 0;
12672         schm->next  = NULL;
12673         if (ssl->QSH_secret->list == NULL) {
12674             ssl->QSH_secret->list = schm;
12675         }
12676         else {
12677             if (schmPre)
12678                 schmPre->next = schm;
12679         }
12680 
12681         tmpSz = QSH_MaxSecret(current);
12682 
12683         if ((schm->PK = (byte*)XMALLOC(tmpSz, 0,
12684                                               DYNAMIC_TYPE_TMP_BUFFER)) == NULL)
12685             return -1;
12686 
12687         /* store info for writing extension */
12688         schm->name = current->name;
12689 
12690         /* no key to use for encryption */
12691         if (tmpSz == 0) {
12692             current = (QSHKey*)current->next;
12693             continue;
12694         }
12695 
12696         if (wc_RNG_GenerateBlock(ssl->rng, buf->buffer + offset, plainSz)
12697                                                                          != 0) {
12698             return -1;
12699         }
12700         if (QSH_Encrypt(current, buf->buffer + offset, plainSz, schm->PK,
12701                                                                  &tmpSz) != 0) {
12702             return -1;
12703         }
12704         schm->PKLen = tmpSz;
12705 
12706         sz += tmpSz;
12707         offset += plainSz;
12708         schmPre = schm;
12709         current = (QSHKey*)current->next;
12710     }
12711 
12712     return sz;
12713 }
12714 
12715 
12716 static word32 QSH_KeyGetSize(WOLFSSL* ssl)
12717 {
12718     word32 sz = 0;
12719     QSHKey* current = ssl->peerQSHKey;
12720 
12721     if (ssl == NULL)
12722         return -1;
12723 
12724     sz += OPAQUE16_LEN; /* type of extension ie 0x00 0x18 */
12725     sz += OPAQUE24_LEN;
12726     /* get size of buffer needed */
12727     while (current) {
12728         sz += OPAQUE16_LEN; /* scheme id */
12729         sz += OPAQUE16_LEN; /* encrypted key len*/
12730         sz += QSH_MaxSecret(current);
12731         current = (QSHKey*)current->next;
12732     }
12733 
12734     return sz;
12735 }
12736 
12737 
12738 /* handle QSH key Exchange
12739    return 0 on success
12740  */
12741 static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
12742 {
12743     int ret = 0;
12744 
12745     WOLFSSL_ENTER("QSH KeyExchange");
12746 
12747     ret = QSH_GenerateSerCliSecret(ssl, isServer);
12748     if (ret < 0)
12749         return MEMORY_E;
12750 
12751     return 0;
12752 }
12753 
12754 #endif /* HAVE_QSH */
12755 
12756 
12757     int SendClientKeyExchange(WOLFSSL* ssl)
12758     {
12759 #ifdef WOLFSSL_SMALL_STACK
12760         byte*  encSecret = NULL;
12761 #else
12762         byte   encSecret[MAX_ENCRYPT_SZ];
12763 #endif
12764         word32 encSz = 0;
12765         word32 idx = 0;
12766         int    ret = 0;
12767         byte   doUserRsa = 0;
12768 
12769     #ifdef HAVE_QSH
12770         word32 qshSz = 0;
12771         if (ssl->peerQSHKeyPresent) {
12772             qshSz = QSH_KeyGetSize(ssl);
12773         }
12774     #endif
12775 
12776         (void)doUserRsa;
12777 
12778 #ifdef HAVE_PK_CALLBACKS
12779     #ifndef NO_RSA
12780         if (ssl->ctx->RsaEncCb)
12781             doUserRsa = 1;
12782     #endif /* NO_RSA */
12783 #endif /*HAVE_PK_CALLBACKS */
12784 
12785     #ifdef WOLFSSL_SMALL_STACK
12786         encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL,
12787                                                        DYNAMIC_TYPE_TMP_BUFFER);
12788         if (encSecret == NULL)
12789             return MEMORY_E;
12790     #endif
12791 
12792         switch (ssl->specs.kea) {
12793         #ifndef NO_RSA
12794             case rsa_kea:
12795                 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
12796                                                                     SECRET_LEN);
12797                 if (ret != 0) {
12798                 #ifdef WOLFSSL_SMALL_STACK
12799                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12800                 #endif
12801                     return ret;
12802                 }
12803 
12804                 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
12805                 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
12806                 ssl->arrays->preMasterSz = SECRET_LEN;
12807 
12808                 if (ssl->peerRsaKey == NULL || ssl->peerRsaKeyPresent == 0) {
12809                 #ifdef WOLFSSL_SMALL_STACK
12810                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12811                 #endif
12812                     return NO_PEER_KEY;
12813                 }
12814 
12815                 if (doUserRsa) {
12816                 #ifdef HAVE_PK_CALLBACKS
12817                     #ifndef NO_RSA
12818                         encSz = MAX_ENCRYPT_SZ;
12819                         ret = ssl->ctx->RsaEncCb(ssl,
12820                                             ssl->arrays->preMasterSecret,
12821                                             SECRET_LEN,
12822                                             encSecret, &encSz,
12823                                             ssl->buffers.peerRsaKey.buffer,
12824                                             ssl->buffers.peerRsaKey.length,
12825                                             ssl->RsaEncCtx);
12826                     #endif /* NO_RSA */
12827                 #endif /*HAVE_PK_CALLBACKS */
12828                 }
12829                 else {
12830                     ret = wc_RsaPublicEncrypt(ssl->arrays->preMasterSecret,
12831                                  SECRET_LEN, encSecret, MAX_ENCRYPT_SZ,
12832                                  ssl->peerRsaKey, ssl->rng);
12833                     if (ret > 0) {
12834                         encSz = ret;
12835                         ret = 0;   /* set success to 0 */
12836                     }
12837                 }
12838                 break;
12839         #endif
12840         #ifndef NO_DH
12841             case diffie_hellman_kea:
12842                 {
12843                     buffer  serverP   = ssl->buffers.serverDH_P;
12844                     buffer  serverG   = ssl->buffers.serverDH_G;
12845                     buffer  serverPub = ssl->buffers.serverDH_Pub;
12846                 #ifdef WOLFSSL_SMALL_STACK
12847                     byte*   priv = NULL;
12848                 #else
12849                     byte    priv[ENCRYPT_LEN];
12850                 #endif
12851                     word32  privSz = 0;
12852                     DhKey   key;
12853 
12854                     if (serverP.buffer == 0 || serverG.buffer == 0 ||
12855                                                serverPub.buffer == 0) {
12856                     #ifdef WOLFSSL_SMALL_STACK
12857                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12858                     #endif
12859                         return NO_PEER_KEY;
12860                     }
12861 
12862                 #ifdef WOLFSSL_SMALL_STACK
12863                     priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
12864                                                        DYNAMIC_TYPE_TMP_BUFFER);
12865                     if (priv == NULL) {
12866                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12867                         return MEMORY_E;
12868                     }
12869                 #endif
12870 
12871                     wc_InitDhKey(&key);
12872                     ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
12873                                    serverG.buffer, serverG.length);
12874                     if (ret == 0)
12875                         /* for DH, encSecret is Yc, agree is pre-master */
12876                         ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
12877                                                 encSecret, &encSz);
12878                     if (ret == 0)
12879                         ret = wc_DhAgree(&key, ssl->arrays->preMasterSecret,
12880                                       &ssl->arrays->preMasterSz, priv, privSz,
12881                                       serverPub.buffer, serverPub.length);
12882                 #ifdef WOLFSSL_SMALL_STACK
12883                     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12884                 #endif
12885                     wc_FreeDhKey(&key);
12886                 }
12887                 break;
12888         #endif /* NO_DH */
12889         #ifndef NO_PSK
12890             case psk_kea:
12891                 {
12892                     byte* pms = ssl->arrays->preMasterSecret;
12893 
12894                     /* sanity check that PSK client callback has been set */
12895                     if (ssl->options.client_psk_cb == NULL) {
12896                         WOLFSSL_MSG("No client PSK callback set");
12897                         return PSK_KEY_ERROR;
12898                     }
12899                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
12900                         ssl->arrays->server_hint, ssl->arrays->client_identity,
12901                         MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
12902                     if (ssl->arrays->psk_keySz == 0 ||
12903                         ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
12904                     #ifdef WOLFSSL_SMALL_STACK
12905                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12906                     #endif
12907                         return PSK_KEY_ERROR;
12908                     }
12909                     encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
12910                     if (encSz > MAX_PSK_ID_LEN) {
12911                     #ifdef WOLFSSL_SMALL_STACK
12912                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12913                     #endif
12914                         return CLIENT_ID_ERROR;
12915                     }
12916                     XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
12917 
12918                     /* make psk pre master secret */
12919                     /* length of key + length 0s + length of key + key */
12920                     c16toa((word16)ssl->arrays->psk_keySz, pms);
12921                     pms += 2;
12922                     XMEMSET(pms, 0, ssl->arrays->psk_keySz);
12923                     pms += ssl->arrays->psk_keySz;
12924                     c16toa((word16)ssl->arrays->psk_keySz, pms);
12925                     pms += 2;
12926                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
12927                     ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
12928                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
12929                     ssl->arrays->psk_keySz = 0; /* No further need */
12930                 }
12931                 break;
12932         #endif /* NO_PSK */
12933         #if !defined(NO_DH) && !defined(NO_PSK)
12934             case dhe_psk_kea:
12935                 {
12936                     byte* pms = ssl->arrays->preMasterSecret;
12937                     byte* es  = encSecret;
12938                     buffer  serverP   = ssl->buffers.serverDH_P;
12939                     buffer  serverG   = ssl->buffers.serverDH_G;
12940                     buffer  serverPub = ssl->buffers.serverDH_Pub;
12941                 #ifdef WOLFSSL_SMALL_STACK
12942                     byte*   priv = NULL;
12943                 #else
12944                     byte    priv[ENCRYPT_LEN];
12945                 #endif
12946                     word32  privSz = 0;
12947                     word32  pubSz = 0;
12948                     word32  esSz = 0;
12949                     DhKey   key;
12950 
12951                     if (serverP.buffer == 0 || serverG.buffer == 0 ||
12952                                                serverPub.buffer == 0) {
12953                     #ifdef WOLFSSL_SMALL_STACK
12954                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12955                     #endif
12956                         return NO_PEER_KEY;
12957                     }
12958 
12959                     /* sanity check that PSK client callback has been set */
12960                     if (ssl->options.client_psk_cb == NULL) {
12961                         WOLFSSL_MSG("No client PSK callback set");
12962                         return PSK_KEY_ERROR;
12963                     }
12964                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
12965                          ssl->arrays->server_hint, ssl->arrays->client_identity,
12966                          MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
12967                     if (ssl->arrays->psk_keySz == 0 ||
12968                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
12969                     #ifdef WOLFSSL_SMALL_STACK
12970                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12971                     #endif
12972                         return PSK_KEY_ERROR;
12973                     }
12974                     esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
12975 
12976                     if (esSz > MAX_PSK_ID_LEN) {
12977                     #ifdef WOLFSSL_SMALL_STACK
12978                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12979                     #endif
12980                         return CLIENT_ID_ERROR;
12981                     }
12982 
12983                 #ifdef WOLFSSL_SMALL_STACK
12984                     priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
12985                                                        DYNAMIC_TYPE_TMP_BUFFER);
12986                     if (priv == NULL) {
12987                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12988                         return MEMORY_E;
12989                     }
12990                 #endif
12991                     c16toa((word16)esSz, es);
12992                     es += OPAQUE16_LEN;
12993                     XMEMCPY(es, ssl->arrays->client_identity, esSz);
12994                     es += esSz;
12995                     encSz = esSz + OPAQUE16_LEN;
12996 
12997                     wc_InitDhKey(&key);
12998                     ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
12999                                    serverG.buffer, serverG.length);
13000                     if (ret == 0)
13001                         /* for DH, encSecret is Yc, agree is pre-master */
13002                         ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
13003                                                 es + OPAQUE16_LEN, &pubSz);
13004                     if (ret == 0)
13005                         ret = wc_DhAgree(&key, pms + OPAQUE16_LEN,
13006                                       &ssl->arrays->preMasterSz, priv, privSz,
13007                                       serverPub.buffer, serverPub.length);
13008                     wc_FreeDhKey(&key);
13009                 #ifdef WOLFSSL_SMALL_STACK
13010                     XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13011                 #endif
13012                     if (ret != 0) {
13013                     #ifdef WOLFSSL_SMALL_STACK
13014                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13015                     #endif
13016                         return ret;
13017                     }
13018 
13019                     c16toa((word16)pubSz, es);
13020                     encSz += pubSz + OPAQUE16_LEN;
13021                     c16toa((word16)ssl->arrays->preMasterSz, pms);
13022                     ssl->arrays->preMasterSz += OPAQUE16_LEN;
13023                     pms += ssl->arrays->preMasterSz;
13024 
13025                     /* make psk pre master secret */
13026                     /* length of key + length 0s + length of key + key */
13027                     c16toa((word16)ssl->arrays->psk_keySz, pms);
13028                     pms += OPAQUE16_LEN;
13029                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13030                     ssl->arrays->preMasterSz +=
13031                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
13032                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13033                     ssl->arrays->psk_keySz = 0; /* No further need */
13034                 }
13035                 break;
13036         #endif /* !NO_DH && !NO_PSK */
13037         #if defined(HAVE_ECC) && !defined(NO_PSK)
13038             case ecdhe_psk_kea:
13039                 {
13040                     byte* pms = ssl->arrays->preMasterSecret;
13041                     byte* es  = encSecret;
13042                     ecc_key  myKey;
13043                     ecc_key* peerKey = NULL;
13044                     word32   size = MAX_ENCRYPT_SZ;
13045                     word32   esSz = 0;
13046 
13047                     /* sanity check that PSK client callback has been set */
13048                     if (ssl->options.client_psk_cb == NULL) {
13049                         WOLFSSL_MSG("No client PSK callback set");
13050                         return PSK_KEY_ERROR;
13051                     }
13052 
13053                     /* Send PSK client identity */
13054                     ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
13055                          ssl->arrays->server_hint, ssl->arrays->client_identity,
13056                          MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
13057                     if (ssl->arrays->psk_keySz == 0 ||
13058                                      ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
13059                     #ifdef WOLFSSL_SMALL_STACK
13060                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13061                     #endif
13062                         return PSK_KEY_ERROR;
13063                     }
13064                     esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
13065 
13066                     if (esSz > MAX_PSK_ID_LEN) {
13067                     #ifdef WOLFSSL_SMALL_STACK
13068                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13069                     #endif
13070                         return CLIENT_ID_ERROR;
13071                     }
13072 
13073                     /* place size and identity in output buffer sz:identity */
13074                     c16toa((word16)esSz, es);
13075                     es += OPAQUE16_LEN;
13076                     XMEMCPY(es, ssl->arrays->client_identity, esSz);
13077                     es += esSz;
13078                     encSz = esSz + OPAQUE16_LEN;
13079 
13080                     /* Send Client ECC public key */
13081                     if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
13082                                             !ssl->peerEccKey->dp) {
13083                     #ifdef WOLFSSL_SMALL_STACK
13084                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13085                     #endif
13086                         return NO_PEER_KEY;
13087                     }
13088                     peerKey = ssl->peerEccKey;
13089 
13090                     if (peerKey == NULL) {
13091                     #ifdef WOLFSSL_SMALL_STACK
13092                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13093                     #endif
13094                         return NO_PEER_KEY;
13095                     }
13096 
13097                     wc_ecc_init(&myKey);
13098                     ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
13099                     if (ret != 0) {
13100                     #ifdef WOLFSSL_SMALL_STACK
13101                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13102                     #endif
13103                         return ECC_MAKEKEY_ERROR;
13104                     }
13105 
13106                     /* Place ECC key in output buffer, leaving room for size */
13107                     ret = wc_ecc_export_x963(&myKey, es + 1, &size);
13108                     *es = (byte)size; /* place size of key in output buffer */
13109                     encSz += size + 1;
13110 
13111                     if (ret != 0) {
13112                     #ifdef WOLFSSL_SMALL_STACK
13113                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13114                     #endif
13115                         ret = ECC_EXPORT_ERROR;
13116                     }
13117                     else {
13118                         /* Create shared ECC key leaveing room at the begining
13119                            of buffer for size of shared key. Note sizeof
13120                            preMasterSecret is ENCRYPT_LEN currently 512 */
13121                         size = sizeof(ssl->arrays->preMasterSecret)
13122                                                                  - OPAQUE16_LEN;
13123                         ret  = wc_ecc_shared_secret(&myKey, peerKey,
13124                             ssl->arrays->preMasterSecret + OPAQUE16_LEN, &size);
13125                         if (ret != 0) {
13126                         #ifdef WOLFSSL_SMALL_STACK
13127                             XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13128                         #endif
13129                             ret = ECC_SHARED_ERROR;
13130                         }
13131                     }
13132 
13133                     wc_ecc_free(&myKey);
13134                     if (ret != 0) {
13135                     #ifdef WOLFSSL_SMALL_STACK
13136                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13137                     #endif
13138                         return ret;
13139                     }
13140 
13141                     /* Create pre master secret is the concatination of
13142                        eccSize + eccSharedKey + pskSize + pskKey */
13143                     c16toa((word16)size, pms);
13144                     ssl->arrays->preMasterSz += OPAQUE16_LEN + size;
13145                     pms += ssl->arrays->preMasterSz;
13146 
13147                     c16toa((word16)ssl->arrays->psk_keySz, pms);
13148                     pms += OPAQUE16_LEN;
13149                     XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13150                     ssl->arrays->preMasterSz +=
13151                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
13152 
13153                     ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
13154                     ssl->arrays->psk_keySz = 0; /* No further need */
13155                 }
13156                 break;
13157         #endif /* HAVE_ECC && !NO_PSK */
13158         #ifdef HAVE_NTRU
13159             case ntru_kea:
13160                 {
13161                     word32 rc;
13162                     word16 cipherLen = MAX_ENCRYPT_SZ;
13163                     DRBG_HANDLE drbg;
13164 
13165                     ret = wc_RNG_GenerateBlock(ssl->rng,
13166                                       ssl->arrays->preMasterSecret, SECRET_LEN);
13167                     if (ret != 0) {
13168                     #ifdef WOLFSSL_SMALL_STACK
13169                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13170                     #endif
13171                         return ret;
13172                     }
13173 
13174                     ssl->arrays->preMasterSz = SECRET_LEN;
13175 
13176                     if (ssl->peerNtruKeyPresent == 0) {
13177                     #ifdef WOLFSSL_SMALL_STACK
13178                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13179                     #endif
13180                         return NO_PEER_KEY;
13181                     }
13182 
13183                     rc = ntru_crypto_drbg_external_instantiate(GetEntropy, &drbg);
13184                     if (rc != DRBG_OK) {
13185                     #ifdef WOLFSSL_SMALL_STACK
13186                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13187                     #endif
13188                         return NTRU_DRBG_ERROR;
13189                     }
13190 
13191                     rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
13192                                                   ssl->peerNtruKey,
13193                                                   ssl->arrays->preMasterSz,
13194                                                   ssl->arrays->preMasterSecret,
13195                                                   &cipherLen, encSecret);
13196                     ntru_crypto_drbg_uninstantiate(drbg);
13197                     if (rc != NTRU_OK) {
13198                     #ifdef WOLFSSL_SMALL_STACK
13199                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13200                     #endif
13201                         return NTRU_ENCRYPT_ERROR;
13202                     }
13203 
13204                     encSz = cipherLen;
13205                     ret = 0;
13206                 }
13207                 break;
13208         #endif /* HAVE_NTRU */
13209         #ifdef HAVE_ECC
13210             case ecc_diffie_hellman_kea:
13211                 {
13212                     ecc_key  myKey;
13213                     ecc_key* peerKey = NULL;
13214                     word32   size = MAX_ENCRYPT_SZ;
13215 
13216                     if (ssl->specs.static_ecdh) {
13217                         /* TODO: EccDsa is really fixed Ecc change naming */
13218                         if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
13219                                                    !ssl->peerEccDsaKey->dp) {
13220                         #ifdef WOLFSSL_SMALL_STACK
13221                             XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13222                         #endif
13223                             return NO_PEER_KEY;
13224                         }
13225                         peerKey = ssl->peerEccDsaKey;
13226                     }
13227                     else {
13228                         if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
13229                                                 !ssl->peerEccKey->dp) {
13230                         #ifdef WOLFSSL_SMALL_STACK
13231                             XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13232                         #endif
13233                             return NO_PEER_KEY;
13234                         }
13235                         peerKey = ssl->peerEccKey;
13236                     }
13237 
13238                     if (peerKey == NULL) {
13239                     #ifdef WOLFSSL_SMALL_STACK
13240                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13241                     #endif
13242                         return NO_PEER_KEY;
13243                     }
13244 
13245                     wc_ecc_init(&myKey);
13246                     ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
13247                     if (ret != 0) {
13248                     #ifdef WOLFSSL_SMALL_STACK
13249                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13250                     #endif
13251                         return ECC_MAKEKEY_ERROR;
13252                     }
13253 
13254                     /* precede export with 1 byte length */
13255                     ret = wc_ecc_export_x963(&myKey, encSecret + 1, &size);
13256                     encSecret[0] = (byte)size;
13257                     encSz = size + 1;
13258 
13259                     if (ret != 0)
13260                         ret = ECC_EXPORT_ERROR;
13261                     else {
13262                         size = sizeof(ssl->arrays->preMasterSecret);
13263                         ret  = wc_ecc_shared_secret(&myKey, peerKey,
13264                                                  ssl->arrays->preMasterSecret, &size);
13265                         if (ret != 0)
13266                             ret = ECC_SHARED_ERROR;
13267                     }
13268 
13269                     ssl->arrays->preMasterSz = size;
13270                     wc_ecc_free(&myKey);
13271                 }
13272                 break;
13273         #endif /* HAVE_ECC */
13274             default:
13275             #ifdef WOLFSSL_SMALL_STACK
13276                 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13277             #endif
13278                 return ALGO_ID_E; /* unsupported kea */
13279         }
13280 
13281         if (ret == 0) {
13282             byte              *output;
13283             int                sendSz;
13284             word32             tlsSz = 0;
13285 
13286             if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
13287                 tlsSz = 2;
13288 
13289             if (ssl->specs.kea == ecc_diffie_hellman_kea ||
13290                 ssl->specs.kea == dhe_psk_kea ||
13291                 ssl->specs.kea == ecdhe_psk_kea)  /* always off */
13292                 tlsSz = 0;
13293 
13294             sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
13295             idx    = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
13296 
13297             #ifdef WOLFSSL_DTLS
13298                 if (ssl->options.dtls) {
13299                     sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
13300                     idx    += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
13301                 }
13302             #endif
13303 
13304             if (IsEncryptionOn(ssl, 1))
13305                 sendSz += MAX_MSG_EXTRA;
13306 
13307         #ifdef HAVE_QSH
13308             encSz += qshSz;
13309             sendSz += qshSz;
13310         #endif
13311 
13312             /* check for available size */
13313             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
13314             #ifdef WOLFSSL_SMALL_STACK
13315                 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13316             #endif
13317                 return ret;
13318             }
13319 
13320             /* get output buffer */
13321             output = ssl->buffers.outputBuffer.buffer +
13322                      ssl->buffers.outputBuffer.length;
13323 
13324 
13325 #ifdef HAVE_QSH
13326             if (ssl->peerQSHKeyPresent) {
13327                 byte idxSave = idx;
13328                 idx = sendSz - qshSz;
13329 
13330                 if (QSH_KeyExchangeWrite(ssl, 0) != 0)
13331                     return MEMORY_E;
13332 
13333                 /* extension type */
13334                 c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
13335                 idx += OPAQUE16_LEN;
13336 
13337                 /* write to output and check amount written */
13338                 if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
13339                                                          > qshSz - OPAQUE16_LEN)
13340                     return MEMORY_E;
13341 
13342                 idx = idxSave;
13343             }
13344 #endif
13345 
13346             AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
13347 
13348 #ifdef HAVE_QSH
13349             if (ssl->peerQSHKeyPresent) {
13350                 encSz -= qshSz;
13351             }
13352 #endif
13353             if (tlsSz) {
13354                 c16toa((word16)encSz, &output[idx]);
13355                 idx += 2;
13356             }
13357             XMEMCPY(output + idx, encSecret, encSz);
13358             idx += encSz;
13359 
13360             if (IsEncryptionOn(ssl, 1)) {
13361                 byte* input;
13362                 int   inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
13363 
13364                 input = (byte*)XMALLOC(inputSz, ssl->heap,
13365                                        DYNAMIC_TYPE_TMP_BUFFER);
13366                 if (input == NULL) {
13367                 #ifdef WOLFSSL_SMALL_STACK
13368                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13369                 #endif
13370                     return MEMORY_E;
13371                 }
13372 
13373                 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
13374                 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
13375                                       handshake, 1);
13376                 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
13377                 if (sendSz < 0) {
13378                 #ifdef WOLFSSL_SMALL_STACK
13379                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13380                 #endif
13381                     return sendSz;
13382                 }
13383             } else {
13384                 ret = HashOutput(ssl, output, sendSz, 0);
13385                 if (ret != 0) {
13386                 #ifdef WOLFSSL_SMALL_STACK
13387                     XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13388                 #endif
13389                     return ret;
13390                 }
13391             }
13392 
13393             #ifdef WOLFSSL_DTLS
13394                 if (ssl->options.dtls) {
13395                     if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
13396                     #ifdef WOLFSSL_SMALL_STACK
13397                         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13398                     #endif
13399                         return ret;
13400                     }
13401                 }
13402             #endif
13403 
13404             #ifdef WOLFSSL_CALLBACKS
13405                 if (ssl->hsInfoOn)
13406                     AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
13407                 if (ssl->toInfoOn)
13408                     AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
13409                                   output, sendSz, ssl->heap);
13410             #endif
13411 
13412             ssl->buffers.outputBuffer.length += sendSz;
13413 
13414             if (ssl->options.groupMessages)
13415                 ret = 0;
13416             else
13417                 ret = SendBuffered(ssl);
13418         }
13419 
13420     #ifdef WOLFSSL_SMALL_STACK
13421         XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13422     #endif
13423 
13424         if (ret == 0 || ret == WANT_WRITE) {
13425             int tmpRet = MakeMasterSecret(ssl);
13426             if (tmpRet != 0)
13427                 ret = tmpRet;   /* save WANT_WRITE unless more serious */
13428             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
13429         }
13430         /* No further need for PMS */
13431         ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
13432         ssl->arrays->preMasterSz = 0;
13433 
13434         return ret;
13435     }
13436 
13437 #ifndef NO_CERTS
13438 
13439 
13440     int SendCertificateVerify(WOLFSSL* ssl)
13441     {
13442         byte              *output;
13443         int                sendSz = MAX_CERT_VERIFY_SZ, length, ret;
13444         word32             idx = 0;
13445         word32             sigOutSz = 0;
13446 #ifndef NO_RSA
13447         RsaKey             key;
13448         int                initRsaKey = 0;
13449 #endif
13450         int                usingEcc = 0;
13451 #ifdef HAVE_ECC
13452         ecc_key            eccKey;
13453 #endif
13454 
13455         (void)idx;
13456 
13457         if (ssl->options.sendVerify == SEND_BLANK_CERT)
13458             return 0;  /* sent blank cert, can't verify */
13459 
13460         if (IsEncryptionOn(ssl, 1))
13461             sendSz += MAX_MSG_EXTRA;
13462 
13463         /* check for available size */
13464         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
13465             return ret;
13466 
13467         /* get output buffer */
13468         output = ssl->buffers.outputBuffer.buffer +
13469                  ssl->buffers.outputBuffer.length;
13470 
13471         ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
13472         if (ret != 0)
13473             return ret;
13474 
13475 #ifdef HAVE_ECC
13476         wc_ecc_init(&eccKey);
13477 #endif
13478 #ifndef NO_RSA
13479         ret = wc_InitRsaKey(&key, ssl->heap);
13480         if (ret == 0) initRsaKey = 1;
13481         if (ret == 0)
13482             ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key,
13483                                       ssl->buffers.key->length);
13484         if (ret == 0)
13485             sigOutSz = wc_RsaEncryptSize(&key);
13486         else
13487 #endif
13488         {
13489     #ifdef HAVE_ECC
13490             WOLFSSL_MSG("Trying ECC client cert, RSA didn't work");
13491 
13492             if (ssl->buffers.key == NULL) {
13493                 WOLFSSL_MSG("ECC Key missing");
13494                 return NO_PRIVATE_KEY;
13495             }
13496 
13497             idx = 0;
13498             ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &eccKey,
13499                                       ssl->buffers.key->length);
13500             if (ret == 0) {
13501                 WOLFSSL_MSG("Using ECC client cert");
13502                 usingEcc = 1;
13503                 sigOutSz = MAX_ENCODED_SIG_SZ;
13504             }
13505             else {
13506                 WOLFSSL_MSG("Bad client cert type");
13507             }
13508     #endif
13509         }
13510         if (ret == 0) {
13511             byte*  verify = (byte*)&output[RECORD_HEADER_SZ +
13512                                            HANDSHAKE_HEADER_SZ];
13513 #ifndef NO_OLD_TLS
13514             byte*  signBuffer = ssl->hsHashes->certHashes.md5;
13515 #else
13516             byte*  signBuffer = NULL;
13517 #endif
13518             word32 signSz = FINISHED_SZ;
13519             word32 extraSz = 0;  /* tls 1.2 hash/sig */
13520 #ifdef WOLFSSL_SMALL_STACK
13521             byte*  encodedSig = NULL;
13522 #else
13523             byte   encodedSig[MAX_ENCODED_SIG_SZ];
13524 #endif
13525 
13526 #ifdef WOLFSSL_SMALL_STACK
13527             encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
13528                                                        DYNAMIC_TYPE_TMP_BUFFER);
13529             if (encodedSig == NULL) {
13530             #ifndef NO_RSA
13531                 if (initRsaKey)
13532                     wc_FreeRsaKey(&key);
13533             #endif
13534             #ifdef HAVE_ECC
13535                 wc_ecc_free(&eccKey);
13536             #endif
13537                 return MEMORY_E;
13538             }
13539 #endif
13540 
13541             (void)encodedSig;
13542             (void)signSz;
13543             (void)signBuffer;
13544 
13545             #ifdef WOLFSSL_DTLS
13546                 if (ssl->options.dtls)
13547                     verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
13548             #endif
13549             length = sigOutSz;
13550             if (IsAtLeastTLSv1_2(ssl)) {
13551                 verify[0] = ssl->suites->hashAlgo;
13552                 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
13553                 extraSz = HASH_SIG_SIZE;
13554             }
13555 
13556             if (usingEcc) {
13557 #ifdef HAVE_ECC
13558                 word32 localSz = MAX_ENCODED_SIG_SZ;
13559                 word32 digestSz;
13560                 byte*  digest;
13561                 byte   doUserEcc = 0;
13562 #ifndef NO_OLD_TLS
13563                 /* old tls default */
13564                 digestSz = SHA_DIGEST_SIZE;
13565                 digest   = ssl->hsHashes->certHashes.sha;
13566 #else
13567                 /* new tls default */
13568                 digestSz = SHA256_DIGEST_SIZE;
13569                 digest   = ssl->hsHashes->certHashes.sha256;
13570 #endif
13571 
13572                 #ifdef HAVE_PK_CALLBACKS
13573                     #ifdef HAVE_ECC
13574                         if (ssl->ctx->EccSignCb)
13575                             doUserEcc = 1;
13576                     #endif /* HAVE_ECC */
13577                 #endif /*HAVE_PK_CALLBACKS */
13578 
13579                 if (IsAtLeastTLSv1_2(ssl)) {
13580                     if (ssl->suites->hashAlgo == sha_mac) {
13581                         #ifndef NO_SHA
13582                             digest = ssl->hsHashes->certHashes.sha;
13583                             digestSz = SHA_DIGEST_SIZE;
13584                         #endif
13585                     }
13586                     else if (ssl->suites->hashAlgo == sha256_mac) {
13587                         #ifndef NO_SHA256
13588                             digest = ssl->hsHashes->certHashes.sha256;
13589                             digestSz = SHA256_DIGEST_SIZE;
13590                         #endif
13591                     }
13592                     else if (ssl->suites->hashAlgo == sha384_mac) {
13593                         #ifdef WOLFSSL_SHA384
13594                             digest = ssl->hsHashes->certHashes.sha384;
13595                             digestSz = SHA384_DIGEST_SIZE;
13596                         #endif
13597                     }
13598                     else if (ssl->suites->hashAlgo == sha512_mac) {
13599                         #ifdef WOLFSSL_SHA512
13600                             digest = ssl->hsHashes->certHashes.sha512;
13601                             digestSz = SHA512_DIGEST_SIZE;
13602                         #endif
13603                     }
13604                 }
13605 
13606                 if (doUserEcc) {
13607                 #ifdef HAVE_PK_CALLBACKS
13608                     #ifdef HAVE_ECC
13609                         ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
13610                                         encodedSig, &localSz,
13611                                         ssl->buffers.key->buffer,
13612                                         ssl->buffers.key->length,
13613                                         ssl->EccSignCtx);
13614                     #endif /* HAVE_ECC */
13615                 #endif /*HAVE_PK_CALLBACKS */
13616                 }
13617                 else {
13618                     ret = wc_ecc_sign_hash(digest, digestSz, encodedSig,
13619                                         &localSz, ssl->rng, &eccKey);
13620                 }
13621                 if (ret == 0) {
13622                     length = localSz;
13623                     c16toa((word16)length, verify + extraSz); /* prepend hdr */
13624                     XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
13625                 }
13626 #endif
13627             }
13628 #ifndef NO_RSA
13629             else {
13630                 byte doUserRsa = 0;
13631 
13632                 #ifdef HAVE_PK_CALLBACKS
13633                     if (ssl->ctx->RsaSignCb)
13634                         doUserRsa = 1;
13635                 #endif /*HAVE_PK_CALLBACKS */
13636 
13637                 if (IsAtLeastTLSv1_2(ssl)) {
13638                     /*
13639                      * MSVC Compiler complains because it can not
13640                      * guarantee any of the conditionals will succeed in
13641                      * assigning a value before wc_EncodeSignature executes.
13642                      */
13643                     byte* digest    = NULL;
13644                     int   digestSz  = 0;
13645                     int   typeH     = 0;
13646                     int   didSet    = 0;
13647 
13648                     if (ssl->suites->hashAlgo == sha_mac) {
13649                         #ifndef NO_SHA
13650                             digest   = ssl->hsHashes->certHashes.sha;
13651                             typeH    = SHAh;
13652                             digestSz = SHA_DIGEST_SIZE;
13653                             didSet   = 1;
13654                         #endif
13655                     }
13656                     else if (ssl->suites->hashAlgo == sha256_mac) {
13657                         #ifndef NO_SHA256
13658                             digest   = ssl->hsHashes->certHashes.sha256;
13659                             typeH    = SHA256h;
13660                             digestSz = SHA256_DIGEST_SIZE;
13661                             didSet   = 1;
13662                         #endif
13663                     }
13664                     else if (ssl->suites->hashAlgo == sha384_mac) {
13665                         #ifdef WOLFSSL_SHA384
13666                             digest   = ssl->hsHashes->certHashes.sha384;
13667                             typeH    = SHA384h;
13668                             digestSz = SHA384_DIGEST_SIZE;
13669                             didSet   = 1;
13670                         #endif
13671                     }
13672                     else if (ssl->suites->hashAlgo == sha512_mac) {
13673                         #ifdef WOLFSSL_SHA512
13674                             digest   = ssl->hsHashes->certHashes.sha512;
13675                             typeH    = SHA512h;
13676                             digestSz = SHA512_DIGEST_SIZE;
13677                             didSet   = 1;
13678                         #endif
13679                     }
13680 
13681                     if (didSet == 0) {
13682                         /* defaults */
13683                         #ifndef NO_OLD_TLS
13684                             digest = ssl->hsHashes->certHashes.sha;
13685                             digestSz = SHA_DIGEST_SIZE;
13686                             typeH = SHAh;
13687                         #else
13688                             digest = ssl->hsHashes->certHashes.sha256;
13689                             digestSz = SHA256_DIGEST_SIZE;
13690                             typeH = SHA256h;
13691                         #endif
13692                     }
13693 
13694                     signSz = wc_EncodeSignature(encodedSig, digest,digestSz,typeH);
13695                     signBuffer = encodedSig;
13696                 }
13697 
13698                 c16toa((word16)length, verify + extraSz); /* prepend hdr */
13699                 if (doUserRsa) {
13700                 #ifdef HAVE_PK_CALLBACKS
13701                     #ifndef NO_RSA
13702                         word32 ioLen = ENCRYPT_LEN;
13703                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
13704                                             verify + extraSz + VERIFY_HEADER,
13705                                             &ioLen,
13706                                             ssl->buffers.key->buffer,
13707                                             ssl->buffers.key->length,
13708                                             ssl->RsaSignCtx);
13709                     #endif /* NO_RSA */
13710                 #endif /*HAVE_PK_CALLBACKS */
13711                 }
13712                 else {
13713                     ret = wc_RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
13714                                   VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
13715                 }
13716 
13717                 if (ret > 0) {
13718                     /* check for signature faults */
13719                     ret = VerifyRsaSign(verify + extraSz + VERIFY_HEADER, ret,
13720                                         signBuffer, signSz, &key);
13721                 }
13722             }
13723 #endif
13724 #ifdef WOLFSSL_SMALL_STACK
13725             XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13726 #endif
13727 
13728             if (ret == 0) {
13729                 AddHeaders(output, length + extraSz + VERIFY_HEADER,
13730                            certificate_verify, ssl);
13731 
13732                 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
13733                          extraSz + VERIFY_HEADER;
13734 
13735                 #ifdef WOLFSSL_DTLS
13736                     if (ssl->options.dtls) {
13737                         sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
13738                     }
13739                 #endif
13740 
13741                 if (IsEncryptionOn(ssl, 1)) {
13742                     byte* input;
13743                     int   inputSz = sendSz - RECORD_HEADER_SZ;
13744                                     /* build msg adds rec hdr */
13745                     input = (byte*)XMALLOC(inputSz, ssl->heap,
13746                                            DYNAMIC_TYPE_TMP_BUFFER);
13747                     if (input == NULL)
13748                         ret = MEMORY_E;
13749                     else {
13750                         XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
13751                         sendSz = BuildMessage(ssl, output,
13752                                               MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
13753                                               input, inputSz, handshake, 1);
13754                         XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
13755 
13756                         if (sendSz < 0)
13757                             ret = sendSz;
13758                     }
13759                 } else {
13760                     ret = HashOutput(ssl, output, sendSz, 0);
13761                 }
13762 
13763                 #ifdef WOLFSSL_DTLS
13764                     if (ssl->options.dtls) {
13765                         if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
13766                             return ret;
13767                     }
13768                 #endif
13769             }
13770         }
13771 #ifndef NO_RSA
13772         if (initRsaKey)
13773             wc_FreeRsaKey(&key);
13774 #endif
13775 #ifdef HAVE_ECC
13776         wc_ecc_free(&eccKey);
13777 #endif
13778 
13779         if (ret == 0) {
13780             #ifdef WOLFSSL_CALLBACKS
13781                 if (ssl->hsInfoOn)
13782                     AddPacketName("CertificateVerify", &ssl->handShakeInfo);
13783                 if (ssl->toInfoOn)
13784                     AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
13785                                   output, sendSz, ssl->heap);
13786             #endif
13787             ssl->buffers.outputBuffer.length += sendSz;
13788             if (ssl->options.groupMessages)
13789                 return 0;
13790             else
13791                 return SendBuffered(ssl);
13792         }
13793         else
13794             return ret;
13795     }
13796 #endif /* NO_CERTS */
13797 
13798 #ifdef HAVE_SESSION_TICKET
13799 int DoSessionTicket(WOLFSSL* ssl,
13800                                const byte* input, word32* inOutIdx, word32 size)
13801 {
13802     word32 begin = *inOutIdx;
13803     word32 lifetime;
13804     word16 length;
13805 
13806     if (ssl->expect_session_ticket == 0) {
13807         WOLFSSL_MSG("Unexpected session ticket");
13808         return SESSION_TICKET_EXPECT_E;
13809     }
13810 
13811     if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
13812         return BUFFER_ERROR;
13813 
13814     ato32(input + *inOutIdx, &lifetime);
13815     *inOutIdx += OPAQUE32_LEN;
13816 
13817     if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
13818         return BUFFER_ERROR;
13819 
13820     ato16(input + *inOutIdx, &length);
13821     *inOutIdx += OPAQUE16_LEN;
13822 
13823     if (length > sizeof(ssl->session.ticket))
13824         return SESSION_TICKET_LEN_E;
13825 
13826     if ((*inOutIdx - begin) + length > size)
13827         return BUFFER_ERROR;
13828 
13829     /* If the received ticket including its length is greater than
13830      * a length value, the save it. Otherwise, don't save it. */
13831     if (length > 0) {
13832         XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
13833         *inOutIdx += length;
13834         ssl->session.ticketLen = length;
13835         ssl->timeout = lifetime;
13836         if (ssl->session_ticket_cb != NULL) {
13837             ssl->session_ticket_cb(ssl,
13838                                    ssl->session.ticket, ssl->session.ticketLen,
13839                                    ssl->session_ticket_ctx);
13840         }
13841         /* Create a fake sessionID based on the ticket, this will
13842          * supercede the existing session cache info. */
13843         ssl->options.haveSessionId = 1;
13844         XMEMCPY(ssl->arrays->sessionID,
13845                                  ssl->session.ticket + length - ID_LEN, ID_LEN);
13846 #ifndef NO_SESSION_CACHE
13847         AddSession(ssl);
13848 #endif
13849 
13850     }
13851     else {
13852         ssl->session.ticketLen = 0;
13853     }
13854 
13855     if (IsEncryptionOn(ssl, 0)) {
13856         *inOutIdx += ssl->keys.padSz;
13857     }
13858 
13859     ssl->expect_session_ticket = 0;
13860 
13861     return 0;
13862 }
13863 #endif /* HAVE_SESSION_TICKET */
13864 
13865 #endif /* NO_WOLFSSL_CLIENT */
13866 
13867 
13868 #ifndef NO_WOLFSSL_SERVER
13869 
13870     int SendServerHello(WOLFSSL* ssl)
13871     {
13872         byte              *output;
13873         word32             length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
13874         int                sendSz;
13875         int                ret;
13876         byte               sessIdSz = ID_LEN;
13877 
13878         length = VERSION_SZ + RAN_LEN
13879                + ID_LEN + ENUM_LEN
13880                + SUITE_LEN
13881                + ENUM_LEN;
13882 
13883 #ifdef HAVE_TLS_EXTENSIONS
13884         length += TLSX_GetResponseSize(ssl);
13885     #ifdef HAVE_SESSION_TICKET
13886         if (ssl->options.useTicket && ssl->arrays->sessionIDSz == 0) {
13887             /* no session id */
13888             length  -= ID_LEN;
13889             sessIdSz = 0;
13890         }
13891     #endif /* HAVE_SESSION_TICKET */
13892 #endif
13893 
13894         /* check for avalaible size */
13895         if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
13896             return ret;
13897 
13898         /* get output buffer */
13899         output = ssl->buffers.outputBuffer.buffer +
13900                  ssl->buffers.outputBuffer.length;
13901 
13902         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
13903         #ifdef WOLFSSL_DTLS
13904         if (ssl->options.dtls) {
13905             /* Server Hello should use the same sequence number as the
13906              * Client Hello. */
13907             ssl->keys.dtls_sequence_number = ssl->keys.dtls_state.curSeq;
13908             idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
13909             sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
13910         }
13911         #endif /* WOLFSSL_DTLS */
13912         AddHeaders(output, length, server_hello, ssl);
13913 
13914         /* now write to output */
13915         /* first version */
13916         output[idx++] = ssl->version.major;
13917         output[idx++] = ssl->version.minor;
13918 
13919         /* then random and session id */
13920         if (!ssl->options.resuming) {
13921             /* generate random part and session id */
13922             ret = wc_RNG_GenerateBlock(ssl->rng, output + idx,
13923                 RAN_LEN + sizeof(sessIdSz) + sessIdSz);
13924             if (ret != 0)
13925                 return ret;
13926 
13927             /* store info in SSL for later */
13928             XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
13929             idx += RAN_LEN;
13930             output[idx++] = sessIdSz;
13931             XMEMCPY(ssl->arrays->sessionID, output + idx, sessIdSz);
13932         }
13933         else {
13934             /* If resuming, use info from SSL */
13935             XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
13936             idx += RAN_LEN;
13937             output[idx++] = sessIdSz;
13938             XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
13939         }
13940         idx += sessIdSz;
13941 
13942 #ifdef SHOW_SECRETS
13943         {
13944             int j;
13945             printf("server random: ");
13946             for (j = 0; j < RAN_LEN; j++)
13947                 printf("%02x", ssl->arrays->serverRandom[j]);
13948             printf("\n");
13949         }
13950 #endif
13951 
13952         /* then cipher suite */
13953         output[idx++] = ssl->options.cipherSuite0;
13954         output[idx++] = ssl->options.cipherSuite;
13955 
13956         /* then compression */
13957         if (ssl->options.usingCompression)
13958             output[idx++] = ZLIB_COMPRESSION;
13959         else
13960             output[idx++] = NO_COMPRESSION;
13961 
13962         /* last, extensions */
13963 #ifdef HAVE_TLS_EXTENSIONS
13964         TLSX_WriteResponse(ssl, output + idx);
13965 #endif
13966 
13967         ssl->buffers.outputBuffer.length += sendSz;
13968         #ifdef WOLFSSL_DTLS
13969             if (ssl->options.dtls) {
13970                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
13971                     return ret;
13972             }
13973         #endif
13974 
13975         ret = HashOutput(ssl, output, sendSz, 0);
13976         if (ret != 0)
13977             return ret;
13978 
13979     #ifdef WOLFSSL_CALLBACKS
13980         if (ssl->hsInfoOn)
13981             AddPacketName("ServerHello", &ssl->handShakeInfo);
13982         if (ssl->toInfoOn)
13983             AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
13984                           ssl->heap);
13985     #endif
13986 
13987         ssl->options.serverState = SERVER_HELLO_COMPLETE;
13988 
13989         if (ssl->options.groupMessages)
13990             return 0;
13991         else
13992             return SendBuffered(ssl);
13993     }
13994 
13995 
13996 #ifdef HAVE_ECC
13997 
13998     static byte SetCurveId(int size)
13999     {
14000         switch(size) {
14001 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
14002             case 20:
14003                 return WOLFSSL_ECC_SECP160R1;
14004 #endif
14005 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
14006             case 24:
14007                 return WOLFSSL_ECC_SECP192R1;
14008 #endif
14009 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
14010             case 28:
14011                 return WOLFSSL_ECC_SECP224R1;
14012 #endif
14013 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
14014             case 32:
14015                 return WOLFSSL_ECC_SECP256R1;
14016 #endif
14017 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
14018             case 48:
14019                 return WOLFSSL_ECC_SECP384R1;
14020 #endif
14021 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
14022             case 66:
14023                 return WOLFSSL_ECC_SECP521R1;
14024 #endif
14025             default:
14026                 return 0;
14027         }
14028     }
14029 
14030 #endif /* HAVE_ECC */
14031 
14032 
14033     int SendServerKeyExchange(WOLFSSL* ssl)
14034     {
14035         int ret = 0;
14036     #ifdef HAVE_QSH
14037         word32 qshSz = 0;
14038     #endif
14039         (void)ssl;
14040         #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
14041 
14042     #ifdef HAVE_QSH
14043         if (ssl->peerQSHKeyPresent && ssl->options.haveQSH) {
14044             qshSz = QSH_KeyGetSize(ssl);
14045         }
14046     #endif
14047 
14048 
14049         switch(ssl->specs.kea)
14050         {
14051     #ifndef NO_PSK
14052         case psk_kea:
14053         {
14054             byte    *output;
14055             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
14056             int      sendSz;
14057             if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
14058 
14059             /* include size part */
14060             length = (word32)XSTRLEN(ssl->arrays->server_hint);
14061             if (length > MAX_PSK_ID_LEN) {
14062                 return SERVER_HINT_ERROR;
14063             }
14064 
14065             length += HINT_LEN_SZ;
14066             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
14067 
14068         #ifdef HAVE_QSH
14069             length += qshSz;
14070             sendSz += qshSz;
14071         #endif
14072 
14073         #ifdef WOLFSSL_DTLS
14074             if (ssl->options.dtls) {
14075                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14076                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14077             }
14078         #endif
14079             /* check for available size */
14080             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
14081                 return ret;
14082             }
14083 
14084             /* get output buffer */
14085             output = ssl->buffers.outputBuffer.buffer +
14086                      ssl->buffers.outputBuffer.length;
14087 
14088             AddHeaders(output, length, server_key_exchange, ssl);
14089 
14090             /* key data */
14091         #ifdef HAVE_QSH
14092             c16toa((word16)(length - qshSz - HINT_LEN_SZ), output + idx);
14093         #else
14094             c16toa((word16)(length - HINT_LEN_SZ), output + idx);
14095         #endif
14096             idx += HINT_LEN_SZ;
14097             XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
14098 
14099         #ifdef HAVE_QSH
14100             if (ssl->peerQSHKeyPresent) {
14101                 if (qshSz > 0) {
14102                     idx = sendSz - qshSz;
14103                     if (QSH_KeyExchangeWrite(ssl, 1) != 0) {
14104                         return MEMORY_E;
14105                     }
14106 
14107                     /* extension type */
14108                     c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
14109                     idx += OPAQUE16_LEN;
14110 
14111                     /* write to output and check amount written */
14112                     if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
14113                                                       > qshSz - OPAQUE16_LEN) {
14114                         return MEMORY_E;
14115                     }
14116                 }
14117             }
14118         #endif
14119 
14120         #ifdef WOLFSSL_DTLS
14121             if (ssl->options.dtls) {
14122                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
14123                     return ret;
14124                 }
14125             }
14126         #endif
14127 
14128             ret = HashOutput(ssl, output, sendSz, 0);
14129             if (ret != 0) {
14130                 return ret;
14131             }
14132 
14133         #ifdef WOLFSSL_CALLBACKS
14134             if (ssl->hsInfoOn) {
14135                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
14136             }
14137             if (ssl->toInfoOn) {
14138                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
14139                                                             sendSz, ssl->heap);
14140             }
14141         #endif
14142 
14143             ssl->buffers.outputBuffer.length += sendSz;
14144             if (ssl->options.groupMessages) {
14145                 ret = 0;
14146             }
14147             else {
14148                 ret = SendBuffered(ssl);
14149             }
14150             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
14151             break;
14152         }
14153     #endif /*NO_PSK */
14154 
14155     #if !defined(NO_DH) && !defined(NO_PSK)
14156         case dhe_psk_kea:
14157         {
14158             byte    *output;
14159             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
14160             word32   hintLen;
14161             int      sendSz;
14162             DhKey    dhKey;
14163 
14164             if (ssl->buffers.serverDH_P.buffer == NULL ||
14165             ssl->buffers.serverDH_G.buffer == NULL) {
14166                 return NO_DH_PARAMS;
14167             }
14168 
14169             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
14170                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
14171                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
14172                         DYNAMIC_TYPE_DH);
14173                 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
14174                     return MEMORY_E;
14175                 }
14176             }
14177 
14178             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
14179                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
14180                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
14181                         DYNAMIC_TYPE_DH);
14182                 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
14183                     return MEMORY_E;
14184                 }
14185             }
14186 
14187             wc_InitDhKey(&dhKey);
14188             ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
14189                                    ssl->buffers.serverDH_P.length,
14190                                    ssl->buffers.serverDH_G.buffer,
14191                                    ssl->buffers.serverDH_G.length);
14192             if (ret == 0) {
14193                 ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
14194                                          ssl->buffers.serverDH_Priv.buffer,
14195                                         &ssl->buffers.serverDH_Priv.length,
14196                                          ssl->buffers.serverDH_Pub.buffer,
14197                                         &ssl->buffers.serverDH_Pub.length);
14198             }
14199             wc_FreeDhKey(&dhKey);
14200             if (ret != 0) {
14201                 return ret;
14202             }
14203 
14204             length = LENGTH_SZ * 3 + /* p, g, pub */
14205                      ssl->buffers.serverDH_P.length +
14206                      ssl->buffers.serverDH_G.length +
14207                      ssl->buffers.serverDH_Pub.length;
14208 
14209             /* include size part */
14210             hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
14211             if (hintLen > MAX_PSK_ID_LEN) {
14212                 return SERVER_HINT_ERROR;
14213             }
14214             length += hintLen + HINT_LEN_SZ;
14215             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
14216 
14217         #ifdef HAVE_QSH
14218             length += qshSz;
14219             sendSz += qshSz;
14220         #endif
14221         #ifdef WOLFSSL_DTLS
14222             if (ssl->options.dtls) {
14223                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14224                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14225             }
14226         #endif
14227 
14228             /* check for available size */
14229             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
14230                 return ret;
14231             }
14232 
14233             /* get output buffer */
14234             output = ssl->buffers.outputBuffer.buffer +
14235                      ssl->buffers.outputBuffer.length;
14236 
14237             AddHeaders(output, length, server_key_exchange, ssl);
14238 
14239             /* key data */
14240             c16toa((word16)hintLen, output + idx);
14241             idx += HINT_LEN_SZ;
14242             XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
14243             idx += hintLen;
14244 
14245             /* add p, g, pub */
14246             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
14247             idx += LENGTH_SZ;
14248             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
14249                                   ssl->buffers.serverDH_P.length);
14250             idx += ssl->buffers.serverDH_P.length;
14251 
14252             /*  g */
14253             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
14254             idx += LENGTH_SZ;
14255             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
14256                                   ssl->buffers.serverDH_G.length);
14257             idx += ssl->buffers.serverDH_G.length;
14258 
14259             /*  pub */
14260             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
14261             idx += LENGTH_SZ;
14262             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
14263                                   ssl->buffers.serverDH_Pub.length);
14264             idx += ssl->buffers.serverDH_Pub.length;
14265             (void)idx; /* suppress analyzer warning, and keep idx current */
14266 
14267         #ifdef HAVE_QSH
14268             if (ssl->peerQSHKeyPresent) {
14269                 if (qshSz > 0) {
14270                     idx = sendSz - qshSz;
14271                     QSH_KeyExchangeWrite(ssl, 1);
14272 
14273                     /* extension type */
14274                     c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
14275                     idx += OPAQUE16_LEN;
14276 
14277                     /* write to output and check amount written */
14278                     if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
14279                                                       > qshSz - OPAQUE16_LEN) {
14280                         return MEMORY_E;
14281                     }
14282                 }
14283             }
14284         #endif
14285 
14286         #ifdef WOLFSSL_DTLS
14287             if (ssl->options.dtls) {
14288                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
14289                     return ret;
14290                 }
14291             }
14292         #endif
14293 
14294             ret = HashOutput(ssl, output, sendSz, 0);
14295 
14296             if (ret != 0) {
14297                 return ret;
14298             }
14299 
14300         #ifdef WOLFSSL_CALLBACKS
14301             if (ssl->hsInfoOn) {
14302                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
14303             }
14304             if (ssl->toInfoOn) {
14305                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
14306                                                             sendSz, ssl->heap);
14307             }
14308         #endif
14309 
14310             ssl->buffers.outputBuffer.length += sendSz;
14311             if (ssl->options.groupMessages) {
14312                 ret = 0;
14313             }
14314             else {
14315                 ret = SendBuffered(ssl);
14316             }
14317             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
14318             break;
14319         }
14320     #endif /* !NO_DH && !NO_PSK */
14321 
14322     #if defined(HAVE_ECC) && !defined(NO_PSK)
14323         case ecdhe_psk_kea:
14324         {
14325             word32   hintLen;
14326             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
14327             int      sendSz;
14328             byte     *output;
14329             ecc_key  dsaKey;
14330         #ifdef WOLFSSL_SMALL_STACK
14331             byte*    exportBuf = NULL;
14332         #else
14333             byte     exportBuf[MAX_EXPORT_ECC_SZ];
14334         #endif
14335             word32   expSz = MAX_EXPORT_ECC_SZ;
14336 
14337             /* curve type, named curve, length(1) */
14338             length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
14339             /* pub key size */
14340             WOLFSSL_MSG("Using ephemeral ECDH");
14341 
14342             /* need ephemeral key now, create it if missing */
14343             if (ssl->eccTempKey == NULL) {
14344                 /* alloc/init on demand */
14345                 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
14346                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
14347                 if (ssl->eccTempKey == NULL) {
14348                     WOLFSSL_MSG("EccTempKey Memory error");
14349                     return MEMORY_E;
14350                 }
14351                 wc_ecc_init(ssl->eccTempKey);
14352             }
14353             if (ssl->eccTempKeyPresent == 0) {
14354                 if (wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz,
14355                                  ssl->eccTempKey) != 0) {
14356                     return ECC_MAKEKEY_ERROR;
14357                 }
14358                 ssl->eccTempKeyPresent = 1;
14359             }
14360 
14361         #ifdef WOLFSSL_SMALL_STACK
14362             exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
14363                                                       DYNAMIC_TYPE_TMP_BUFFER);
14364             if (exportBuf == NULL) {
14365                 return MEMORY_E;
14366             }
14367         #endif
14368 
14369             if (wc_ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0) {
14370                 #ifdef WOLFSSL_SMALL_STACK
14371                     XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14372                 #endif
14373                 return ECC_EXPORT_ERROR;
14374             }
14375             length += expSz;
14376 
14377             /* include size part */
14378             hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
14379             if (hintLen > MAX_PSK_ID_LEN) {
14380                 #ifdef WOLFSSL_SMALL_STACK
14381                     XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14382                 #endif
14383                 return SERVER_HINT_ERROR;
14384             }
14385             length += hintLen + HINT_LEN_SZ;
14386             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
14387 
14388         #ifdef HAVE_QSH
14389             length += qshSz;
14390             sendSz += qshSz;
14391         #endif
14392         #ifdef WOLFSSL_DTLS
14393             if (ssl->options.dtls) {
14394                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14395                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14396             }
14397         #endif
14398             /* check for available size */
14399             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
14400                 wc_ecc_free(&dsaKey);
14401                 #ifdef WOLFSSL_SMALL_STACK
14402                     XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14403                 #endif
14404                 return ret;
14405             }
14406 
14407             /* get output buffer */
14408             output = ssl->buffers.outputBuffer.buffer +
14409                      ssl->buffers.outputBuffer.length;
14410 
14411             /* key data */
14412             c16toa((word16)hintLen, output + idx);
14413             idx += HINT_LEN_SZ;
14414             XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
14415             idx += hintLen;
14416 
14417             /* ECC key exchange data */
14418             output[idx++] = named_curve;
14419             output[idx++] = 0x00;          /* leading zero */
14420             output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey));
14421             output[idx++] = (byte)expSz;
14422             XMEMCPY(output + idx, exportBuf, expSz);
14423             #ifdef WOLFSSL_SMALL_STACK
14424                 XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14425             #endif
14426 
14427         #ifdef HAVE_QSH
14428             if (ssl->peerQSHKeyPresent) {
14429                 if (qshSz > 0) {
14430                     idx = sendSz - qshSz;
14431                     QSH_KeyExchangeWrite(ssl, 1);
14432 
14433                     /* extension type */
14434                     c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
14435                     idx += OPAQUE16_LEN;
14436 
14437                     /* write to output and check amount written */
14438                     if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
14439                                                       > qshSz - OPAQUE16_LEN) {
14440                         return MEMORY_E;
14441                     }
14442                 }
14443             }
14444         #endif
14445 
14446 
14447             AddHeaders(output, length, server_key_exchange, ssl);
14448 
14449         #ifdef WOLFSSL_DTLS
14450             if (ssl->options.dtls) {
14451                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
14452                     return ret;
14453                 }
14454             }
14455         #endif
14456 
14457             ret = HashOutput(ssl, output, sendSz, 0);
14458 
14459             if (ret != 0) {
14460                 return ret;
14461             }
14462 
14463         #ifdef WOLFSSL_CALLBACKS
14464             if (ssl->hsInfoOn) {
14465                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
14466             }
14467             if (ssl->toInfoOn) {
14468                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
14469                                                             sendSz, ssl->heap);
14470             }
14471         #endif
14472 
14473             ssl->buffers.outputBuffer.length += sendSz;
14474             if (ssl->options.groupMessages) {
14475                 ret = 0;
14476             }
14477             else {
14478                 ret = SendBuffered(ssl);
14479             }
14480             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
14481             break;
14482         }
14483     #endif /* HAVE_ECC && !NO_PSK */
14484 
14485     #ifdef HAVE_ECC
14486         case ecc_diffie_hellman_kea:
14487         {
14488             byte    *output;
14489             word32   length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
14490             int      sendSz;
14491             word32   sigSz;
14492             word32   preSigSz, preSigIdx;
14493         #ifndef NO_RSA
14494             RsaKey   rsaKey;
14495         #endif
14496             ecc_key  dsaKey;
14497         #ifdef WOLFSSL_SMALL_STACK
14498             byte*    exportBuf = NULL;
14499         #else
14500             byte     exportBuf[MAX_EXPORT_ECC_SZ];
14501         #endif
14502             word32   expSz = MAX_EXPORT_ECC_SZ;
14503 
14504         #ifndef NO_OLD_TLS
14505             byte doMd5 = 0;
14506             byte doSha = 0;
14507         #endif
14508         #ifndef NO_SHA256
14509             byte doSha256 = 0;
14510         #endif
14511         #ifdef WOLFSSL_SHA384
14512             byte doSha384 = 0;
14513         #endif
14514         #ifdef WOLFSSL_SHA512
14515             byte doSha512 = 0;
14516         #endif
14517 
14518             if (ssl->specs.static_ecdh) {
14519                 WOLFSSL_MSG("Using Static ECDH, not sending ServerKeyExchange");
14520                 return 0;
14521             }
14522 
14523             /* curve type, named curve, length(1) */
14524             length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
14525             /* pub key size */
14526             WOLFSSL_MSG("Using ephemeral ECDH");
14527 
14528             /* need ephemeral key now, create it if missing */
14529             if (ssl->eccTempKey == NULL) {
14530                 /* alloc/init on demand */
14531                 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
14532                                              ssl->ctx->heap, DYNAMIC_TYPE_ECC);
14533                 if (ssl->eccTempKey == NULL) {
14534                     WOLFSSL_MSG("EccTempKey Memory error");
14535                     return MEMORY_E;
14536                 }
14537                 wc_ecc_init(ssl->eccTempKey);
14538             }
14539             if (ssl->eccTempKeyPresent == 0) {
14540                 if (wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz,
14541                                  ssl->eccTempKey) != 0) {
14542                     return ECC_MAKEKEY_ERROR;
14543                 }
14544                 ssl->eccTempKeyPresent = 1;
14545             }
14546 
14547         #ifdef WOLFSSL_SMALL_STACK
14548             exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
14549                                                       DYNAMIC_TYPE_TMP_BUFFER);
14550             if (exportBuf == NULL) {
14551                 return MEMORY_E;
14552             }
14553         #endif
14554 
14555             if (wc_ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0) {
14556                 ERROR_OUT(ECC_EXPORT_ERROR, done_a);
14557             }
14558             length += expSz;
14559 
14560             preSigSz  = length;
14561             preSigIdx = idx;
14562 
14563         #ifndef NO_RSA
14564             ret = wc_InitRsaKey(&rsaKey, ssl->heap);
14565             if (ret != 0) {
14566                 goto done_a;
14567             }
14568         #endif
14569 
14570             wc_ecc_init(&dsaKey);
14571 
14572             /* sig length */
14573             length += LENGTH_SZ;
14574 
14575             if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
14576             #ifndef NO_RSA
14577                 wc_FreeRsaKey(&rsaKey);
14578             #endif
14579                 wc_ecc_free(&dsaKey);
14580                 ERROR_OUT(NO_PRIVATE_KEY, done_a);
14581             }
14582 
14583         #ifndef NO_RSA
14584             if (ssl->specs.sig_algo == rsa_sa_algo) {
14585                 /* rsa sig size */
14586                 word32 i = 0;
14587                 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &i,
14588                                           &rsaKey, ssl->buffers.key->length);
14589                 if (ret != 0) {
14590                     goto done_a;
14591                 }
14592                 sigSz = wc_RsaEncryptSize(&rsaKey);
14593             } else
14594         #endif
14595 
14596             if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
14597                 /* ecdsa sig size */
14598                 word32 i = 0;
14599                 ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &i,
14600                                           &dsaKey, ssl->buffers.key->length);
14601                 if (ret != 0) {
14602                     goto done_a;
14603                 }
14604                 sigSz = wc_ecc_sig_size(&dsaKey);  /* worst case estimate */
14605             }
14606             else {
14607             #ifndef NO_RSA
14608                 wc_FreeRsaKey(&rsaKey);
14609             #endif
14610                 wc_ecc_free(&dsaKey);
14611                 ERROR_OUT(ALGO_ID_E, done_a);  /* unsupported type */
14612             }
14613             length += sigSz;
14614 
14615             if (IsAtLeastTLSv1_2(ssl)) {
14616                 length += HASH_SIG_SIZE;
14617             }
14618 
14619             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
14620 
14621         #ifdef HAVE_QSH
14622             length += qshSz;
14623             sendSz += qshSz;
14624         #endif
14625         #ifdef WOLFSSL_DTLS
14626             if (ssl->options.dtls) {
14627                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14628                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
14629                 preSigIdx = idx;
14630             }
14631         #endif
14632             /* check for available size */
14633             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
14634             #ifndef NO_RSA
14635                 wc_FreeRsaKey(&rsaKey);
14636             #endif
14637                 wc_ecc_free(&dsaKey);
14638                 goto done_a;
14639             }
14640 
14641             /* get output buffer */
14642             output = ssl->buffers.outputBuffer.buffer +
14643                      ssl->buffers.outputBuffer.length;
14644 
14645             /* record and message headers will be added below, when we're sure
14646                of the sig length */
14647 
14648             /* key exchange data */
14649             output[idx++] = named_curve;
14650             output[idx++] = 0x00;          /* leading zero */
14651             output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey));
14652             output[idx++] = (byte)expSz;
14653             XMEMCPY(output + idx, exportBuf, expSz);
14654             idx += expSz;
14655             if (IsAtLeastTLSv1_2(ssl)) {
14656                 byte setHash = 0;
14657 
14658                 output[idx++] = ssl->suites->hashAlgo;
14659                 output[idx++] = ssl->suites->sigAlgo;
14660 
14661                 switch (ssl->suites->hashAlgo) {
14662                     case sha512_mac:
14663                         #ifdef WOLFSSL_SHA512
14664                             doSha512 = 1;
14665                             setHash  = 1;
14666                         #endif
14667                         break;
14668 
14669                     case sha384_mac:
14670                         #ifdef WOLFSSL_SHA384
14671                             doSha384 = 1;
14672                             setHash  = 1;
14673                         #endif
14674                         break;
14675 
14676                     case sha256_mac:
14677                         #ifndef NO_SHA256
14678                             doSha256 = 1;
14679                             setHash  = 1;
14680                         #endif
14681                         break;
14682 
14683                     case sha_mac:
14684                         #ifndef NO_OLD_TLS
14685                             doSha = 1;
14686                             setHash  = 1;
14687                         #endif
14688                         break;
14689 
14690                     default:
14691                         WOLFSSL_MSG("Bad hash sig algo");
14692                         break;
14693                 }
14694 
14695                 if (setHash == 0) {
14696                     #ifndef NO_RSA
14697                         wc_FreeRsaKey(&rsaKey);
14698                     #endif
14699                     wc_ecc_free(&dsaKey);
14700                     ERROR_OUT(ALGO_ID_E, done_a);
14701                 }
14702             } else {
14703                 /* only using sha and md5 for rsa */
14704                 #ifndef NO_OLD_TLS
14705                     doSha = 1;
14706                     if (ssl->suites->sigAlgo == rsa_sa_algo) {
14707                         doMd5 = 1;
14708                     }
14709                 #else
14710                     #ifndef NO_RSA
14711                         wc_FreeRsaKey(&rsaKey);
14712                     #endif
14713                     wc_ecc_free(&dsaKey);
14714                     ERROR_OUT(ALGO_ID_E, done_a);
14715                 #endif
14716             }
14717 
14718             /* Signtaure length will be written later, when we're sure what it
14719                is */
14720 
14721         #ifdef HAVE_FUZZER
14722             if (ssl->fuzzerCb) {
14723                 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz,
14724                                                FUZZ_SIGNATURE, ssl->fuzzerCtx);
14725             }
14726         #endif
14727 
14728             /* do signature */
14729             {
14730         #ifndef NO_OLD_TLS
14731             #ifdef WOLFSSL_SMALL_STACK
14732                 Md5*   md5  = NULL;
14733                 Sha*   sha  = NULL;
14734             #else
14735                 Md5    md5[1];
14736                 Sha    sha[1];
14737             #endif
14738         #endif
14739             #ifdef WOLFSSL_SMALL_STACK
14740                 byte*  hash = NULL;
14741             #else
14742                 byte   hash[FINISHED_SZ];
14743             #endif
14744         #ifndef NO_SHA256
14745             #ifdef WOLFSSL_SMALL_STACK
14746                 Sha256* sha256  = NULL;
14747                 byte*   hash256 = NULL;
14748             #else
14749                 Sha256  sha256[1];
14750                 byte    hash256[SHA256_DIGEST_SIZE];
14751             #endif
14752         #endif
14753         #ifdef WOLFSSL_SHA384
14754             #ifdef WOLFSSL_SMALL_STACK
14755                 Sha384* sha384  = NULL;
14756                 byte*   hash384 = NULL;
14757             #else
14758                 Sha384  sha384[1];
14759                 byte    hash384[SHA384_DIGEST_SIZE];
14760             #endif
14761         #endif
14762         #ifdef WOLFSSL_SHA512
14763             #ifdef WOLFSSL_SMALL_STACK
14764                 Sha512* sha512  = NULL;
14765                 byte*   hash512 = NULL;
14766             #else
14767                 Sha512  sha512[1];
14768                 byte    hash512[SHA512_DIGEST_SIZE];
14769             #endif
14770         #endif
14771 
14772             #ifdef WOLFSSL_SMALL_STACK
14773                 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
14774                                                       DYNAMIC_TYPE_TMP_BUFFER);
14775                 if (hash == NULL) {
14776                     ERROR_OUT(MEMORY_E, done_a);
14777                 }
14778             #endif
14779 
14780         #ifndef NO_OLD_TLS
14781                 /* md5 */
14782             #ifdef WOLFSSL_SMALL_STACK
14783                 if (doMd5) {
14784                     md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
14785                                         DYNAMIC_TYPE_TMP_BUFFER);
14786                     if (md5 == NULL) {
14787                         ERROR_OUT(MEMORY_E, done_a2);
14788                     }
14789                 }
14790             #endif
14791                 if (doMd5) {
14792                     wc_InitMd5(md5);
14793                     wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
14794                     wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
14795                     wc_Md5Update(md5, output + preSigIdx, preSigSz);
14796                     wc_Md5Final(md5, hash);
14797                 }
14798                 /* sha */
14799             #ifdef WOLFSSL_SMALL_STACK
14800                 if (doSha) {
14801                     sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
14802                                         DYNAMIC_TYPE_TMP_BUFFER);
14803                     if (sha == NULL) {
14804                         ERROR_OUT(MEMORY_E, done_a2);
14805                     }
14806                 }
14807             #endif
14808                 if (doSha) {
14809                     ret = wc_InitSha(sha);
14810                     if (ret != 0) {
14811                         goto done_a2;
14812                     }
14813                     wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
14814                     wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
14815                     wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
14816                     wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
14817                 }
14818         #endif
14819 
14820         #ifndef NO_SHA256
14821             #ifdef WOLFSSL_SMALL_STACK
14822                 if (doSha256) {
14823                     sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
14824                                               DYNAMIC_TYPE_TMP_BUFFER);
14825                     hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
14826                                              DYNAMIC_TYPE_TMP_BUFFER);
14827                     if (sha256 == NULL || hash256 == NULL) {
14828                         ERROR_OUT(MEMORY_E, done_a2);
14829                     }
14830                 }
14831             #endif
14832 
14833                 if (doSha256) {
14834                     if (!(ret = wc_InitSha256(sha256))
14835                     &&  !(ret = wc_Sha256Update(sha256,
14836                                            ssl->arrays->clientRandom, RAN_LEN))
14837                     &&  !(ret = wc_Sha256Update(sha256,
14838                                            ssl->arrays->serverRandom, RAN_LEN))
14839                     &&  !(ret = wc_Sha256Update(sha256,
14840                                            output + preSigIdx, preSigSz))) {
14841                         ret = wc_Sha256Final(sha256, hash256);
14842                     }
14843                     if (ret != 0) {
14844                         goto done_a2;
14845                     }
14846                 }
14847         #endif
14848 
14849         #ifdef WOLFSSL_SHA384
14850             #ifdef WOLFSSL_SMALL_STACK
14851                 if (doSha384) {
14852                     sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
14853                                               DYNAMIC_TYPE_TMP_BUFFER);
14854                     hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
14855                                              DYNAMIC_TYPE_TMP_BUFFER);
14856                     if (sha384 == NULL || hash384 == NULL) {
14857                         ERROR_OUT(MEMORY_E, done_a2);
14858                     }
14859                 }
14860             #endif
14861 
14862                 if (doSha384) {
14863                     if (!(ret = wc_InitSha384(sha384))
14864                     &&  !(ret = wc_Sha384Update(sha384,
14865                                            ssl->arrays->clientRandom, RAN_LEN))
14866                     &&  !(ret = wc_Sha384Update(sha384,
14867                                            ssl->arrays->serverRandom, RAN_LEN))
14868                     &&  !(ret = wc_Sha384Update(sha384,
14869                                            output + preSigIdx, preSigSz))) {
14870                         ret = wc_Sha384Final(sha384, hash384);
14871                     }
14872                     if (ret != 0) {
14873                         goto done_a2;
14874                     }
14875                 }
14876         #endif
14877 
14878         #ifdef WOLFSSL_SHA512
14879             #ifdef WOLFSSL_SMALL_STACK
14880                 if (doSha512) {
14881                     sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
14882                                               DYNAMIC_TYPE_TMP_BUFFER);
14883                     hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
14884                                              DYNAMIC_TYPE_TMP_BUFFER);
14885                     if (sha512 == NULL || hash512 == NULL) {
14886                         ERROR_OUT(MEMORY_E, done_a2);
14887                     }
14888                 }
14889             #endif
14890 
14891                 if (doSha512) {
14892                     if (!(ret = wc_InitSha512(sha512))
14893                     &&  !(ret = wc_Sha512Update(sha512,
14894                                            ssl->arrays->clientRandom, RAN_LEN))
14895                     &&  !(ret = wc_Sha512Update(sha512,
14896                                            ssl->arrays->serverRandom, RAN_LEN))
14897                     &&  !(ret = wc_Sha512Update(sha512,
14898                                            output + preSigIdx, preSigSz))) {
14899                         ret = wc_Sha512Final(sha512, hash512);
14900                     }
14901                     if (ret != 0) {
14902                         goto done_a2;
14903                     }
14904                 }
14905         #endif
14906 
14907             #ifndef NO_RSA
14908                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
14909                     byte*  signBuffer = hash;
14910                     word32 signSz     = FINISHED_SZ;
14911                     byte   doUserRsa = 0;
14912                 #ifdef WOLFSSL_SMALL_STACK
14913                     byte*  encodedSig = NULL;
14914                 #else
14915                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
14916                 #endif
14917 
14918                 #ifdef HAVE_PK_CALLBACKS
14919                     if (ssl->ctx->RsaSignCb)
14920                         doUserRsa = 1;
14921                 #endif
14922 
14923                 #ifdef WOLFSSL_SMALL_STACK
14924                     encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
14925                                                       DYNAMIC_TYPE_TMP_BUFFER);
14926                     if (encodedSig == NULL) {
14927                         ERROR_OUT(MEMORY_E, done_a2);
14928                     }
14929                 #endif
14930 
14931                     if (IsAtLeastTLSv1_2(ssl)) {
14932                         byte* digest   = &hash[MD5_DIGEST_SIZE];
14933                         int   typeH    = SHAh;
14934                         int   digestSz = SHA_DIGEST_SIZE;
14935 
14936                         if (ssl->suites->hashAlgo == sha256_mac) {
14937                         #ifndef NO_SHA256
14938                             digest   = hash256;
14939                             typeH    = SHA256h;
14940                             digestSz = SHA256_DIGEST_SIZE;
14941                         #endif
14942                         }
14943                         else if (ssl->suites->hashAlgo == sha384_mac) {
14944                         #ifdef WOLFSSL_SHA384
14945                             digest   = hash384;
14946                             typeH    = SHA384h;
14947                             digestSz = SHA384_DIGEST_SIZE;
14948                         #endif
14949                         }
14950                         else if (ssl->suites->hashAlgo == sha512_mac) {
14951                         #ifdef WOLFSSL_SHA512
14952                             digest   = hash512;
14953                             typeH    = SHA512h;
14954                             digestSz = SHA512_DIGEST_SIZE;
14955                         #endif
14956                         }
14957 
14958                         if (digest == NULL) {
14959                             #ifndef NO_RSA
14960                                 wc_FreeRsaKey(&rsaKey);
14961                             #endif
14962                             wc_ecc_free(&dsaKey);
14963                             ERROR_OUT(ALGO_ID_E, done_a2);
14964                         }
14965                         signSz = wc_EncodeSignature(encodedSig, digest,
14966                                                     digestSz, typeH);
14967                         signBuffer = encodedSig;
14968                     }
14969                     /* write sig size here */
14970                     c16toa((word16)sigSz, output + idx);
14971                     idx += LENGTH_SZ;
14972 
14973                     if (doUserRsa) {
14974                     #ifdef HAVE_PK_CALLBACKS
14975                         word32 ioLen = sigSz;
14976                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
14977                                             output + idx, &ioLen,
14978                                             ssl->buffers.key->buffer,
14979                                             ssl->buffers.key->length,
14980                                             ssl->RsaSignCtx);
14981                     #endif /*HAVE_PK_CALLBACKS */
14982                     }
14983                     else {
14984                         ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
14985                                                      sigSz, &rsaKey, ssl->rng);
14986                     }
14987 
14988                     if (ret > 0) {
14989                         /* check for signature faults */
14990                         ret = VerifyRsaSign(output + idx, ret,
14991                                                   signBuffer, signSz, &rsaKey);
14992                     }
14993                     wc_FreeRsaKey(&rsaKey);
14994                     wc_ecc_free(&dsaKey);
14995 
14996                 #ifdef WOLFSSL_SMALL_STACK
14997                     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14998                 #endif
14999 
15000                     if (ret < 0) {
15001                         goto done_a2;
15002                     }
15003                 } else
15004             #endif
15005 
15006                 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
15007                 #ifndef NO_OLD_TLS
15008                     byte* digest = &hash[MD5_DIGEST_SIZE];
15009                     word32 digestSz = SHA_DIGEST_SIZE;
15010                 #else
15011                     byte* digest = hash256;
15012                     word32 digestSz = SHA256_DIGEST_SIZE;
15013                 #endif
15014                     word32 sz = sigSz;
15015                     byte   doUserEcc = 0;
15016 
15017                 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
15018                     if (ssl->ctx->EccSignCb) {
15019                         doUserEcc = 1;
15020                     }
15021                 #endif
15022 
15023                     if (IsAtLeastTLSv1_2(ssl)) {
15024                         if (ssl->suites->hashAlgo == sha_mac) {
15025                         #ifndef NO_SHA
15026                             digest   = &hash[MD5_DIGEST_SIZE];
15027                             digestSz = SHA_DIGEST_SIZE;
15028                         #endif
15029                         }
15030                         else if (ssl->suites->hashAlgo == sha256_mac) {
15031                         #ifndef NO_SHA256
15032                             digest   = hash256;
15033                             digestSz = SHA256_DIGEST_SIZE;
15034                         #endif
15035                         }
15036                         else if (ssl->suites->hashAlgo == sha384_mac) {
15037                         #ifdef WOLFSSL_SHA384
15038                             digest   = hash384;
15039                             digestSz = SHA384_DIGEST_SIZE;
15040                         #endif
15041                         }
15042                         else if (ssl->suites->hashAlgo == sha512_mac) {
15043                         #ifdef WOLFSSL_SHA512
15044                             digest   = hash512;
15045                             digestSz = SHA512_DIGEST_SIZE;
15046                         #endif
15047                         }
15048                     }
15049 
15050                     if (doUserEcc) {
15051                     #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
15052                         ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
15053                                                   output + LENGTH_SZ + idx,
15054                                                   &sz,
15055                                                   ssl->buffers.key->buffer,
15056                                                   ssl->buffers.key->length,
15057                                                   ssl->EccSignCtx);
15058                     #endif
15059                     }
15060                     else {
15061                         ret = wc_ecc_sign_hash(digest, digestSz,
15062                              output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
15063                     }
15064                 #ifndef NO_RSA
15065                     wc_FreeRsaKey(&rsaKey);
15066                 #endif
15067                     wc_ecc_free(&dsaKey);
15068 
15069                     if (ret < 0) {
15070                         goto done_a2;
15071                     }
15072 
15073                     /* Now that we know the real sig size, write it. */
15074                     c16toa((word16)sz, output + idx);
15075 
15076                     /* And adjust length and sendSz from estimates */
15077                     length += sz - sigSz;
15078                     sendSz += sz - sigSz;
15079                 }
15080 
15081             done_a2:
15082         #ifdef WOLFSSL_SMALL_STACK
15083             #ifndef NO_OLD_TLS
15084                 XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
15085                 XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
15086             #endif
15087                 XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
15088             #ifndef NO_SHA256
15089                 XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15090                 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15091             #endif
15092             #ifdef WOLFSSL_SHA384
15093                 XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15094                 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15095             #endif
15096             #ifdef WOLFSSL_SHA512
15097                 XFREE(sha512,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15098                 XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15099             #endif
15100         #endif
15101 
15102                 if (ret < 0)
15103                     goto done_a;
15104             }
15105 
15106 #ifdef HAVE_QSH
15107             if (ssl->peerQSHKeyPresent) {
15108                 if (qshSz > 0) {
15109                     idx = sendSz - qshSz;
15110                     QSH_KeyExchangeWrite(ssl, 1);
15111 
15112                     /* extension type */
15113                     c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
15114                     idx += OPAQUE16_LEN;
15115 
15116                     /* write to output and check amount written */
15117                     if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
15118                                                       > qshSz - OPAQUE16_LEN) {
15119                         return MEMORY_E;
15120                     }
15121                 }
15122             }
15123 #endif
15124 
15125 
15126             AddHeaders(output, length, server_key_exchange, ssl);
15127 
15128         #ifdef WOLFSSL_DTLS
15129             if (ssl->options.dtls) {
15130                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
15131                     goto done_a;
15132                 }
15133             }
15134         #endif
15135 
15136             if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0) {
15137                 goto done_a;
15138             }
15139 
15140         #ifdef WOLFSSL_CALLBACKS
15141             if (ssl->hsInfoOn) {
15142                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
15143             }
15144             if (ssl->toInfoOn) {
15145                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
15146                               output, sendSz, ssl->heap);
15147             }
15148         #endif
15149 
15150             ssl->buffers.outputBuffer.length += sendSz;
15151             if (ssl->options.groupMessages) {
15152                 ret = 0;
15153             }
15154             else {
15155                 ret = SendBuffered(ssl);
15156             }
15157             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
15158 
15159         done_a:
15160         #ifdef WOLFSSL_SMALL_STACK
15161             XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15162         #endif
15163 
15164             return ret;
15165         }
15166     #endif /* HAVE_ECC */
15167 
15168     #if !defined(NO_DH) && !defined(NO_RSA)
15169         case diffie_hellman_kea:
15170         {
15171             byte    *output;
15172             word32   length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
15173             int      sendSz;
15174             word32   sigSz = 0, i = 0;
15175             word32   preSigSz = 0, preSigIdx = 0;
15176             RsaKey   rsaKey;
15177             DhKey    dhKey;
15178 
15179             if (ssl->buffers.serverDH_P.buffer == NULL ||
15180             ssl->buffers.serverDH_G.buffer == NULL) {
15181                 return NO_DH_PARAMS;
15182             }
15183 
15184             if (ssl->buffers.serverDH_Pub.buffer == NULL) {
15185                 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
15186                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
15187                         DYNAMIC_TYPE_DH);
15188                 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
15189                     return MEMORY_E;
15190                 }
15191             }
15192 
15193             if (ssl->buffers.serverDH_Priv.buffer == NULL) {
15194                 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
15195                         ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
15196                         DYNAMIC_TYPE_DH);
15197                 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
15198                     return MEMORY_E;
15199                 }
15200             }
15201 
15202             wc_InitDhKey(&dhKey);
15203             ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
15204                                    ssl->buffers.serverDH_P.length,
15205                                    ssl->buffers.serverDH_G.buffer,
15206                                    ssl->buffers.serverDH_G.length);
15207             if (ret == 0) {
15208                 ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
15209                                          ssl->buffers.serverDH_Priv.buffer,
15210                                         &ssl->buffers.serverDH_Priv.length,
15211                                          ssl->buffers.serverDH_Pub.buffer,
15212                                         &ssl->buffers.serverDH_Pub.length);
15213             }
15214             wc_FreeDhKey(&dhKey);
15215 
15216             if (ret != 0) {
15217                 return ret;
15218             }
15219 
15220             length = LENGTH_SZ * 3;  /* p, g, pub */
15221             length += ssl->buffers.serverDH_P.length +
15222                       ssl->buffers.serverDH_G.length +
15223                       ssl->buffers.serverDH_Pub.length;
15224 
15225             preSigIdx = idx;
15226             preSigSz  = length;
15227 
15228             if (!ssl->options.usingAnon_cipher) {
15229                 ret = wc_InitRsaKey(&rsaKey, ssl->heap);
15230                 if (ret != 0) {
15231                     return ret;
15232                 }
15233 
15234                 /* sig length */
15235                 length += LENGTH_SZ;
15236 
15237                 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
15238                     return NO_PRIVATE_KEY;
15239                 }
15240 
15241                 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &i,
15242                                              &rsaKey, ssl->buffers.key->length);
15243                 if (ret == 0) {
15244                     sigSz = wc_RsaEncryptSize(&rsaKey);
15245                     length += sigSz;
15246                 }
15247                 else {
15248                     wc_FreeRsaKey(&rsaKey);
15249                     return ret;
15250                 }
15251 
15252                 if (IsAtLeastTLSv1_2(ssl)) {
15253                     length += HASH_SIG_SIZE;
15254                 }
15255             }
15256 
15257             sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
15258 
15259         #ifdef HAVE_QSH
15260             length += qshSz;
15261             sendSz += qshSz;
15262         #endif
15263         #ifdef WOLFSSL_DTLS
15264             if (ssl->options.dtls) {
15265                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
15266                 idx    += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
15267                 preSigIdx = idx;
15268             }
15269         #endif
15270 
15271             /* check for available size */
15272             if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
15273                 if (!ssl->options.usingAnon_cipher) {
15274                     wc_FreeRsaKey(&rsaKey);
15275                 }
15276                 return ret;
15277             }
15278 
15279             /* get output buffer */
15280             output = ssl->buffers.outputBuffer.buffer +
15281                      ssl->buffers.outputBuffer.length;
15282 
15283             AddHeaders(output, length, server_key_exchange, ssl);
15284 
15285             /* add p, g, pub */
15286             c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
15287             idx += LENGTH_SZ;
15288             XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
15289                                   ssl->buffers.serverDH_P.length);
15290             idx += ssl->buffers.serverDH_P.length;
15291 
15292             /*  g */
15293             c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
15294             idx += LENGTH_SZ;
15295             XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
15296                                   ssl->buffers.serverDH_G.length);
15297             idx += ssl->buffers.serverDH_G.length;
15298 
15299             /*  pub */
15300             c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
15301             idx += LENGTH_SZ;
15302             XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
15303                                   ssl->buffers.serverDH_Pub.length);
15304             idx += ssl->buffers.serverDH_Pub.length;
15305 
15306         #ifdef HAVE_FUZZER
15307             if (ssl->fuzzerCb) {
15308                 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz,
15309                                                FUZZ_SIGNATURE, ssl->fuzzerCtx);
15310             }
15311         #endif
15312 
15313             /* Add signature */
15314             if (!ssl->options.usingAnon_cipher) {
15315         #ifndef NO_OLD_TLS
15316             #ifdef WOLFSSL_SMALL_STACK
15317                 Md5*   md5  = NULL;
15318                 Sha*   sha  = NULL;
15319             #else
15320                 Md5    md5[1];
15321                 Sha    sha[1];
15322             #endif
15323         #endif
15324             #ifdef WOLFSSL_SMALL_STACK
15325                 byte*  hash = NULL;
15326             #else
15327                 byte   hash[FINISHED_SZ];
15328             #endif
15329         #ifndef NO_SHA256
15330             #ifdef WOLFSSL_SMALL_STACK
15331                 Sha256* sha256  = NULL;
15332                 byte*   hash256 = NULL;
15333             #else
15334                 Sha256  sha256[1];
15335                 byte    hash256[SHA256_DIGEST_SIZE];
15336             #endif
15337         #endif
15338         #ifdef WOLFSSL_SHA384
15339             #ifdef WOLFSSL_SMALL_STACK
15340                 Sha384* sha384  = NULL;
15341                 byte*   hash384 = NULL;
15342             #else
15343                 Sha384  sha384[1];
15344                 byte    hash384[SHA384_DIGEST_SIZE];
15345             #endif
15346         #endif
15347         #ifdef WOLFSSL_SHA512
15348             #ifdef WOLFSSL_SMALL_STACK
15349                 Sha512* sha512  = NULL;
15350                 byte*   hash512 = NULL;
15351             #else
15352                 Sha512  sha512[1];
15353                 byte    hash512[SHA512_DIGEST_SIZE];
15354             #endif
15355         #endif
15356 
15357         #ifndef NO_OLD_TLS
15358             byte doMd5 = 0;
15359             byte doSha = 0;
15360         #endif
15361         #ifndef NO_SHA256
15362             byte doSha256 = 0;
15363         #endif
15364         #ifdef WOLFSSL_SHA384
15365             byte doSha384 = 0;
15366         #endif
15367         #ifdef WOLFSSL_SHA512
15368             byte doSha512 = 0;
15369         #endif
15370 
15371             /* Add hash/signature algo ID */
15372             if (IsAtLeastTLSv1_2(ssl)) {
15373                 byte setHash = 0;
15374 
15375                 output[idx++] = ssl->suites->hashAlgo;
15376                 output[idx++] = ssl->suites->sigAlgo;
15377 
15378                 switch (ssl->suites->hashAlgo) {
15379                     case sha512_mac:
15380                         #ifdef WOLFSSL_SHA512
15381                             doSha512 = 1;
15382                             setHash  = 1;
15383                         #endif
15384                         break;
15385 
15386                     case sha384_mac:
15387                         #ifdef WOLFSSL_SHA384
15388                             doSha384 = 1;
15389                             setHash  = 1;
15390                         #endif
15391                         break;
15392 
15393                     case sha256_mac:
15394                         #ifndef NO_SHA256
15395                             doSha256 = 1;
15396                             setHash  = 1;
15397                         #endif
15398                         break;
15399 
15400                     case sha_mac:
15401                         #ifndef NO_OLD_TLS
15402                             doSha = 1;
15403                             setHash  = 1;
15404                         #endif
15405                         break;
15406 
15407                     default:
15408                         WOLFSSL_MSG("Bad hash sig algo");
15409                         break;
15410                 }
15411 
15412                 if (setHash == 0) {
15413                     wc_FreeRsaKey(&rsaKey);
15414                     return ALGO_ID_E;
15415                 }
15416             } else {
15417                 /* only using sha and md5 for rsa */
15418                 #ifndef NO_OLD_TLS
15419                     doSha = 1;
15420                     if (ssl->suites->sigAlgo == rsa_sa_algo) {
15421                         doMd5 = 1;
15422                     }
15423                 #else
15424                     wc_FreeRsaKey(&rsaKey);
15425                     return ALGO_ID_E;
15426                 #endif
15427             }
15428 
15429             /* signature size */
15430             c16toa((word16)sigSz, output + idx);
15431             idx += LENGTH_SZ;
15432 
15433             /* do signature */
15434             #ifdef WOLFSSL_SMALL_STACK
15435                 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
15436                                                       DYNAMIC_TYPE_TMP_BUFFER);
15437                 if (hash == NULL) {
15438                     return MEMORY_E; /* No heap commitment before this point,
15439                                         from now on, the resources are freed
15440                                         at done_b. */
15441                 }
15442             #endif
15443 
15444         #ifndef NO_OLD_TLS
15445                 /* md5 */
15446             #ifdef WOLFSSL_SMALL_STACK
15447                 if (doMd5) {
15448                     md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
15449                                         DYNAMIC_TYPE_TMP_BUFFER);
15450                     if (md5 == NULL) {
15451                         ERROR_OUT(MEMORY_E, done_b);
15452                     }
15453                 }
15454             #endif
15455                 if (doMd5) {
15456                     wc_InitMd5(md5);
15457                     wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
15458                     wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
15459                     wc_Md5Update(md5, output + preSigIdx, preSigSz);
15460                     wc_Md5Final(md5, hash);
15461                 }
15462 
15463                 /* sha */
15464             #ifdef WOLFSSL_SMALL_STACK
15465                 if (doSha) {
15466                     sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
15467                                         DYNAMIC_TYPE_TMP_BUFFER);
15468                     if (sha == NULL) {
15469                         ERROR_OUT(MEMORY_E, done_b);
15470                     }
15471                 }
15472             #endif
15473 
15474                 if (doSha) {
15475                     if ((ret = wc_InitSha(sha)) != 0) {
15476                         goto done_b;
15477                     }
15478                     wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
15479                     wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
15480                     wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
15481                     wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
15482                 }
15483         #endif
15484 
15485         #ifndef NO_SHA256
15486             #ifdef WOLFSSL_SMALL_STACK
15487                 if (doSha256) {
15488                     sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
15489                                               DYNAMIC_TYPE_TMP_BUFFER);
15490                     hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
15491                                              DYNAMIC_TYPE_TMP_BUFFER);
15492                     if (sha256 == NULL || hash256 == NULL) {
15493                         ERROR_OUT(MEMORY_E, done_b);
15494                     }
15495                 }
15496             #endif
15497 
15498                 if (doSha256) {
15499                     if (!(ret = wc_InitSha256(sha256))
15500                     &&  !(ret = wc_Sha256Update(sha256,
15501                                            ssl->arrays->clientRandom, RAN_LEN))
15502                     &&  !(ret = wc_Sha256Update(sha256,
15503                                            ssl->arrays->serverRandom, RAN_LEN))
15504                     &&  !(ret = wc_Sha256Update(sha256,
15505                                            output + preSigIdx, preSigSz))) {
15506                         ret = wc_Sha256Final(sha256, hash256);
15507                     }
15508                     if (ret != 0) {
15509                         goto done_b;
15510                     }
15511                 }
15512             #endif
15513 
15514         #ifdef WOLFSSL_SHA384
15515             #ifdef WOLFSSL_SMALL_STACK
15516                 if (doSha384) {
15517                     sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
15518                                               DYNAMIC_TYPE_TMP_BUFFER);
15519                     hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
15520                                               DYNAMIC_TYPE_TMP_BUFFER);
15521                     if (sha384 == NULL || hash384 == NULL) {
15522                         ERROR_OUT(MEMORY_E, done_b);
15523                     }
15524                 }
15525             #endif
15526 
15527                 if (doSha384) {
15528                     if (!(ret = wc_InitSha384(sha384))
15529                     &&  !(ret = wc_Sha384Update(sha384,
15530                                            ssl->arrays->clientRandom, RAN_LEN))
15531                     &&  !(ret = wc_Sha384Update(sha384,
15532                                            ssl->arrays->serverRandom, RAN_LEN))
15533                     &&  !(ret = wc_Sha384Update(sha384,
15534                                            output + preSigIdx, preSigSz))) {
15535                         ret = wc_Sha384Final(sha384, hash384);
15536                     }
15537                     if (ret != 0) {
15538                         goto done_b;
15539                     }
15540                 }
15541         #endif
15542 
15543         #ifdef WOLFSSL_SHA512
15544             #ifdef WOLFSSL_SMALL_STACK
15545                 if (doSha512) {
15546                     sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
15547                                               DYNAMIC_TYPE_TMP_BUFFER);
15548                     hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
15549                                              DYNAMIC_TYPE_TMP_BUFFER);
15550                     if (sha512 == NULL || hash512 == NULL) {
15551                         ERROR_OUT(MEMORY_E, done_b);
15552                     }
15553                 }
15554             #endif
15555 
15556                 if (doSha512) {
15557                     if (!(ret = wc_InitSha512(sha512))
15558                     &&  !(ret = wc_Sha512Update(sha512,
15559                                            ssl->arrays->clientRandom, RAN_LEN))
15560                     &&  !(ret = wc_Sha512Update(sha512,
15561                                            ssl->arrays->serverRandom, RAN_LEN))
15562                     &&  !(ret = wc_Sha512Update(sha512,
15563                                            output + preSigIdx, preSigSz))) {
15564                         ret = wc_Sha512Final(sha512, hash512);
15565                     }
15566                     if (ret != 0) {
15567                         goto done_b;
15568                     }
15569                 }
15570         #endif
15571 
15572             #ifndef NO_RSA
15573                 if (ssl->suites->sigAlgo == rsa_sa_algo) {
15574                     byte*  signBuffer = hash;
15575                     word32 signSz     = FINISHED_SZ;
15576                 #ifdef WOLFSSL_SMALL_STACK
15577                     byte*  encodedSig = NULL;
15578                 #else
15579                     byte   encodedSig[MAX_ENCODED_SIG_SZ];
15580                 #endif
15581                     byte   doUserRsa = 0;
15582 
15583                 #ifdef HAVE_PK_CALLBACKS
15584                     if (ssl->ctx->RsaSignCb) {
15585                         doUserRsa = 1;
15586                     }
15587                 #endif
15588 
15589                     if (IsAtLeastTLSv1_2(ssl)) {
15590                         byte* digest   = &hash[MD5_DIGEST_SIZE];
15591                         int   typeH    = SHAh;
15592                         int   digestSz = SHA_DIGEST_SIZE;
15593 
15594                     #ifdef WOLFSSL_SMALL_STACK
15595                         encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
15596                                                       DYNAMIC_TYPE_TMP_BUFFER);
15597                         if (encodedSig == NULL)
15598                             ERROR_OUT(MEMORY_E, done_b);
15599                     #endif
15600 
15601                         if (ssl->suites->hashAlgo == sha256_mac) {
15602                         #ifndef NO_SHA256
15603                             digest   = hash256;
15604                             typeH    = SHA256h;
15605                             digestSz = SHA256_DIGEST_SIZE;
15606                         #endif
15607                         }
15608                         else if (ssl->suites->hashAlgo == sha384_mac) {
15609                         #ifdef WOLFSSL_SHA384
15610                             digest   = hash384;
15611                             typeH    = SHA384h;
15612                             digestSz = SHA384_DIGEST_SIZE;
15613                         #endif
15614                         }
15615                         else if (ssl->suites->hashAlgo == sha512_mac) {
15616                         #ifdef WOLFSSL_SHA512
15617                             digest   = hash512;
15618                             typeH    = SHA512h;
15619                             digestSz = SHA512_DIGEST_SIZE;
15620                         #endif
15621                         }
15622 
15623                         if (digest == NULL) {
15624                             ret = ALGO_ID_E;
15625                         } else {
15626                             signSz = wc_EncodeSignature(encodedSig, digest,
15627                                                         digestSz, typeH);
15628                             signBuffer = encodedSig;
15629                         }
15630                     }
15631                     if (doUserRsa && ret == 0) {
15632                     #ifdef HAVE_PK_CALLBACKS
15633                         word32 ioLen = sigSz;
15634                         ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
15635                                                   output + idx, &ioLen,
15636                                                   ssl->buffers.key->buffer,
15637                                                   ssl->buffers.key->length,
15638                                                   ssl->RsaSignCtx);
15639                     #endif
15640                     } else if (ret == 0) {
15641                         ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
15642                                           sigSz, &rsaKey, ssl->rng);
15643                     }
15644 
15645                     if (ret > 0) {
15646                         /* check for signature faults */
15647                         ret = VerifyRsaSign(output + idx, ret,
15648                                             signBuffer, signSz, &rsaKey);
15649                     }
15650 
15651                     wc_FreeRsaKey(&rsaKey);
15652 
15653                 #ifdef WOLFSSL_SMALL_STACK
15654                     XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15655                 #endif
15656                 }
15657             #endif
15658 
15659             done_b:
15660         #ifdef WOLFSSL_SMALL_STACK
15661             #ifndef NO_OLD_TLS
15662                 XFREE(md5,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
15663                 XFREE(sha,     NULL, DYNAMIC_TYPE_TMP_BUFFER);
15664             #endif
15665                 XFREE(hash,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
15666             #ifndef NO_SHA256
15667                 XFREE(sha256,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15668                 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15669             #endif
15670             #ifdef WOLFSSL_SHA384
15671                 XFREE(sha384,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15672                 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15673             #endif
15674             #ifdef WOLFSSL_SHA512
15675                 XFREE(sha512,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
15676                 XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15677             #endif
15678         #endif
15679 
15680                 if (ret < 0) {
15681                     return ret;
15682                 }
15683             }
15684 
15685     #ifdef HAVE_QSH
15686             if (ssl->peerQSHKeyPresent) {
15687                 if (qshSz > 0) {
15688                     idx = sendSz - qshSz;
15689                     QSH_KeyExchangeWrite(ssl, 1);
15690 
15691                     /* extension type */
15692                     c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx);
15693                     idx += OPAQUE16_LEN;
15694 
15695                     /* write to output and check amount written */
15696                     if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx)
15697                                                       > qshSz - OPAQUE16_LEN) {
15698                         return MEMORY_E;
15699                     }
15700                 }
15701             }
15702     #endif
15703 
15704         #ifdef WOLFSSL_DTLS
15705             if (ssl->options.dtls) {
15706                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
15707                     return ret;
15708                 }
15709             }
15710         #endif
15711 
15712             if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0) {
15713                 return ret;
15714             }
15715 
15716         #ifdef WOLFSSL_CALLBACKS
15717             if (ssl->hsInfoOn) {
15718                 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
15719             }
15720             if (ssl->toInfoOn) {
15721                 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
15722                               output, sendSz, ssl->heap);
15723             }
15724         #endif
15725 
15726             ssl->buffers.outputBuffer.length += sendSz;
15727             if (ssl->options.groupMessages) {
15728                 ret = 0;
15729             }
15730             else {
15731                 ret = SendBuffered(ssl);
15732             }
15733             ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
15734             break;
15735         }
15736     #endif /* NO_DH */
15737         default:
15738             break;
15739         } /* switch(ssl->specs.kea) */
15740 
15741         return ret;
15742         #undef ERROR_OUT
15743     }
15744 
15745 
15746     /* Make sure server cert/key are valid for this suite, true on success */
15747     static int VerifyServerSuite(WOLFSSL* ssl, word16 idx)
15748     {
15749         int  haveRSA = !ssl->options.haveStaticECC;
15750         int  havePSK = 0;
15751         byte first;
15752         byte second;
15753 
15754         WOLFSSL_ENTER("VerifyServerSuite");
15755 
15756         if (ssl->suites == NULL) {
15757             WOLFSSL_MSG("Suites pointer error");
15758             return 0;
15759         }
15760 
15761         first   = ssl->suites->suites[idx];
15762         second  = ssl->suites->suites[idx+1];
15763 
15764         #ifndef NO_PSK
15765             havePSK = ssl->options.havePSK;
15766         #endif
15767 
15768         if (ssl->options.haveNTRU)
15769             haveRSA = 0;
15770 
15771         if (CipherRequires(first, second, REQUIRES_RSA)) {
15772             WOLFSSL_MSG("Requires RSA");
15773             if (haveRSA == 0) {
15774                 WOLFSSL_MSG("Don't have RSA");
15775                 return 0;
15776             }
15777         }
15778 
15779         if (CipherRequires(first, second, REQUIRES_DHE)) {
15780             WOLFSSL_MSG("Requires DHE");
15781             if (ssl->options.haveDH == 0) {
15782                 WOLFSSL_MSG("Don't have DHE");
15783                 return 0;
15784             }
15785         }
15786 
15787         if (CipherRequires(first, second, REQUIRES_ECC)) {
15788             WOLFSSL_MSG("Requires ECC");
15789             if (ssl->options.haveECC == 0) {
15790                 WOLFSSL_MSG("Don't have ECC");
15791                 return 0;
15792             }
15793         }
15794 
15795         if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
15796             WOLFSSL_MSG("Requires static ECC");
15797             if (ssl->options.haveStaticECC == 0) {
15798                 WOLFSSL_MSG("Don't have static ECC");
15799                 return 0;
15800             }
15801         }
15802 
15803         if (CipherRequires(first, second, REQUIRES_PSK)) {
15804             WOLFSSL_MSG("Requires PSK");
15805             if (havePSK == 0) {
15806                 WOLFSSL_MSG("Don't have PSK");
15807                 return 0;
15808             }
15809         }
15810 
15811         if (CipherRequires(first, second, REQUIRES_NTRU)) {
15812             WOLFSSL_MSG("Requires NTRU");
15813             if (ssl->options.haveNTRU == 0) {
15814                 WOLFSSL_MSG("Don't have NTRU");
15815                 return 0;
15816             }
15817         }
15818 
15819         if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
15820             WOLFSSL_MSG("Requires RSA Signature");
15821             if (ssl->options.side == WOLFSSL_SERVER_END &&
15822                                            ssl->options.haveECDSAsig == 1) {
15823                 WOLFSSL_MSG("Don't have RSA Signature");
15824                 return 0;
15825             }
15826         }
15827 
15828 #ifdef HAVE_SUPPORTED_CURVES
15829         if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
15830             WOLFSSL_MSG("Don't have matching curves");
15831                 return 0;
15832         }
15833 #endif
15834 
15835         /* ECCDHE is always supported if ECC on */
15836 
15837 #ifdef HAVE_QSH
15838         /* need to negotiate a classic suite in addition to TLS_QSH */
15839         if (first == QSH_BYTE && second == TLS_QSH) {
15840             if (TLSX_SupportExtensions(ssl)) {
15841                 ssl->options.haveQSH = 1; /* matched TLS_QSH */
15842             }
15843             else {
15844                 WOLFSSL_MSG("Version of SSL connection does not support TLS_QSH");
15845             }
15846             return 0;
15847         }
15848 #endif
15849 
15850         return 1;
15851     }
15852 
15853 #ifndef NO_WOLFSSL_SERVER
15854     static int MatchSuite(WOLFSSL* ssl, Suites* peerSuites)
15855     {
15856         word16 i, j;
15857 
15858         WOLFSSL_ENTER("MatchSuite");
15859 
15860         /* & 0x1 equivalent % 2 */
15861         if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
15862             return MATCH_SUITE_ERROR;
15863 
15864         if (ssl->suites == NULL)
15865             return SUITES_ERROR;
15866         /* start with best, if a match we are good */
15867         for (i = 0; i < ssl->suites->suiteSz; i += 2)
15868             for (j = 0; j < peerSuites->suiteSz; j += 2)
15869                 if (ssl->suites->suites[i]   == peerSuites->suites[j] &&
15870                     ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
15871 
15872                     if (VerifyServerSuite(ssl, i)) {
15873                         int result;
15874                         WOLFSSL_MSG("Verified suite validity");
15875                         ssl->options.cipherSuite0 = ssl->suites->suites[i];
15876                         ssl->options.cipherSuite  = ssl->suites->suites[i+1];
15877                         result = SetCipherSpecs(ssl);
15878                         if (result == 0)
15879                             PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
15880                                                  peerSuites->hashSigAlgoSz);
15881                         return result;
15882                     }
15883                     else {
15884                         WOLFSSL_MSG("Could not verify suite validity, continue");
15885                     }
15886                 }
15887 
15888         return MATCH_SUITE_ERROR;
15889     }
15890 #endif
15891 
15892 #ifdef OLD_HELLO_ALLOWED
15893 
15894     /* process old style client hello, deprecate? */
15895     int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
15896                               word32 inSz, word16 sz)
15897     {
15898         word32          idx = *inOutIdx;
15899         word16          sessionSz;
15900         word16          randomSz;
15901         word16          i, j;
15902         ProtocolVersion pv;
15903         Suites          clSuites;
15904 
15905         (void)inSz;
15906         WOLFSSL_MSG("Got old format client hello");
15907 #ifdef WOLFSSL_CALLBACKS
15908         if (ssl->hsInfoOn)
15909             AddPacketName("ClientHello", &ssl->handShakeInfo);
15910         if (ssl->toInfoOn)
15911             AddLateName("ClientHello", &ssl->timeoutInfo);
15912 #endif
15913 
15914         /* manually hash input since different format */
15915 #ifndef NO_OLD_TLS
15916 #ifndef NO_MD5
15917         wc_Md5Update(&ssl->hsHashes->hashMd5, input + idx, sz);
15918 #endif
15919 #ifndef NO_SHA
15920         wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz);
15921 #endif
15922 #endif
15923 #ifndef NO_SHA256
15924         if (IsAtLeastTLSv1_2(ssl)) {
15925             int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256,
15926                                          input + idx, sz);
15927             if (shaRet != 0)
15928                 return shaRet;
15929         }
15930 #endif
15931 
15932         /* does this value mean client_hello? */
15933         idx++;
15934 
15935         /* version */
15936         pv.major = input[idx++];
15937         pv.minor = input[idx++];
15938         ssl->chVersion = pv;  /* store */
15939 
15940         if (ssl->version.minor > pv.minor) {
15941             byte haveRSA = 0;
15942             byte havePSK = 0;
15943             if (!ssl->options.downgrade) {
15944                 WOLFSSL_MSG("Client trying to connect with lesser version");
15945                 return VERSION_ERROR;
15946             }
15947             if (pv.minor < ssl->options.minDowngrade) {
15948                 WOLFSSL_MSG("    version below minimum allowed, fatal error");
15949                 return VERSION_ERROR;
15950             }
15951             if (pv.minor == SSLv3_MINOR) {
15952                 /* turn off tls */
15953                 WOLFSSL_MSG("    downgrading to SSLv3");
15954                 ssl->options.tls    = 0;
15955                 ssl->options.tls1_1 = 0;
15956                 ssl->version.minor  = SSLv3_MINOR;
15957             }
15958             else if (pv.minor == TLSv1_MINOR) {
15959                 WOLFSSL_MSG("    downgrading to TLSv1");
15960                 /* turn off tls 1.1+ */
15961                 ssl->options.tls1_1 = 0;
15962                 ssl->version.minor  = TLSv1_MINOR;
15963             }
15964             else if (pv.minor == TLSv1_1_MINOR) {
15965                 WOLFSSL_MSG("    downgrading to TLSv1.1");
15966                 ssl->version.minor  = TLSv1_1_MINOR;
15967             }
15968 #ifndef NO_RSA
15969             haveRSA = 1;
15970 #endif
15971 #ifndef NO_PSK
15972             havePSK = ssl->options.havePSK;
15973 #endif
15974 
15975             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
15976                        ssl->options.haveDH, ssl->options.haveNTRU,
15977                        ssl->options.haveECDSAsig, ssl->options.haveECC,
15978                        ssl->options.haveStaticECC, ssl->options.side);
15979         }
15980 
15981         /* suite size */
15982         ato16(&input[idx], &clSuites.suiteSz);
15983         idx += 2;
15984 
15985         if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
15986             return BUFFER_ERROR;
15987         clSuites.hashSigAlgoSz = 0;
15988 
15989         /* session size */
15990         ato16(&input[idx], &sessionSz);
15991         idx += 2;
15992 
15993         if (sessionSz > ID_LEN)
15994             return BUFFER_ERROR;
15995 
15996         /* random size */
15997         ato16(&input[idx], &randomSz);
15998         idx += 2;
15999 
16000         if (randomSz > RAN_LEN)
16001             return BUFFER_ERROR;
16002 
16003         /* suites */
16004         for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
16005             byte first = input[idx++];
16006             if (!first) { /* implicit: skip sslv2 type */
16007                 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
16008                 j += 2;
16009             }
16010             idx += 2;
16011         }
16012         clSuites.suiteSz = j;
16013 
16014         /* session id */
16015         if (sessionSz) {
16016             XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
16017             ssl->arrays->sessionIDSz = (byte)sessionSz;
16018             idx += sessionSz;
16019             ssl->options.resuming = 1;
16020         }
16021 
16022         /* random */
16023         if (randomSz < RAN_LEN)
16024             XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
16025         XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
16026                randomSz);
16027         idx += randomSz;
16028 
16029         if (ssl->options.usingCompression)
16030             ssl->options.usingCompression = 0;  /* turn off */
16031 
16032         ssl->options.clientState = CLIENT_HELLO_COMPLETE;
16033         *inOutIdx = idx;
16034 
16035         ssl->options.haveSessionId = 1;
16036         /* DoClientHello uses same resume code */
16037         if (ssl->options.resuming) {  /* let's try */
16038             int ret = -1;
16039             WOLFSSL_SESSION* session = GetSession(ssl,
16040                                                   ssl->arrays->masterSecret);
16041             #ifdef HAVE_SESSION_TICKET
16042                 if (ssl->options.useTicket == 1) {
16043                     session = &ssl->session;
16044                 }
16045             #endif
16046 
16047             if (!session) {
16048                 WOLFSSL_MSG("Session lookup for resume failed");
16049                 ssl->options.resuming = 0;
16050             } else {
16051                 if (MatchSuite(ssl, &clSuites) < 0) {
16052                     WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
16053                     return UNSUPPORTED_SUITE;
16054                 }
16055                 #ifdef SESSION_CERTS
16056                     ssl->session = *session; /* restore session certs. */
16057                 #endif
16058 
16059                 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
16060                                                                        RAN_LEN);
16061                 if (ret != 0)
16062                     return ret;
16063 
16064                 #ifdef NO_OLD_TLS
16065                     ret = DeriveTlsKeys(ssl);
16066                 #else
16067                     #ifndef NO_TLS
16068                         if (ssl->options.tls)
16069                             ret = DeriveTlsKeys(ssl);
16070                     #endif
16071                         if (!ssl->options.tls)
16072                             ret = DeriveKeys(ssl);
16073                 #endif
16074                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
16075 
16076                 return ret;
16077             }
16078         }
16079 
16080         return MatchSuite(ssl, &clSuites);
16081     }
16082 
16083 #endif /* OLD_HELLO_ALLOWED */
16084 
16085 
16086     static int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
16087                              word32 helloSz)
16088     {
16089         byte            b;
16090         ProtocolVersion pv;
16091         Suites          clSuites;
16092         word32          i = *inOutIdx;
16093         word32          begin = i;
16094 #ifdef WOLFSSL_DTLS
16095         Hmac            cookieHmac;
16096         byte            peerCookie[MAX_COOKIE_LEN];
16097         byte            peerCookieSz = 0;
16098         byte            cookieType;
16099         byte            cookieSz;
16100 #endif /* WOLFSSL_DTLS */
16101 
16102 #ifdef WOLFSSL_CALLBACKS
16103         if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
16104         if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
16105 #endif
16106 
16107         /* protocol version, random and session id length check */
16108         if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
16109             return BUFFER_ERROR;
16110 
16111         /* protocol version */
16112         XMEMCPY(&pv, input + i, OPAQUE16_LEN);
16113         ssl->chVersion = pv;   /* store */
16114 #ifdef WOLFSSL_DTLS
16115         if (ssl->options.dtls) {
16116             int ret;
16117             #if defined(NO_SHA) && defined(NO_SHA256)
16118                 #error "DTLS needs either SHA or SHA-256"
16119             #endif /* NO_SHA && NO_SHA256 */
16120 
16121             #if !defined(NO_SHA) && defined(NO_SHA256)
16122                 cookieType = SHA;
16123                 cookieSz = SHA_DIGEST_SIZE;
16124             #endif /* NO_SHA */
16125             #ifndef NO_SHA256
16126                 cookieType = SHA256;
16127                 cookieSz = SHA256_DIGEST_SIZE;
16128             #endif /* NO_SHA256 */
16129             ret = wc_HmacSetKey(&cookieHmac, cookieType,
16130                                 ssl->buffers.dtlsCookieSecret.buffer,
16131                                 ssl->buffers.dtlsCookieSecret.length);
16132             if (ret != 0) return ret;
16133             ret = wc_HmacUpdate(&cookieHmac,
16134                                 ssl->buffers.dtlsCtx.peer.sa,
16135                                 ssl->buffers.dtlsCtx.peer.sz);
16136             if (ret != 0) return ret;
16137             ret = wc_HmacUpdate(&cookieHmac, input + i, OPAQUE16_LEN);
16138             if (ret != 0) return ret;
16139         }
16140 #endif /* WOLFSSL_DTLS */
16141         i += OPAQUE16_LEN;
16142 
16143         if ((!ssl->options.dtls && ssl->version.minor > pv.minor) ||
16144             (ssl->options.dtls && ssl->version.minor != DTLS_MINOR
16145              && ssl->version.minor != DTLSv1_2_MINOR && pv.minor != DTLS_MINOR
16146              && pv.minor != DTLSv1_2_MINOR)) {
16147 
16148             word16 haveRSA = 0;
16149             word16 havePSK = 0;
16150 
16151             if (!ssl->options.downgrade) {
16152                 WOLFSSL_MSG("Client trying to connect with lesser version");
16153                 return VERSION_ERROR;
16154             }
16155             if (pv.minor < ssl->options.minDowngrade) {
16156                 WOLFSSL_MSG("    version below minimum allowed, fatal error");
16157                 return VERSION_ERROR;
16158             }
16159 
16160             if (pv.minor == SSLv3_MINOR) {
16161                 /* turn off tls */
16162                 WOLFSSL_MSG("    downgrading to SSLv3");
16163                 ssl->options.tls    = 0;
16164                 ssl->options.tls1_1 = 0;
16165                 ssl->version.minor  = SSLv3_MINOR;
16166             }
16167             else if (pv.minor == TLSv1_MINOR) {
16168                 /* turn off tls 1.1+ */
16169                 WOLFSSL_MSG("    downgrading to TLSv1");
16170                 ssl->options.tls1_1 = 0;
16171                 ssl->version.minor  = TLSv1_MINOR;
16172             }
16173             else if (pv.minor == TLSv1_1_MINOR) {
16174                 WOLFSSL_MSG("    downgrading to TLSv1.1");
16175                 ssl->version.minor  = TLSv1_1_MINOR;
16176             }
16177 #ifndef NO_RSA
16178             haveRSA = 1;
16179 #endif
16180 #ifndef NO_PSK
16181             havePSK = ssl->options.havePSK;
16182 #endif
16183             InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
16184                        ssl->options.haveDH, ssl->options.haveNTRU,
16185                        ssl->options.haveECDSAsig, ssl->options.haveECC,
16186                        ssl->options.haveStaticECC, ssl->options.side);
16187         }
16188 
16189         /* random */
16190         XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
16191 #ifdef WOLFSSL_DTLS
16192         if (ssl->options.dtls) {
16193             int ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
16194             if (ret != 0) return ret;
16195         }
16196 #endif /* WOLFSSL_DTLS */
16197         i += RAN_LEN;
16198 
16199 #ifdef SHOW_SECRETS
16200         {
16201             int j;
16202             printf("client random: ");
16203             for (j = 0; j < RAN_LEN; j++)
16204                 printf("%02x", ssl->arrays->clientRandom[j]);
16205             printf("\n");
16206         }
16207 #endif
16208 
16209         /* session id */
16210         b = input[i++];
16211 
16212         if (b == ID_LEN) {
16213             if ((i - begin) + ID_LEN > helloSz)
16214                 return BUFFER_ERROR;
16215 
16216             XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
16217 #ifdef WOLFSSL_DTLS
16218             if (ssl->options.dtls) {
16219                 int ret = wc_HmacUpdate(&cookieHmac, input + i - 1, ID_LEN + 1);
16220                 if (ret != 0) return ret;
16221             }
16222 #endif /* WOLFSSL_DTLS */
16223             ssl->arrays->sessionIDSz = ID_LEN;
16224             i += ID_LEN;
16225             ssl->options.resuming = 1; /* client wants to resume */
16226             WOLFSSL_MSG("Client wants to resume session");
16227         }
16228         else if (b) {
16229             WOLFSSL_MSG("Invalid session ID size");
16230             return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
16231         }
16232 
16233         #ifdef WOLFSSL_DTLS
16234             /* cookie */
16235             if (ssl->options.dtls) {
16236 
16237                 if ((i - begin) + OPAQUE8_LEN > helloSz)
16238                     return BUFFER_ERROR;
16239 
16240                 peerCookieSz = input[i++];
16241 
16242                 if (peerCookieSz) {
16243                     if (peerCookieSz > MAX_COOKIE_LEN)
16244                         return BUFFER_ERROR;
16245 
16246                     if ((i - begin) + peerCookieSz > helloSz)
16247                         return BUFFER_ERROR;
16248 
16249                     XMEMCPY(peerCookie, input + i, peerCookieSz);
16250 
16251                     i += peerCookieSz;
16252                 }
16253             }
16254         #endif
16255 
16256         /* suites */
16257         if ((i - begin) + OPAQUE16_LEN > helloSz)
16258             return BUFFER_ERROR;
16259 
16260         ato16(&input[i], &clSuites.suiteSz);
16261         i += OPAQUE16_LEN;
16262 
16263         /* suites and compression length check */
16264         if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
16265             return BUFFER_ERROR;
16266 
16267         if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
16268             return BUFFER_ERROR;
16269 
16270         XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
16271 #ifdef WOLFSSL_DTLS
16272         if (ssl->options.dtls) {
16273             int ret = wc_HmacUpdate(&cookieHmac,
16274                                     input + i - OPAQUE16_LEN,
16275                                     clSuites.suiteSz + OPAQUE16_LEN);
16276             if (ret != 0) return ret;
16277         }
16278 #endif /* WOLFSSL_DTLS */
16279         i += clSuites.suiteSz;
16280         clSuites.hashSigAlgoSz = 0;
16281 
16282         /* compression length */
16283         b = input[i++];
16284 
16285         if ((i - begin) + b > helloSz)
16286             return BUFFER_ERROR;
16287 
16288 #ifdef WOLFSSL_DTLS
16289         if (ssl->options.dtls) {
16290             byte newCookie[MAX_COOKIE_LEN];
16291             int ret;
16292 
16293             ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
16294             if (ret != 0) return ret;
16295             ret = wc_HmacFinal(&cookieHmac, newCookie);
16296             if (ret != 0) return ret;
16297 
16298             /* If a cookie callback is set, call it to overwrite the cookie.
16299              * This should be deprecated. The code now calculates the cookie
16300              * using an HMAC as expected. */
16301             if (ssl->ctx->CBIOCookie != NULL &&
16302                 ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz,
16303                                              ssl->IOCB_CookieCtx) != cookieSz) {
16304                 return COOKIE_ERROR;
16305             }
16306 
16307             /* Check the cookie, see if we progress the state machine. */
16308             if (peerCookieSz != cookieSz ||
16309                 XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
16310 
16311                 /* Send newCookie to client in a HelloVerifyRequest message
16312                  * and let the state machine alone. */
16313                 ssl->msgsReceived.got_client_hello = 0;
16314                 ssl->keys.dtls_handshake_number = 0;
16315                 ssl->keys.dtls_expected_peer_handshake_number = 0;
16316                 *inOutIdx += helloSz;
16317                 return SendHelloVerifyRequest(ssl, newCookie, cookieSz);
16318             }
16319 
16320             /* This was skipped in the DTLS case so we could handle the hello
16321              * verify request. */
16322             ret = HashInput(ssl, input + *inOutIdx, helloSz);
16323             if (ret != 0) return ret;
16324         }
16325 #endif /* WOLFSSL_DTLS */
16326 
16327         if (ssl->options.usingCompression) {
16328             int match = 0;
16329 
16330             while (b--) {
16331                 byte comp = input[i++];
16332 
16333                 if (comp == ZLIB_COMPRESSION)
16334                     match = 1;
16335             }
16336 
16337             if (!match) {
16338                 WOLFSSL_MSG("Not matching compression, turning off");
16339                 ssl->options.usingCompression = 0;  /* turn off */
16340             }
16341         }
16342         else
16343             i += b; /* ignore, since we're not on */
16344 
16345         *inOutIdx = i;
16346 
16347         /* tls extensions */
16348         if ((i - begin) < helloSz) {
16349 #ifdef HAVE_TLS_EXTENSIONS
16350         #ifdef HAVE_QSH
16351             QSH_Init(ssl);
16352         #endif
16353             if (TLSX_SupportExtensions(ssl)) {
16354                 int ret = 0;
16355 #else
16356             if (IsAtLeastTLSv1_2(ssl)) {
16357 #endif
16358                 /* Process the hello extension. Skip unsupported. */
16359                 word16 totalExtSz;
16360 
16361 #ifdef HAVE_TLS_EXTENSIONS
16362                 /* auto populate extensions supported unless user defined */
16363                 if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
16364                     return ret;
16365 #endif
16366 
16367                 if ((i - begin) + OPAQUE16_LEN > helloSz)
16368                     return BUFFER_ERROR;
16369 
16370                 ato16(&input[i], &totalExtSz);
16371                 i += OPAQUE16_LEN;
16372 
16373                 if ((i - begin) + totalExtSz > helloSz)
16374                     return BUFFER_ERROR;
16375 
16376 #ifdef HAVE_TLS_EXTENSIONS
16377                 /* tls extensions */
16378                 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
16379                                                      totalExtSz, 1, &clSuites)))
16380                     return ret;
16381 #ifdef HAVE_STUNNEL
16382                 if((ret=SNI_Callback(ssl)))
16383                     return ret;
16384 #endif /*HAVE_STUNNEL*/
16385 
16386                 i += totalExtSz;
16387 #else
16388                 while (totalExtSz) {
16389                     word16 extId, extSz;
16390 
16391                     if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
16392                         return BUFFER_ERROR;
16393 
16394                     ato16(&input[i], &extId);
16395                     i += OPAQUE16_LEN;
16396                     ato16(&input[i], &extSz);
16397                     i += OPAQUE16_LEN;
16398 
16399                     if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
16400                         return BUFFER_ERROR;
16401 
16402                     if (extId == HELLO_EXT_SIG_ALGO) {
16403                         ato16(&input[i], &clSuites.hashSigAlgoSz);
16404                         i += OPAQUE16_LEN;
16405 
16406                         if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
16407                             return BUFFER_ERROR;
16408 
16409                         XMEMCPY(clSuites.hashSigAlgo, &input[i],
16410                             min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
16411                         i += clSuites.hashSigAlgoSz;
16412 
16413                         if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
16414                             clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
16415                     }
16416                     else
16417                         i += extSz;
16418 
16419                     totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
16420                 }
16421 #endif
16422                 *inOutIdx = i;
16423             }
16424             else
16425                 *inOutIdx = begin + helloSz; /* skip extensions */
16426         }
16427 
16428         ssl->options.clientState   = CLIENT_HELLO_COMPLETE;
16429         ssl->options.haveSessionId = 1;
16430 
16431         /* ProcessOld uses same resume code */
16432         if (ssl->options.resuming) {
16433             int ret = -1;
16434             WOLFSSL_SESSION* session = GetSession(ssl,
16435                                                   ssl->arrays->masterSecret);
16436             #ifdef HAVE_SESSION_TICKET
16437                 if (ssl->options.useTicket == 1) {
16438                     session = &ssl->session;
16439                 }
16440             #endif
16441 
16442             if (!session) {
16443                 WOLFSSL_MSG("Session lookup for resume failed");
16444                 ssl->options.resuming = 0;
16445             }
16446             else {
16447                 if (MatchSuite(ssl, &clSuites) < 0) {
16448                     WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
16449                     return UNSUPPORTED_SUITE;
16450                 }
16451                 #ifdef SESSION_CERTS
16452                     ssl->session = *session; /* restore session certs. */
16453                 #endif
16454 
16455                 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
16456                                                                        RAN_LEN);
16457                 if (ret != 0)
16458                     return ret;
16459 
16460                 #ifdef NO_OLD_TLS
16461                     ret = DeriveTlsKeys(ssl);
16462                 #else
16463                     #ifndef NO_TLS
16464                         if (ssl->options.tls)
16465                             ret = DeriveTlsKeys(ssl);
16466                     #endif
16467                         if (!ssl->options.tls)
16468                             ret = DeriveKeys(ssl);
16469                 #endif
16470                 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
16471 
16472                 return ret;
16473             }
16474         }
16475         return MatchSuite(ssl, &clSuites);
16476     }
16477 
16478 #if !defined(NO_RSA) || defined(HAVE_ECC)
16479     static int DoCertificateVerify(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16480                                    word32 size)
16481     {
16482         word16      sz = 0;
16483         int         ret = VERIFY_CERT_ERROR;   /* start in error state */
16484         byte        hashAlgo = sha_mac;
16485         byte        sigAlgo = anonymous_sa_algo;
16486         word32      begin = *inOutIdx;
16487 
16488         #ifdef WOLFSSL_CALLBACKS
16489             if (ssl->hsInfoOn)
16490                 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
16491             if (ssl->toInfoOn)
16492                 AddLateName("CertificateVerify", &ssl->timeoutInfo);
16493         #endif
16494 
16495 
16496         if (IsAtLeastTLSv1_2(ssl)) {
16497             if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
16498                 return BUFFER_ERROR;
16499 
16500             hashAlgo = input[(*inOutIdx)++];
16501             sigAlgo  = input[(*inOutIdx)++];
16502         }
16503 
16504         if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
16505             return BUFFER_ERROR;
16506 
16507         ato16(input + *inOutIdx, &sz);
16508         *inOutIdx += OPAQUE16_LEN;
16509 
16510         if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
16511             return BUFFER_ERROR;
16512 
16513         /* RSA */
16514 #ifndef NO_RSA
16515         if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
16516             byte* out       = NULL;
16517             int   outLen    = 0;
16518             byte  doUserRsa = 0;
16519 
16520             #ifdef HAVE_PK_CALLBACKS
16521                 if (ssl->ctx->RsaVerifyCb)
16522                     doUserRsa = 1;
16523             #endif /*HAVE_PK_CALLBACKS */
16524 
16525             WOLFSSL_MSG("Doing RSA peer cert verify");
16526 
16527             if (doUserRsa) {
16528             #ifdef HAVE_PK_CALLBACKS
16529                 outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
16530                                             &out,
16531                                             ssl->buffers.peerRsaKey.buffer,
16532                                             ssl->buffers.peerRsaKey.length,
16533                                             ssl->RsaVerifyCtx);
16534             #endif /*HAVE_PK_CALLBACKS */
16535             }
16536             else {
16537                 outLen = wc_RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
16538                                                                ssl->peerRsaKey);
16539             }
16540 
16541             if (IsAtLeastTLSv1_2(ssl)) {
16542 #ifdef WOLFSSL_SMALL_STACK
16543                 byte*  encodedSig = NULL;
16544 #else
16545                 byte   encodedSig[MAX_ENCODED_SIG_SZ];
16546 #endif
16547                 word32 sigSz;
16548                 byte*  digest = ssl->hsHashes->certHashes.sha;
16549                 int    typeH = SHAh;
16550                 int    digestSz = SHA_DIGEST_SIZE;
16551 
16552 #ifdef WOLFSSL_SMALL_STACK
16553                 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
16554                                                        DYNAMIC_TYPE_TMP_BUFFER);
16555                 if (encodedSig == NULL)
16556                     return MEMORY_E;
16557 #endif
16558 
16559                 if (sigAlgo != rsa_sa_algo) {
16560                     WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
16561                 }
16562 
16563                 if (hashAlgo == sha256_mac) {
16564                     #ifndef NO_SHA256
16565                         digest = ssl->hsHashes->certHashes.sha256;
16566                         typeH    = SHA256h;
16567                         digestSz = SHA256_DIGEST_SIZE;
16568                     #endif
16569                 }
16570                 else if (hashAlgo == sha384_mac) {
16571                     #ifdef WOLFSSL_SHA384
16572                         digest = ssl->hsHashes->certHashes.sha384;
16573                         typeH    = SHA384h;
16574                         digestSz = SHA384_DIGEST_SIZE;
16575                     #endif
16576                 }
16577                 else if (hashAlgo == sha512_mac) {
16578                     #ifdef WOLFSSL_SHA512
16579                         digest = ssl->hsHashes->certHashes.sha512;
16580                         typeH    = SHA512h;
16581                         digestSz = SHA512_DIGEST_SIZE;
16582                     #endif
16583                 }
16584 
16585                 sigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH);
16586 
16587                 if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
16588                                            min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
16589                     ret = 0; /* verified */
16590 
16591 #ifdef WOLFSSL_SMALL_STACK
16592                 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16593 #endif
16594             }
16595             else {
16596                 if (outLen == FINISHED_SZ && out && XMEMCMP(out,
16597                                             &ssl->hsHashes->certHashes,
16598                                             FINISHED_SZ) == 0) {
16599                     ret = 0; /* verified */
16600                 }
16601             }
16602         }
16603 #endif
16604 #ifdef HAVE_ECC
16605         if (ssl->peerEccDsaKeyPresent) {
16606             int verify =  0;
16607             int err    = -1;
16608             byte* digest = ssl->hsHashes->certHashes.sha;
16609             word32 digestSz = SHA_DIGEST_SIZE;
16610             byte doUserEcc = 0;
16611 
16612             #ifdef HAVE_PK_CALLBACKS
16613                 if (ssl->ctx->EccVerifyCb)
16614                     doUserEcc = 1;
16615             #endif
16616 
16617             WOLFSSL_MSG("Doing ECC peer cert verify");
16618 
16619             if (IsAtLeastTLSv1_2(ssl)) {
16620                 if (sigAlgo != ecc_dsa_sa_algo) {
16621                     WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
16622                 }
16623 
16624                 if (hashAlgo == sha256_mac) {
16625                     #ifndef NO_SHA256
16626                         digest = ssl->hsHashes->certHashes.sha256;
16627                         digestSz = SHA256_DIGEST_SIZE;
16628                     #endif
16629                 }
16630                 else if (hashAlgo == sha384_mac) {
16631                     #ifdef WOLFSSL_SHA384
16632                         digest = ssl->hsHashes->certHashes.sha384;
16633                         digestSz = SHA384_DIGEST_SIZE;
16634                     #endif
16635                 }
16636                 else if (hashAlgo == sha512_mac) {
16637                     #ifdef WOLFSSL_SHA512
16638                         digest = ssl->hsHashes->certHashes.sha512;
16639                         digestSz = SHA512_DIGEST_SIZE;
16640                     #endif
16641                 }
16642             }
16643 
16644             if (doUserEcc) {
16645             #ifdef HAVE_PK_CALLBACKS
16646                 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
16647                                             digestSz,
16648                                             ssl->buffers.peerEccDsaKey.buffer,
16649                                             ssl->buffers.peerEccDsaKey.length,
16650                                             &verify, ssl->EccVerifyCtx);
16651             #endif
16652             }
16653             else {
16654                 err = wc_ecc_verify_hash(input + *inOutIdx, sz, digest,
16655                                          digestSz, &verify, ssl->peerEccDsaKey);
16656             }
16657 
16658             if (err == 0 && verify == 1)
16659                ret = 0; /* verified */
16660         }
16661 #endif
16662         *inOutIdx += sz;
16663 
16664         if (ret == 0)
16665             ssl->options.havePeerVerify = 1;
16666 
16667         return ret;
16668     }
16669 #endif /* !NO_RSA || HAVE_ECC */
16670 
16671     int SendServerHelloDone(WOLFSSL* ssl)
16672     {
16673         byte              *output;
16674         int                sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
16675         int                ret;
16676 
16677         #ifdef WOLFSSL_DTLS
16678             if (ssl->options.dtls)
16679                 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
16680         #endif
16681         /* check for available size */
16682         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
16683             return ret;
16684 
16685         /* get output buffer */
16686         output = ssl->buffers.outputBuffer.buffer +
16687                  ssl->buffers.outputBuffer.length;
16688 
16689         AddHeaders(output, 0, server_hello_done, ssl);
16690 
16691         #ifdef WOLFSSL_DTLS
16692             if (ssl->options.dtls) {
16693                 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
16694                     return 0;
16695             }
16696         #endif
16697 
16698         ret = HashOutput(ssl, output, sendSz, 0);
16699             if (ret != 0)
16700                 return ret;
16701 
16702 #ifdef WOLFSSL_CALLBACKS
16703         if (ssl->hsInfoOn)
16704             AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
16705         if (ssl->toInfoOn)
16706             AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
16707                           ssl->heap);
16708 #endif
16709         ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
16710 
16711         ssl->buffers.outputBuffer.length += sendSz;
16712 
16713         return SendBuffered(ssl);
16714     }
16715 
16716 
16717 #ifdef HAVE_SESSION_TICKET
16718 
16719 #define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
16720                 WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
16721 #define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
16722 
16723     /* our ticket format */
16724     typedef struct InternalTicket {
16725         ProtocolVersion pv;                    /* version when ticket created */
16726         byte            suite[SUITE_LEN];      /* cipher suite when created */
16727         byte            msecret[SECRET_LEN];   /* master secret */
16728         word32          timestamp;             /* born on */
16729     } InternalTicket;
16730 
16731     /* fit within SESSION_TICKET_LEN */
16732     typedef struct ExternalTicket {
16733         byte key_name[WOLFSSL_TICKET_NAME_SZ];  /* key context name */
16734         byte iv[WOLFSSL_TICKET_IV_SZ];          /* this ticket's iv */
16735         byte enc_len[LENGTH_SZ];                /* encrypted length */
16736         byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
16737         byte mac[WOLFSSL_TICKET_MAC_SZ];        /* total mac */
16738         /* !! if add to structure, add to TICKET_FIXED_SZ !! */
16739     } ExternalTicket;
16740 
16741     /* create a new session ticket, 0 on success */
16742     static int CreateTicket(WOLFSSL* ssl)
16743     {
16744         InternalTicket  it;
16745         ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
16746         int encLen;
16747         int ret;
16748         byte zeros[WOLFSSL_TICKET_MAC_SZ];   /* biggest cmp size */
16749 
16750         /* build internal */
16751         it.pv.major = ssl->version.major;
16752         it.pv.minor = ssl->version.minor;
16753 
16754         it.suite[0] = ssl->options.cipherSuite0;
16755         it.suite[1] = ssl->options.cipherSuite;
16756 
16757         XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
16758         c32toa(LowResTimer(), (byte*)&it.timestamp);
16759 
16760         /* build external */
16761         XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
16762 
16763         /* encrypt */
16764         encLen = WOLFSSL_TICKET_ENC_SZ;  /* max size user can use */
16765         ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
16766                                     et->enc_ticket, sizeof(InternalTicket),
16767                                     &encLen, ssl->ctx->ticketEncCtx);
16768         if (ret == WOLFSSL_TICKET_RET_OK) {
16769             if (encLen < (int)sizeof(InternalTicket) ||
16770                 encLen > WOLFSSL_TICKET_ENC_SZ) {
16771                 WOLFSSL_MSG("Bad user ticket encrypt size");
16772                 return BAD_TICKET_KEY_CB_SZ;
16773             }
16774 
16775             /* sanity checks on encrypt callback */
16776 
16777             /* internal ticket can't be the same if encrypted */
16778             if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
16779                 WOLFSSL_MSG("User ticket encrypt didn't encrypt");
16780                 return BAD_TICKET_ENCRYPT;
16781             }
16782 
16783             XMEMSET(zeros, 0, sizeof(zeros));
16784 
16785             /* name */
16786             if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) {
16787                 WOLFSSL_MSG("User ticket encrypt didn't set name");
16788                 return BAD_TICKET_ENCRYPT;
16789             }
16790 
16791             /* iv */
16792             if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) {
16793                 WOLFSSL_MSG("User ticket encrypt didn't set iv");
16794                 return BAD_TICKET_ENCRYPT;
16795             }
16796 
16797             /* mac */
16798             if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
16799                 WOLFSSL_MSG("User ticket encrypt didn't set mac");
16800                 return BAD_TICKET_ENCRYPT;
16801             }
16802 
16803             /* set size */
16804             c16toa((word16)encLen, et->enc_len);
16805             ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
16806             if (encLen < WOLFSSL_TICKET_ENC_SZ) {
16807                 /* move mac up since whole enc buffer not used */
16808                 XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
16809             }
16810         }
16811 
16812         return ret;
16813     }
16814 
16815 
16816     /* Parse ticket sent by client, returns callback return value */
16817     int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
16818     {
16819         ExternalTicket* et;
16820         InternalTicket* it;
16821         int             ret;
16822         int             outLen;
16823         word16          inLen;
16824 
16825         if (len > SESSION_TICKET_LEN ||
16826              len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
16827             return BAD_TICKET_MSG_SZ;
16828         }
16829 
16830         et = (ExternalTicket*)input;
16831         it = (InternalTicket*)et->enc_ticket;
16832 
16833         /* decrypt */
16834         ato16(et->enc_len, &inLen);
16835         if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
16836             return BAD_TICKET_MSG_SZ;
16837         }
16838         outLen = inLen;   /* may be reduced by user padding */
16839         ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
16840                                     et->enc_ticket + inLen, 0,
16841                                     et->enc_ticket, inLen, &outLen,
16842                                     ssl->ctx->ticketEncCtx);
16843         if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) return ret;
16844         if (outLen > inLen || outLen < (int)sizeof(InternalTicket)) {
16845             WOLFSSL_MSG("Bad user ticket decrypt len");
16846             return BAD_TICKET_KEY_CB_SZ;
16847         }
16848 
16849         /* get master secret */
16850         if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE)
16851             XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
16852 
16853         return ret;
16854     }
16855 
16856 
16857     /* send Session Ticket */
16858     int SendTicket(WOLFSSL* ssl)
16859     {
16860         byte*              output;
16861         int                ret;
16862         int                sendSz;
16863         word32             length = SESSION_HINT_SZ + LENGTH_SZ;
16864         word32             idx    = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
16865 
16866     #ifdef WOLFSSL_DTLS
16867         if (ssl->options.dtls) {
16868             length += DTLS_RECORD_EXTRA;
16869             idx    += DTLS_RECORD_EXTRA;
16870         }
16871     #endif
16872 
16873         if (ssl->options.createTicket) {
16874             ret = CreateTicket(ssl);
16875             if (ret != 0) return ret;
16876         }
16877 
16878         length += ssl->session.ticketLen;
16879         sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
16880 
16881         /* check for available size */
16882         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
16883             return ret;
16884 
16885         /* get output buffer */
16886         output = ssl->buffers.outputBuffer.buffer +
16887                  ssl->buffers.outputBuffer.length;
16888 
16889         AddHeaders(output, length, session_ticket, ssl);
16890 
16891         /* hint */
16892         c32toa(ssl->ctx->ticketHint, output + idx);
16893         idx += SESSION_HINT_SZ;
16894 
16895         /* length */
16896         c16toa(ssl->session.ticketLen, output + idx);
16897         idx += LENGTH_SZ;
16898 
16899         /* ticket */
16900         XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
16901         /* idx += ssl->session.ticketLen; */
16902 
16903         ret = HashOutput(ssl, output, sendSz, 0);
16904         if (ret != 0) return ret;
16905         ssl->buffers.outputBuffer.length += sendSz;
16906 
16907         return SendBuffered(ssl);
16908     }
16909 
16910 #endif /* HAVE_SESSION_TICKET */
16911 
16912 
16913 #ifdef WOLFSSL_DTLS
16914     static int SendHelloVerifyRequest(WOLFSSL* ssl,
16915                                       const byte* cookie, byte cookieSz)
16916     {
16917         byte* output;
16918         int   length = VERSION_SZ + ENUM_LEN + cookieSz;
16919         int   idx    = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
16920         int   sendSz = length + idx;
16921         int   ret;
16922 
16923         /* check for available size */
16924         if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
16925             return ret;
16926 
16927         /* get output buffer */
16928         output = ssl->buffers.outputBuffer.buffer +
16929                  ssl->buffers.outputBuffer.length;
16930 
16931         /* Hello Verify Request should use the same sequence number as the
16932          * Client Hello. */
16933         ssl->keys.dtls_sequence_number = ssl->keys.dtls_state.curSeq;
16934         AddHeaders(output, length, hello_verify_request, ssl);
16935         {
16936             DtlsRecordLayerHeader* rh = (DtlsRecordLayerHeader*)output;
16937             rh->pvMajor = DTLS_MAJOR;
16938             rh->pvMinor = DTLS_MINOR;
16939         }
16940 
16941         output[idx++] = DTLS_MAJOR;
16942         output[idx++] = DTLS_MINOR;
16943 
16944         output[idx++] = cookieSz;
16945         if (cookie == NULL || cookieSz == 0)
16946             return COOKIE_ERROR;
16947 
16948         XMEMCPY(output + idx, cookie, cookieSz);
16949 
16950 #ifdef WOLFSSL_CALLBACKS
16951         if (ssl->hsInfoOn)
16952             AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
16953         if (ssl->toInfoOn)
16954             AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
16955                           sendSz, ssl->heap);
16956 #endif
16957 
16958         ssl->buffers.outputBuffer.length += sendSz;
16959 
16960         return SendBuffered(ssl);
16961     }
16962 #endif
16963 
16964     static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16965                                                                     word32 size)
16966     {
16967         #ifdef HAVE_QSH
16968             word16 name;
16969             int    qshSz;
16970         #endif
16971         int    ret = 0;
16972         word32 length = 0;
16973         byte*  out = NULL;
16974         word32 begin = *inOutIdx;
16975 
16976         (void)length; /* shut up compiler warnings */
16977         (void)out;
16978         (void)input;
16979         (void)size;
16980         (void)begin;
16981 
16982         if (ssl->options.side != WOLFSSL_SERVER_END) {
16983             WOLFSSL_MSG("Client received client keyexchange, attack?");
16984             WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
16985             return SSL_FATAL_ERROR;
16986         }
16987 
16988         if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
16989             WOLFSSL_MSG("Client sending keyexchange at wrong time");
16990             SendAlert(ssl, alert_fatal, unexpected_message);
16991             return OUT_OF_ORDER_E;
16992         }
16993 
16994         #ifndef NO_CERTS
16995             if (ssl->options.verifyPeer && ssl->options.failNoCert) {
16996                 if (!ssl->options.havePeerCert) {
16997                     WOLFSSL_MSG("client didn't present peer cert");
16998                     return NO_PEER_CERT;
16999                 }
17000             }
17001 
17002             if (ssl->options.verifyPeer && ssl->options.failNoCertxPSK) {
17003                 if (!ssl->options.havePeerCert &&
17004                                                  !ssl->options.usingPSK_cipher){
17005                     WOLFSSL_MSG("client didn't present peer cert");
17006                     return NO_PEER_CERT;
17007                 }
17008             }
17009         #endif
17010 
17011         #ifdef WOLFSSL_CALLBACKS
17012             if (ssl->hsInfoOn) {
17013                 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
17014             }
17015             if (ssl->toInfoOn) {
17016                 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
17017             }
17018         #endif
17019 
17020         switch (ssl->specs.kea) {
17021         #ifndef NO_RSA
17022             case rsa_kea:
17023             {
17024                 word32 idx = 0;
17025                 RsaKey key;
17026                 byte   doUserRsa = 0;
17027 
17028                 #ifdef HAVE_PK_CALLBACKS
17029                     if (ssl->ctx->RsaDecCb) {
17030                         doUserRsa = 1;
17031                     }
17032                 #endif
17033 
17034                 ret = wc_InitRsaKey(&key, ssl->heap);
17035                 if (ret != 0) {
17036                     return ret;
17037                 }
17038 
17039                 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
17040                     return NO_PRIVATE_KEY;
17041                 }
17042 
17043                 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
17044                                              &key, ssl->buffers.key->length);
17045 
17046                 if (ret == 0) {
17047                     length = wc_RsaEncryptSize(&key);
17048                     ssl->arrays->preMasterSz = SECRET_LEN;
17049 
17050                     if (ssl->options.tls) {
17051                         word16 check;
17052 
17053                         if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17054                             return BUFFER_ERROR;
17055                         }
17056 
17057                         ato16(input + *inOutIdx, &check);
17058                         *inOutIdx += OPAQUE16_LEN;
17059 
17060                         if ((word32) check != length) {
17061                             WOLFSSL_MSG("RSA explicit size doesn't match");
17062                             wc_FreeRsaKey(&key);
17063                             return RSA_PRIVATE_ERROR;
17064                         }
17065                     }
17066 
17067                     if ((*inOutIdx - begin) + length > size) {
17068                         WOLFSSL_MSG("RSA message too big");
17069                         wc_FreeRsaKey(&key);
17070                         return BUFFER_ERROR;
17071                     }
17072 
17073                     if (doUserRsa) {
17074                         #ifdef HAVE_PK_CALLBACKS
17075                             ret = ssl->ctx->RsaDecCb(ssl,
17076                                         input + *inOutIdx, length, &out,
17077                                         ssl->buffers.key->buffer,
17078                                         ssl->buffers.key->length,
17079                                         ssl->RsaDecCtx);
17080                         #endif
17081                     }
17082                     else {
17083                         ret = wc_RsaPrivateDecryptInline(input + *inOutIdx, length,
17084                                                                     &out, &key);
17085                     }
17086 
17087                     *inOutIdx += length;
17088 
17089                     if (ret == SECRET_LEN) {
17090                         XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
17091                         if (ssl->arrays->preMasterSecret[0] !=
17092                                                            ssl->chVersion.major
17093                             || ssl->arrays->preMasterSecret[1] !=
17094                                                            ssl->chVersion.minor) {
17095                             ret = PMS_VERSION_ERROR;
17096                         }
17097                         else
17098                         {
17099                 #ifdef HAVE_QSH
17100                             if (ssl->options.haveQSH) {
17101                                 /* extension name */
17102                                 ato16(input + *inOutIdx, &name);
17103                                 *inOutIdx += OPAQUE16_LEN;
17104 
17105                                 if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17106                                     /* if qshSz is larger than 0 it is the
17107                                        length of buffer used */
17108                                     if ((qshSz = TLSX_QSHCipher_Parse(ssl, input
17109                                                   + *inOutIdx, size - *inOutIdx
17110                                                   + begin, 1)) < 0) {
17111                                         return qshSz;
17112                                     }
17113                                     *inOutIdx += qshSz;
17114                                 }
17115                                 else {
17116                                     /* unknown extension sent client ignored
17117                                        handshake */
17118                                     return BUFFER_ERROR;
17119                                 }
17120                             }
17121                 #endif
17122                             ret = MakeMasterSecret(ssl);
17123                          }
17124                     }
17125                     else {
17126                         ret = RSA_PRIVATE_ERROR;
17127                     }
17128                 }
17129 
17130                 wc_FreeRsaKey(&key);
17131             }
17132             break;
17133         #endif
17134         #ifndef NO_PSK
17135             case psk_kea:
17136             {
17137                 byte* pms = ssl->arrays->preMasterSecret;
17138                 word16 ci_sz;
17139 
17140                 /* sanity check that PSK server callback has been set */
17141                 if (ssl->options.server_psk_cb == NULL) {
17142                     WOLFSSL_MSG("No server PSK callback set");
17143                     return PSK_KEY_ERROR;
17144                 }
17145 
17146                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17147                     return BUFFER_ERROR;
17148                 }
17149 
17150                 ato16(input + *inOutIdx, &ci_sz);
17151                 *inOutIdx += OPAQUE16_LEN;
17152 
17153                 if (ci_sz > MAX_PSK_ID_LEN) {
17154                     return CLIENT_ID_ERROR;
17155                 }
17156 
17157                 if ((*inOutIdx - begin) + ci_sz > size) {
17158                     return BUFFER_ERROR;
17159                 }
17160 
17161                 XMEMCPY(ssl->arrays->client_identity, input + *inOutIdx, ci_sz);
17162                 *inOutIdx += ci_sz;
17163 
17164                 ssl->arrays->client_identity[min(ci_sz, MAX_PSK_ID_LEN-1)] = 0;
17165                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
17166                     ssl->arrays->client_identity, ssl->arrays->psk_key,
17167                     MAX_PSK_KEY_LEN);
17168 
17169                 if (ssl->arrays->psk_keySz == 0 ||
17170                                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17171                     return PSK_KEY_ERROR;
17172                 }
17173 
17174                 /* make psk pre master secret */
17175                 /* length of key + length 0s + length of key + key */
17176                 c16toa((word16) ssl->arrays->psk_keySz, pms);
17177                 pms += OPAQUE16_LEN;
17178 
17179                 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
17180                 pms += ssl->arrays->psk_keySz;
17181 
17182                 c16toa((word16) ssl->arrays->psk_keySz, pms);
17183                 pms += OPAQUE16_LEN;
17184 
17185                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17186                 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
17187 
17188             #ifdef HAVE_QSH
17189                 if (ssl->options.haveQSH) {
17190                     /* extension name */
17191                     ato16(input + *inOutIdx, &name);
17192                     *inOutIdx += OPAQUE16_LEN;
17193 
17194                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17195                         /* if qshSz is larger than 0 it is the length of
17196                            buffer used */
17197                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17198                                               size - *inOutIdx + begin, 1)) < 0) {
17199                             return qshSz;
17200                         }
17201                         *inOutIdx += qshSz;
17202                     }
17203                     else {
17204                         /* unknown extension sent client ignored
17205                            handshake */
17206                         return BUFFER_ERROR;
17207                     }
17208                 }
17209             #endif
17210                 ret = MakeMasterSecret(ssl);
17211 
17212                 /* No further need for PSK */
17213                 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17214                 ssl->arrays->psk_keySz = 0;
17215             }
17216             break;
17217         #endif /* NO_PSK */
17218         #ifdef HAVE_NTRU
17219             case ntru_kea:
17220             {
17221                 word16 cipherLen;
17222                 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
17223 
17224                 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
17225                     return NO_PRIVATE_KEY;
17226                 }
17227 
17228                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17229                     return BUFFER_ERROR;
17230                 }
17231 
17232                 ato16(input + *inOutIdx, &cipherLen);
17233                 *inOutIdx += OPAQUE16_LEN;
17234 
17235                 if (cipherLen > MAX_NTRU_ENCRYPT_SZ) {
17236                     return NTRU_KEY_ERROR;
17237                 }
17238 
17239                 if ((*inOutIdx - begin) + cipherLen > size) {
17240                     return BUFFER_ERROR;
17241                 }
17242 
17243                 if (NTRU_OK != ntru_crypto_ntru_decrypt(
17244                             (word16) ssl->buffers.key->length,
17245                             ssl->buffers.key->buffer, cipherLen,
17246                             input + *inOutIdx, &plainLen,
17247                             ssl->arrays->preMasterSecret)) {
17248                     return NTRU_DECRYPT_ERROR;
17249                 }
17250 
17251                 if (plainLen != SECRET_LEN) {
17252                     return NTRU_DECRYPT_ERROR;
17253                 }
17254 
17255                 *inOutIdx += cipherLen;
17256 
17257             #ifdef HAVE_QSH
17258                 if (ssl->options.haveQSH) {
17259                     /* extension name */
17260                     ato16(input + *inOutIdx, &name);
17261                     *inOutIdx += OPAQUE16_LEN;
17262 
17263                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17264                         /* if qshSz is larger than 0 it is the length of
17265                            buffer used */
17266                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17267                                               size - *inOutIdx + begin, 1)) < 0) {
17268                             return qshSz;
17269                         }
17270                         *inOutIdx += qshSz;
17271                     }
17272                     else {
17273                         /* unknown extension sent client ignored
17274                            handshake */
17275                         return BUFFER_ERROR;
17276                     }
17277                 }
17278             #endif
17279                 ssl->arrays->preMasterSz = plainLen;
17280                 ret = MakeMasterSecret(ssl);
17281             }
17282             break;
17283         #endif /* HAVE_NTRU */
17284         #ifdef HAVE_ECC
17285             case ecc_diffie_hellman_kea:
17286             {
17287                 if ((*inOutIdx - begin) + OPAQUE8_LEN > size) {
17288                     return BUFFER_ERROR;
17289                 }
17290 
17291                 length = input[(*inOutIdx)++];
17292 
17293                 if ((*inOutIdx - begin) + length > size) {
17294                     return BUFFER_ERROR;
17295                 }
17296 
17297                 if (ssl->peerEccKey == NULL) {
17298                     /* alloc/init on demand */
17299                     ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
17300                                               ssl->ctx->heap, DYNAMIC_TYPE_ECC);
17301                     if (ssl->peerEccKey == NULL) {
17302                         WOLFSSL_MSG("PeerEccKey Memory error");
17303                         return MEMORY_E;
17304                     }
17305                     wc_ecc_init(ssl->peerEccKey);
17306                 } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
17307                     wc_ecc_free(ssl->peerEccKey);
17308                     ssl->peerEccKeyPresent = 0;
17309                     wc_ecc_init(ssl->peerEccKey);
17310                 }
17311 
17312                 if (wc_ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey)) {
17313                     return ECC_PEERKEY_ERROR;
17314                 }
17315 
17316                 *inOutIdx += length;
17317                 ssl->peerEccKeyPresent = 1;
17318 
17319                 length = sizeof(ssl->arrays->preMasterSecret);
17320 
17321                 if (ssl->specs.static_ecdh) {
17322                     ecc_key staticKey;
17323                     word32 i = 0;
17324 
17325                     wc_ecc_init(&staticKey);
17326                     ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &i,
17327                                            &staticKey, ssl->buffers.key->length);
17328 
17329                     if (ret == 0) {
17330                         ret = wc_ecc_shared_secret(&staticKey, ssl->peerEccKey,
17331                                          ssl->arrays->preMasterSecret, &length);
17332                     }
17333 
17334                     wc_ecc_free(&staticKey);
17335                 }
17336                 else {
17337                     if (ssl->eccTempKeyPresent == 0) {
17338                         WOLFSSL_MSG("Ecc ephemeral key not made correctly");
17339                         ret = ECC_MAKEKEY_ERROR;
17340                     } else {
17341                         ret = wc_ecc_shared_secret(ssl->eccTempKey,ssl->peerEccKey,
17342                                          ssl->arrays->preMasterSecret, &length);
17343                     }
17344                 }
17345 
17346                 if (ret != 0) {
17347                     return ECC_SHARED_ERROR;
17348                 }
17349 
17350                 ssl->arrays->preMasterSz = length;
17351             #ifdef HAVE_QSH
17352                 if (ssl->options.haveQSH) {
17353                     /* extension name */
17354                     ato16(input + *inOutIdx, &name);
17355                     *inOutIdx += OPAQUE16_LEN;
17356 
17357                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17358                         /* if qshSz is larger than 0 it is the length of
17359                            buffer used */
17360                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17361                                               size - *inOutIdx + begin, 1)) < 0) {
17362                             return qshSz;
17363                         }
17364                         *inOutIdx += qshSz;
17365                     }
17366                     else {
17367                         /* unknown extension sent client ignored
17368                            handshake */
17369                         return BUFFER_ERROR;
17370                     }
17371                 }
17372             #endif
17373                 ret = MakeMasterSecret(ssl);
17374             }
17375             break;
17376         #endif /* HAVE_ECC */
17377         #ifndef NO_DH
17378             case diffie_hellman_kea:
17379             {
17380                 word16 clientPubSz;
17381                 DhKey  dhKey;
17382 
17383                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17384                     return BUFFER_ERROR;
17385                 }
17386 
17387                 ato16(input + *inOutIdx, &clientPubSz);
17388                 *inOutIdx += OPAQUE16_LEN;
17389 
17390                 if ((*inOutIdx - begin) + clientPubSz > size) {
17391                     return BUFFER_ERROR;
17392                 }
17393 
17394                 wc_InitDhKey(&dhKey);
17395                 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
17396                                        ssl->buffers.serverDH_P.length,
17397                                        ssl->buffers.serverDH_G.buffer,
17398                                        ssl->buffers.serverDH_G.length);
17399                 if (ret == 0) {
17400                     ret = wc_DhAgree(&dhKey, ssl->arrays->preMasterSecret,
17401                                          &ssl->arrays->preMasterSz,
17402                                           ssl->buffers.serverDH_Priv.buffer,
17403                                           ssl->buffers.serverDH_Priv.length,
17404                                           input + *inOutIdx, clientPubSz);
17405                 }
17406                 wc_FreeDhKey(&dhKey);
17407 
17408                 *inOutIdx += clientPubSz;
17409 
17410             #ifdef HAVE_QSH
17411                 if (ssl->options.haveQSH) {
17412                     /* extension name */
17413                     ato16(input + *inOutIdx, &name);
17414                     *inOutIdx += OPAQUE16_LEN;
17415 
17416                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17417                         /* if qshSz is larger than 0 it is the length of
17418                            buffer used */
17419                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17420                                               size - *inOutIdx + begin, 1)) < 0) {
17421                             return qshSz;
17422                         }
17423                         *inOutIdx += qshSz;
17424                     }
17425                     else {
17426                         /* unknown extension sent client ignored
17427                            handshake */
17428                         return BUFFER_ERROR;
17429                     }
17430                 }
17431             #endif
17432                 if (ret == 0) {
17433                     ret = MakeMasterSecret(ssl);
17434                 }
17435             }
17436             break;
17437         #endif /* NO_DH */
17438         #if !defined(NO_DH) && !defined(NO_PSK)
17439             case dhe_psk_kea:
17440             {
17441                 byte* pms = ssl->arrays->preMasterSecret;
17442                 word16 clientSz;
17443                 DhKey  dhKey;
17444 
17445                 /* sanity check that PSK server callback has been set */
17446                 if (ssl->options.server_psk_cb == NULL) {
17447                     WOLFSSL_MSG("No server PSK callback set");
17448                     return PSK_KEY_ERROR;
17449                 }
17450 
17451                 /* Read in the PSK hint */
17452                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17453                     return BUFFER_ERROR;
17454                 }
17455 
17456                 ato16(input + *inOutIdx, &clientSz);
17457                 *inOutIdx += OPAQUE16_LEN;
17458                 if (clientSz > MAX_PSK_ID_LEN) {
17459                     return CLIENT_ID_ERROR;
17460                 }
17461 
17462                 if ((*inOutIdx - begin) + clientSz > size) {
17463                     return BUFFER_ERROR;
17464                 }
17465 
17466                 XMEMCPY(ssl->arrays->client_identity,
17467                                                    input + *inOutIdx, clientSz);
17468                 *inOutIdx += clientSz;
17469                 ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
17470                                                                               0;
17471 
17472                 /* Read in the DHE business */
17473                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17474                     return BUFFER_ERROR;
17475                 }
17476 
17477                 ato16(input + *inOutIdx, &clientSz);
17478                 *inOutIdx += OPAQUE16_LEN;
17479 
17480                 if ((*inOutIdx - begin) + clientSz > size) {
17481                     return BUFFER_ERROR;
17482                 }
17483 
17484                 wc_InitDhKey(&dhKey);
17485                 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
17486                                        ssl->buffers.serverDH_P.length,
17487                                        ssl->buffers.serverDH_G.buffer,
17488                                        ssl->buffers.serverDH_G.length);
17489                 if (ret == 0) {
17490                     ret = wc_DhAgree(&dhKey, pms + OPAQUE16_LEN,
17491                                           &ssl->arrays->preMasterSz,
17492                                           ssl->buffers.serverDH_Priv.buffer,
17493                                           ssl->buffers.serverDH_Priv.length,
17494                                           input + *inOutIdx, clientSz);
17495                 }
17496                 wc_FreeDhKey(&dhKey);
17497 
17498                 *inOutIdx += clientSz;
17499                 c16toa((word16)ssl->arrays->preMasterSz, pms);
17500                 ssl->arrays->preMasterSz += OPAQUE16_LEN;
17501                 pms += ssl->arrays->preMasterSz;
17502 
17503                 /* Use the PSK hint to look up the PSK and add it to the
17504                  * preMasterSecret here. */
17505                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
17506                     ssl->arrays->client_identity, ssl->arrays->psk_key,
17507                     MAX_PSK_KEY_LEN);
17508 
17509                 if (ssl->arrays->psk_keySz == 0 ||
17510                                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17511                     return PSK_KEY_ERROR;
17512                 }
17513 
17514                 c16toa((word16) ssl->arrays->psk_keySz, pms);
17515                 pms += OPAQUE16_LEN;
17516 
17517                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17518                 ssl->arrays->preMasterSz +=
17519                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
17520             #ifdef HAVE_QSH
17521                 if (ssl->options.haveQSH) {
17522                     /* extension name */
17523                     ato16(input + *inOutIdx, &name);
17524                     *inOutIdx += OPAQUE16_LEN;
17525 
17526                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17527                         /* if qshSz is larger than 0 it is the length of
17528                            buffer used */
17529                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17530                                               size - *inOutIdx + begin, 1)) < 0) {
17531                             return qshSz;
17532                         }
17533                         *inOutIdx += qshSz;
17534                     }
17535                     else {
17536                         /* unknown extension sent client ignored
17537                            handshake */
17538                         return BUFFER_ERROR;
17539                     }
17540                 }
17541             #endif
17542                 if (ret == 0)
17543                     ret = MakeMasterSecret(ssl);
17544 
17545                 /* No further need for PSK */
17546                 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17547                 ssl->arrays->psk_keySz = 0;
17548             }
17549             break;
17550         #endif /* !NO_DH && !NO_PSK */
17551         #if defined(HAVE_ECC) && !defined(NO_PSK)
17552             case ecdhe_psk_kea:
17553             {
17554                 byte* pms = ssl->arrays->preMasterSecret;
17555                 word16 clientSz;
17556 
17557                 /* sanity check that PSK server callback has been set */
17558                 if (ssl->options.server_psk_cb == NULL) {
17559                     WOLFSSL_MSG("No server PSK callback set");
17560                     return PSK_KEY_ERROR;
17561                 }
17562 
17563                 /* Read in the PSK hint */
17564                 if ((*inOutIdx - begin) + OPAQUE16_LEN > size) {
17565                     return BUFFER_ERROR;
17566                 }
17567 
17568                 ato16(input + *inOutIdx, &clientSz);
17569                 *inOutIdx += OPAQUE16_LEN;
17570                 if (clientSz > MAX_PSK_ID_LEN) {
17571                     return CLIENT_ID_ERROR;
17572                 }
17573 
17574                 if ((*inOutIdx - begin) + clientSz > size) {
17575                     return BUFFER_ERROR;
17576                 }
17577 
17578                 XMEMCPY(ssl->arrays->client_identity,
17579                                                    input + *inOutIdx, clientSz);
17580                 *inOutIdx += clientSz;
17581                 ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
17582                                                                               0;
17583 
17584                 /* ECC key */
17585                 if ((*inOutIdx - begin) + OPAQUE8_LEN > size) {
17586                     return BUFFER_ERROR;
17587                 }
17588 
17589                 length = input[(*inOutIdx)++];
17590 
17591                 if ((*inOutIdx - begin) + length > size) {
17592                     return BUFFER_ERROR;
17593                 }
17594 
17595                 if (ssl->peerEccKey == NULL) {
17596                     /* alloc/init on demand */
17597                     ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
17598                                               ssl->ctx->heap, DYNAMIC_TYPE_ECC);
17599                     if (ssl->peerEccKey == NULL) {
17600                         WOLFSSL_MSG("PeerEccKey Memory error");
17601                         return MEMORY_E;
17602                     }
17603                     wc_ecc_init(ssl->peerEccKey);
17604                 } else if (ssl->peerEccKeyPresent) {  /* don't leak on reuse */
17605                     wc_ecc_free(ssl->peerEccKey);
17606                     ssl->peerEccKeyPresent = 0;
17607                     wc_ecc_init(ssl->peerEccKey);
17608                 }
17609 
17610                 if (wc_ecc_import_x963(input + *inOutIdx, length,
17611                                                              ssl->peerEccKey)) {
17612                     return ECC_PEERKEY_ERROR;
17613                 }
17614 
17615                 *inOutIdx += length;
17616                 ssl->peerEccKeyPresent = 1;
17617 
17618                 /* Note sizeof preMasterSecret is ENCRYPT_LEN currently 512 */
17619                 length = sizeof(ssl->arrays->preMasterSecret);
17620 
17621                 if (ssl->eccTempKeyPresent == 0) {
17622                     WOLFSSL_MSG("Ecc ephemeral key not made correctly");
17623                     ret = ECC_MAKEKEY_ERROR;
17624                 } else {
17625                     ret = wc_ecc_shared_secret(ssl->eccTempKey,
17626                           ssl->peerEccKey, ssl->arrays->preMasterSecret +
17627                           OPAQUE16_LEN, &length);
17628                 }
17629 
17630                 if (ret != 0) {
17631                     return ECC_SHARED_ERROR;
17632                 }
17633 
17634                 c16toa((word16)length, pms);
17635                 ssl->arrays->preMasterSz += OPAQUE16_LEN + length;
17636                 pms += ssl->arrays->preMasterSz;
17637 
17638                 /* Use the PSK hint to look up the PSK and add it to the
17639                  * preMasterSecret here. */
17640                 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
17641                     ssl->arrays->client_identity, ssl->arrays->psk_key,
17642                     MAX_PSK_KEY_LEN);
17643 
17644                 if (ssl->arrays->psk_keySz == 0 ||
17645                                        ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
17646                     return PSK_KEY_ERROR;
17647                 }
17648 
17649                 c16toa((word16) ssl->arrays->psk_keySz, pms);
17650                 pms += OPAQUE16_LEN;
17651 
17652                 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17653                 ssl->arrays->preMasterSz +=
17654                                           ssl->arrays->psk_keySz + OPAQUE16_LEN;
17655 
17656             #ifdef HAVE_QSH
17657                 if (ssl->options.haveQSH) {
17658                     /* extension name */
17659                     ato16(input + *inOutIdx, &name);
17660                     *inOutIdx += OPAQUE16_LEN;
17661 
17662                     if (name == TLSX_QUANTUM_SAFE_HYBRID) {
17663                         /* if qshSz is larger than 0 it is the length of
17664                            buffer used */
17665                         if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx,
17666                                             size - *inOutIdx + begin, 1)) < 0) {
17667                             return qshSz;
17668                         }
17669                         *inOutIdx += qshSz;
17670                     }
17671                     else {
17672                         /* unknown extension sent client ignored
17673                            handshake */
17674                         return BUFFER_ERROR;
17675                     }
17676                 }
17677             #endif
17678                 if (ret == 0)
17679                     ret = MakeMasterSecret(ssl);
17680 
17681                 /* No further need for PSK */
17682                 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
17683                 ssl->arrays->psk_keySz = 0;
17684             }
17685             break;
17686         #endif /* HAVE_ECC && !NO_PSK */
17687             default:
17688             {
17689                 WOLFSSL_MSG("Bad kea type");
17690                 ret = BAD_KEA_TYPE_E;
17691             }
17692             break;
17693         }
17694 
17695         /* No further need for PMS */
17696         ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
17697         ssl->arrays->preMasterSz = 0;
17698 
17699         if (ret == 0) {
17700             ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
17701             #ifndef NO_CERTS
17702                 if (ssl->options.verifyPeer) {
17703                     ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
17704                 }
17705             #endif
17706         }
17707 
17708         return ret;
17709     }
17710 
17711 #ifdef HAVE_STUNNEL
17712     static int SNI_Callback(WOLFSSL* ssl)
17713     {
17714         /* Stunnel supports a custom sni callback to switch an SSL's ctx
17715         * when SNI is received. Call it now if exists */
17716         if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) {
17717             WOLFSSL_MSG("Calling custom sni callback");
17718             if(ssl->ctx->sniRecvCb(ssl, NULL, ssl->ctx->sniRecvCbArg)
17719                     == alert_fatal) {
17720                 WOLFSSL_MSG("Error in custom sni callback. Fatal alert");
17721                 SendAlert(ssl, alert_fatal, unrecognized_name);
17722                 return FATAL_ERROR;
17723             }
17724         }
17725         return 0;
17726     }
17727 #endif /* HAVE_STUNNEL */
17728 #endif /* NO_WOLFSSL_SERVER */
17729 #endif /* WOLFCRYPT_ONLY */
17730